Module: ActiveSanction::Sources
- Extended by:
- T::Sig
- Defined in:
- lib/active_sanction/sources.rb,
lib/active_sanction/sources/base.rb,
lib/active_sanction/sources/ofac.rb,
lib/active_sanction/sources/eu_fsf.rb,
lib/active_sanction/sources/remarks.rb,
lib/active_sanction/sources/ofac_sdn.rb,
lib/active_sanction/sources/definition.rb,
lib/active_sanction/sources/canada_sema.rb,
lib/active_sanction/sources/ofac/record.rb,
lib/active_sanction/sources/eu_fsf/record.rb,
lib/active_sanction/sources/australia_dfat.rb,
lib/active_sanction/sources/un_consolidated.rb,
lib/active_sanction/sources/ofac_consolidated.rb,
lib/active_sanction/sources/uk_sanctions_list.rb,
lib/active_sanction/sources/canada_sema/record.rb,
lib/active_sanction/sources/ofac/remarks_parser.rb,
lib/active_sanction/sources/australia_dfat/record.rb,
lib/active_sanction/sources/canada_sema/source_ref.rb,
lib/active_sanction/sources/un_consolidated/record.rb,
lib/active_sanction/sources/ofac_consolidated/record.rb,
lib/active_sanction/sources/uk_sanctions_list/record.rb,
lib/active_sanction/sources/ofac/remarks_parser/coverage.rb,
lib/active_sanction/sources/australia_dfat/published_date.rb,
lib/active_sanction/sources/ofac/remarks_parser/vocabulary.rb,
lib/active_sanction/sources/uk_sanctions_list/published_date.rb
Overview
Every sanctions list this library knows how to read, filed under the key its adapter declares.
ActiveSanction::Sources[:un_consolidated] # => the adapter class
ActiveSanction::Sources.keys # => [:ofac_sdn, :un_consolidated, ...]
The registry is open, and that is the point of this milestone. A bank with an internal watchlist, or a gem adding a jurisdiction this one has not got to, registers an adapter of its own without forking:
ActiveSanction::Sources.register(MyCompany::InternalWatchlist)
ActiveSanction.configure { |c| c.sources = %i[ofac_sdn my_internal_watchlist] }
Nothing here requires Sources::Base. Registration is duck-typed on .key
and .new, so a source backed by a database table rather than a published
file -- which has no URL to declare and no payload to fetch -- is a
first-class citizen rather than something that has to pretend to be a file
download. Base is the convenient way to write an adapter, not the price of
admission.
Built-in adapters register themselves at the bottom of their own file, one
explicit Sources.register(self) line each, rather than being enrolled by
inherited. Auto-registering every subclass would also enrol the abstract
intermediates that adapters sharing a publisher will want (an OFAC base
holding the authority and the format for SDN and Consolidated both) and
every throwaway subclass a test defines.
Defined Under Namespace
Modules: Definition, Remarks Classes: AustraliaDfat, Base, CanadaSema, DeclarationError, DuplicateKey, EuFsf, MissingPayload, OfacConsolidated, OfacSdn, UkSanctionsList, UnConsolidated, UnknownSource
Class Method Summary collapse
-
.[](key) ⇒ T.untyped
The adapter registered under a key.
-
.all ⇒ Array<T.untyped>
Every registered adapter, ordered by key so a CLI listing and a sync summary do not reshuffle themselves between runs.
- .empty? ⇒ Boolean
-
.enabled(configured = ActiveSanction.config.sources) ⇒ Array<T.untyped>
The adapters a sync should run: what
config.sourcesnames, or every registered source when it names nothing. - .keys ⇒ Array<Symbol>
-
.register(source) ⇒ T.untyped
Adds a source to the registry and returns it.
- .registered?(key) ⇒ Boolean
- .size ⇒ Integer
-
.unregister(key) ⇒ T.untyped
Drops a key and returns what was registered there, or nil.
Class Method Details
.[](key) ⇒ T.untyped
The adapter registered under a key.
Raises rather than returning nil, because every caller of this method
is resolving a name a human typed -- into config.sources, into
activesanction sync ofac_sdb -- and a nil surfaces three layers later
as a NoMethodError that says nothing about the misspelling. The message
lists what is registered, which is also the answer to "why is my
adapter not being picked up" (its file was never required).
117 118 119 120 121 122 |
# File 'lib/active_sanction/sources.rb', line 117 def [](key) name = key.to_sym registry.fetch(name) do raise UnknownSource, "no source registered as #{name.inspect}. Registered: #{list}" end end |
.all ⇒ Array<T.untyped>
Every registered adapter, ordered by key so a CLI listing and a sync summary do not reshuffle themselves between runs.
130 |
# File 'lib/active_sanction/sources.rb', line 130 def all = registry.keys.sort.map { |key| registry[key] } |
.empty? ⇒ Boolean
139 |
# File 'lib/active_sanction/sources.rb', line 139 def empty? = registry.empty? |
.enabled(configured = ActiveSanction.config.sources) ⇒ Array<T.untyped>
The adapters a sync should run: what config.sources names, or every
registered source when it names nothing. An unknown key raises here,
at the start of the run, rather than after the other lists have been
downloaded.
146 147 148 149 150 |
# File 'lib/active_sanction/sources.rb', line 146 def enabled(configured = ActiveSanction.config.sources) return all if configured.nil? configured.map { |key| self[key] } end |
.keys ⇒ Array<Symbol>
133 |
# File 'lib/active_sanction/sources.rb', line 133 def keys = registry.keys.sort |
.register(source) ⇒ T.untyped
Adds a source to the registry and returns it. Registering the same class twice is a no-op, so a file that manages to get loaded under two paths does not take the whole process down with it.
97 98 99 100 101 102 103 104 105 106 |
# File 'lib/active_sanction/sources.rb', line 97 def register(source) key = registrable!(source) MUTEX.synchronize do claimed = registry[key] raise DuplicateKey, (key, source, claimed) if claimed && claimed != source registry[key] = source end source end |
.registered?(key) ⇒ Boolean
125 |
# File 'lib/active_sanction/sources.rb', line 125 def registered?(key) = registry.key?(key.to_sym) |
.size ⇒ Integer
136 |
# File 'lib/active_sanction/sources.rb', line 136 def size = registry.size |
.unregister(key) ⇒ T.untyped
Drops a key and returns what was registered there, or nil. The supported way to replace a built-in adapter with a patched one:
ActiveSanction::Sources.unregister(:ofac_sdn)
ActiveSanction::Sources.register(MyCompany::PatchedOfacSdn)
There is deliberately no clear!. Built-in adapters register on
require, and require runs once per process: a suite that emptied the
registry between examples would leave every later example running
against a library that has forgotten its own sources.
163 164 165 |
# File 'lib/active_sanction/sources.rb', line 163 def unregister(key) MUTEX.synchronize { registry.delete(key.to_sym) } end |