Module: Foobara::RemoteImports::ImportBase

Included in:
ImportCommand, ImportDomain, ImportError, ImportOrganization, ImportType
Defined in:
foobara-remote-imports-1.2.1/src/foobara/remote_imports/import_base.rb

Defined Under Namespace

Classes: BadManifestInputsError, NotFoundError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#manifest_data ⇒ Object

Returns the value of attribute manifest_data.



57
58
59
# File 'src/foobara/remote_imports/import_base.rb', line 57

def manifest_data
  @manifest_data
end

#manifest_to_import ⇒ Object

Returns the value of attribute manifest_to_import.



57
58
59
# File 'src/foobara/remote_imports/import_base.rb', line 57

def manifest_to_import
  @manifest_to_import
end

#manifests_to_import ⇒ Object

Returns the value of attribute manifests_to_import.



57
58
59
# File 'src/foobara/remote_imports/import_base.rb', line 57

def manifests_to_import
  @manifests_to_import
end

Class Method Details

.included(klass) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'src/foobara/remote_imports/import_base.rb', line 28

def included(klass)
  klass.possible_input_error :to_import, NotFoundError
  klass.possible_error BadManifestInputsError

  klass.inputs(
    manifest_url: :string,
    raw_manifest: :associative_array,
    cache: { type: :boolean, default: true },
    cache_path: { type: :string, default: "tmp/cache/foobara-remote-imports" },
    to_import: :duck,
    already_imported: { type: :duck, allow_nil: true },
    deanonymize_models: { type: :boolean, default: true }
  )

  klass.result :duck
end

Instance Method Details

#already_exists? ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
77
78
79
80
81
82
# File 'src/foobara/remote_imports/import_base.rb', line 74

def already_exists?
  method = "foobara_lookup_#{manifest_to_import.scoped_category}"

  Foobara.foobara_root_namespace.send(
    method,
    manifest_to_import.reference,
    mode: Namespace::LookupMode::ABSOLUTE
  )
end

#already_imported ⇒ Object



84
85
86
# File 'src/foobara/remote_imports/import_base.rb', line 84

def already_imported
  inputs[:already_imported] || AlreadyImported.new
end

#cache_file_path ⇒ Object



189
190
191
# File 'src/foobara/remote_imports/import_base.rb', line 189

def cache_file_path
  @cache_file_path ||= "#{cache_path}/#{cache_key}.json"
end

#cache_key ⇒ Object



180
181
182
183
184
185
186
187
# File 'src/foobara/remote_imports/import_base.rb', line 180

def cache_key
  @cache_key ||= begin
    hash = Digest::MD5.hexdigest(manifest_url)
    escaped_url = manifest_url.gsub(/[^\w]/, "_")

    "#{hash}_#{escaped_url}"
  end
end

#cache_manifest ⇒ Object



163
164
165
166
# File 'src/foobara/remote_imports/import_base.rb', line 163

def cache_manifest
  FileUtils.mkdir_p(cache_path)
  File.write(cache_file_path, manifest_data.to_json)
end

#cached? ⇒ Boolean

Returns:

  • (Boolean)


172
173
174
# File 'src/foobara/remote_imports/import_base.rb', line 172

def cached?
  File.exist?(cache_file_path)
end

#determine_manifests_to_import ⇒ Object



193
194
195
# File 'src/foobara/remote_imports/import_base.rb', line 193

def determine_manifests_to_import
  self.manifests_to_import = find_manifests_to_import
end

#execute ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'src/foobara/remote_imports/import_base.rb', line 46

def execute
  load_manifest

  cache_manifest if should_cache?
  determine_manifests_to_import
  filter_manifests_to_import
  import_objects_from_manifests

  imported_objects
end

#filter_manifests_to_import ⇒ Object

TODO: feels like a command smell to pass manifests here... reconsider algorithm



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'src/foobara/remote_imports/import_base.rb', line 125

def filter_manifests_to_import
  return if to_import.nil? || to_import.empty?

  references = manifests_to_import.map(&:reference)

  filter = Util.array(to_import)

  filter.map! do |name|
    if references.include?(name)
      name
    else
      suffix = "::#{name}"

      partial_matches = references.select { |reference| reference.end_with?(suffix) }

      if partial_matches.size == 1
        partial_matches.first
      else
        name
      end
    end
  end

  not_found = filter - references

  if not_found.any?
    add_input_error :to_import, :not_found, "Could not find #{not_found}", not_found:
  end

  self.manifests_to_import = manifests_to_import.select do |manifest|
    filter.include?(manifest.reference)
  end
end

#find_manifests_to_import ⇒ Object



197
198
199
200
201
# File 'src/foobara/remote_imports/import_base.rb', line 197

def find_manifests_to_import
  # simplecov:disable
  raise "subclass responsibility"
  # simplecov:enable
end

#import_object_from_manifest ⇒ Object



216
217
218
219
220
# File 'src/foobara/remote_imports/import_base.rb', line 216

def import_object_from_manifest
  # simplecov:disable
  raise "subclass responsibility"
  # simplecov:enable
end

#import_objects_from_manifests ⇒ Object



203
204
205
206
207
208
209
210
211
212
213
214
# File 'src/foobara/remote_imports/import_base.rb', line 203

def import_objects_from_manifests
  manifests_to_import.each do |manifest|
    unless already_imported.already_imported?(manifest)
      self.manifest_to_import = manifest

      next if already_exists?

      imported_objects << import_object_from_manifest
      already_imported << manifest
    end
  end
end

#imported_objects ⇒ Object



222
223
224
# File 'src/foobara/remote_imports/import_base.rb', line 222

def imported_objects
  @imported_objects ||= []
end

#load_cached_manifest ⇒ Object



176
177
178
# File 'src/foobara/remote_imports/import_base.rb', line 176

def load_cached_manifest
  JSON.parse(File.read(cache_file_path))
end

#load_manifest ⇒ Object



88
89
90
91
92
93
94
95
96
# File 'src/foobara/remote_imports/import_base.rb', line 88

def load_manifest
  self.manifest_data = if raw_manifest
                         raw_manifest
                       elsif cache && cached?
                         load_cached_manifest
                       else
                         load_manifest_from_url
                       end
end

#load_manifest_from_url ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'src/foobara/remote_imports/import_base.rb', line 98

def load_manifest_from_url
  uri = URI.parse(manifest_url)

  net_http = Net::HTTP.new(uri.host, uri.port).tap do |http|
    http.use_ssl = uri.scheme == "https"
    http.read_timeout = ENV["FOOBARA_HTTP_MANIFEST_TIMEOUT"]&.to_i || 30
  end

  request = Net::HTTP::Get.new(uri.request_uri, load_manifest_headers)
  response = net_http.request(request)

  unless response.is_a?(Net::HTTPSuccess)
    # simplecov:disable
    raise "Could not get manifest from #{manifest_url}: " \
          "#{response.code} #{response.message}"
    # simplecov:enable
  end
  manifest_json = response.body

  JSON.parse(manifest_json)
end

#load_manifest_headers ⇒ Object



120
121
122
# File 'src/foobara/remote_imports/import_base.rb', line 120

def load_manifest_headers
  { "Content-Type" => "application/json" }
end

#root_manifest ⇒ Object



159
160
161
# File 'src/foobara/remote_imports/import_base.rb', line 159

def root_manifest
  @root_manifest ||= Manifest::RootManifest.new(manifest_data)
end

#should_cache? ⇒ Boolean

Returns:

  • (Boolean)


168
169
170
# File 'src/foobara/remote_imports/import_base.rb', line 168

def should_cache?
  cache && manifest_url && !cached?
end

#validate ⇒ Object



59
60
61
62
# File 'src/foobara/remote_imports/import_base.rb', line 59

def validate
  super
  validate_manifest
end

#validate_manifest ⇒ Object



64
65
66
67
68
69
70
71
72
# File 'src/foobara/remote_imports/import_base.rb', line 64

def validate_manifest
  if manifest_url
    if raw_manifest
      add_runtime_error :bad_manifest_inputs, "Cannot provide both manifest_url and raw_manifest"
    end
  elsif !raw_manifest
    add_runtime_error :bad_manifest_inputs, "Must provide either manifest_url or raw_manifest"
  end
end