Class: Archsight::Import::Handler
- Inherits:
-
Object
- Object
- Archsight::Import::Handler
- Defined in:
- lib/archsight/import/handler.rb
Overview
Base class for import handlers
Subclasses must implement the #execute method to perform the actual import. Use the helper methods to read configuration, validate environment, and write output.
Direct Known Subclasses
Archsight::Import::Handlers::Github, Archsight::Import::Handlers::Gitlab, Archsight::Import::Handlers::JiraDiscover, Archsight::Import::Handlers::JiraMetrics, Archsight::Import::Handlers::Repository, Archsight::Import::Handlers::RestApi, Archsight::Import::Handlers::RestApiIndex
Instance Attribute Summary collapse
-
#database ⇒ Object
readonly
Returns the value of attribute database.
-
#import_resource ⇒ Object
readonly
Returns the value of attribute import_resource.
-
#progress ⇒ Object
readonly
Returns the value of attribute progress.
-
#resources_dir ⇒ Object
readonly
Returns the value of attribute resources_dir.
-
#shared_writer ⇒ Object
readonly
Returns the value of attribute shared_writer.
Instance Method Summary collapse
-
#compute_config_hash ⇒ String
Compute a hash of the import’s configuration for cache invalidation.
-
#config(key, default: nil) ⇒ String?
Get a configuration value from import/config/* annotations.
-
#config_all ⇒ Hash
Get all configuration values as a hash.
-
#execute ⇒ Object
Execute the import.
-
#import_yaml(name:, handler:, config: {}, annotations: {}) ⇒ Hash
Generate an Import resource YAML hash for child imports NOTE: generated/at is NOT set here - it’s only set by the self_marker when the child import actually executes.
-
#initialize(import_resource, database:, resources_dir:, progress: nil, shared_writer: nil) ⇒ Handler
constructor
A new instance of Handler.
-
#resource_yaml(kind:, name:, annotations: {}, spec: {}) ⇒ Hash
Generate a resource YAML hash with standard metadata.
-
#resources_to_yaml(resources) ⇒ String
Convert multiple resource hashes to YAML string with document separators.
-
#self_marker ⇒ Hash
Generate a marker Import for this handler with generated/at timestamp and config hash Used for caching - call at end of execute() to persist the execution timestamp.
-
#write_generates_meta ⇒ Object
Write generates meta record for this Import Call at end of execute() to persist tracking of generated resources Appends to the output file rather than overwriting.
-
#write_yaml(content, filename: nil, sort_key: nil) ⇒ String
Write YAML content to the output path Output location is determined by import/outputPath annotation: - Relative to resources_dir (e.g., “generated/repositories.yaml”) - If filename parameter is provided, it replaces the filename from outputPath - If no outputPath, falls back to resources_dir/generated with import name as filename.
Constructor Details
#initialize(import_resource, database:, resources_dir:, progress: nil, shared_writer: nil) ⇒ Handler
Returns a new instance of Handler.
22 23 24 25 26 27 28 29 |
# File 'lib/archsight/import/handler.rb', line 22 def initialize(import_resource, database:, resources_dir:, progress: nil, shared_writer: nil) @import_resource = import_resource @database = database @resources_dir = resources_dir @progress = progress || Archsight::Import::Progress.new @shared_writer = shared_writer @tracked_resources = [] end |
Instance Attribute Details
#database ⇒ Object (readonly)
Returns the value of attribute database.
15 16 17 |
# File 'lib/archsight/import/handler.rb', line 15 def database @database end |
#import_resource ⇒ Object (readonly)
Returns the value of attribute import_resource.
15 16 17 |
# File 'lib/archsight/import/handler.rb', line 15 def import_resource @import_resource end |
#progress ⇒ Object (readonly)
Returns the value of attribute progress.
15 16 17 |
# File 'lib/archsight/import/handler.rb', line 15 def progress @progress end |
#resources_dir ⇒ Object (readonly)
Returns the value of attribute resources_dir.
15 16 17 |
# File 'lib/archsight/import/handler.rb', line 15 def resources_dir @resources_dir end |
#shared_writer ⇒ Object (readonly)
Returns the value of attribute shared_writer.
15 16 17 |
# File 'lib/archsight/import/handler.rb', line 15 def shared_writer @shared_writer end |
Instance Method Details
#compute_config_hash ⇒ String
Compute a hash of the import’s configuration for cache invalidation
58 59 60 61 62 63 64 |
# File 'lib/archsight/import/handler.rb', line 58 def compute_config_hash config_data = { handler: import_resource.annotations["import/handler"], config: import_resource.annotations.select { |k, _| k.start_with?("import/config/") }.sort.to_h } Digest::SHA256.hexdigest(config_data.to_json)[0, 16] end |
#config(key, default: nil) ⇒ String?
Get a configuration value from import/config/* annotations
41 42 43 |
# File 'lib/archsight/import/handler.rb', line 41 def config(key, default: nil) import_resource.annotations["import/config/#{key}"] || default end |
#config_all ⇒ Hash
Get all configuration values as a hash
47 48 49 50 51 52 53 54 |
# File 'lib/archsight/import/handler.rb', line 47 def config_all import_resource.annotations.each_with_object({}) do |(key, value), hash| next unless key.start_with?("import/config/") config_key = key.sub("import/config/", "") hash[config_key] = value end end |
#execute ⇒ Object
Execute the import. Must be implemented by subclasses.
33 34 35 |
# File 'lib/archsight/import/handler.rb', line 33 def execute raise NotImplementedError, "#{self.class}#execute must be implemented" end |
#import_yaml(name:, handler:, config: {}, annotations: {}) ⇒ Hash
Generate an Import resource YAML hash for child imports NOTE: generated/at is NOT set here - it’s only set by the self_marker when the child import actually executes. This ensures caching works correctly regardless of file loading order.
Dependencies are not specified here - they are derived from the ‘generates` relation on the parent import (tracked via write_generates_meta).
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/archsight/import/handler.rb', line 163 def import_yaml(name:, handler:, config: {}, annotations: {}) @tracked_resources << { kind: "Import", name: name } all_annotations = { "import/handler" => handler, "generated/script" => import_resource.name } # Add direct annotations (e.g., import/outputPath) all_annotations.merge!(annotations) # Add config annotations with prefix config.each do |key, value| all_annotations["import/config/#{key}"] = value.to_s end { "apiVersion" => "architecture/v1alpha1", "kind" => "Import", "metadata" => { "name" => name, "annotations" => all_annotations }, "spec" => {} } end |
#resource_yaml(kind:, name:, annotations: {}, spec: {}) ⇒ Hash
Generate a resource YAML hash with standard metadata
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/archsight/import/handler.rb', line 134 def resource_yaml(kind:, name:, annotations: {}, spec: {}) @tracked_resources << { kind: kind, name: name } { "apiVersion" => "architecture/v1alpha1", "kind" => kind, "metadata" => { "name" => name, "annotations" => annotations.merge( "generated/script" => import_resource.name, "generated/at" => Time.now.utc.iso8601 ) }, "spec" => spec } end |
#resources_to_yaml(resources) ⇒ String
Convert multiple resource hashes to YAML string with document separators
192 193 194 |
# File 'lib/archsight/import/handler.rb', line 192 def resources_to_yaml(resources) resources.map { |r| YAML.dump(r) }.join end |
#self_marker ⇒ Hash
Generate a marker Import for this handler with generated/at timestamp and config hash Used for caching - call at end of execute() to persist the execution timestamp
69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/archsight/import/handler.rb', line 69 def self_marker { "apiVersion" => "architecture/v1alpha1", "kind" => "Import", "metadata" => { "name" => import_resource.name, "annotations" => { "generated/at" => Time.now.utc.iso8601, "generated/configHash" => compute_config_hash } }, "spec" => {} } end |
#write_generates_meta ⇒ Object
Write generates meta record for this Import Call at end of execute() to persist tracking of generated resources Appends to the output file rather than overwriting
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/archsight/import/handler.rb', line 199 def return if @tracked_resources.empty? = (@tracked_resources) output_path = import_resource.annotations["import/outputPath"] full_path = if output_path File.join(resources_dir, output_path) else File.join(resources_dir, "generated", "#{safe_filename(import_resource.name)}.yaml") end if @shared_writer @shared_writer.append_yaml(full_path, YAML.dump(), sort_key: "#{import_resource.name}:generates") else # Append to existing file File.open(full_path, "a") { |f| f.write(YAML.dump()) } end end |
#write_yaml(content, filename: nil, sort_key: nil) ⇒ String
Write YAML content to the output path Output location is determined by import/outputPath annotation:
- Relative to resources_dir (e.g., "generated/repositories.yaml")
- If filename parameter is provided, it replaces the filename from outputPath
- If no outputPath, falls back to resources_dir/generated with import name as filename
When shared_writer is available, uses thread-safe append for concurrent writes.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/archsight/import/handler.rb', line 98 def write_yaml(content, filename: nil, sort_key: nil) output_path = import_resource.annotations["import/outputPath"] full_path = if output_path base = File.join(resources_dir, output_path) if filename # Replace filename portion with provided filename File.join(File.dirname(base), filename) else base end else # Fallback to resources_dir/generated File.join(resources_dir, "generated", filename || "#{safe_filename(import_resource.name)}.yaml") end if @shared_writer # Use thread-safe shared writer for concurrent execution # Default sort key is import name for stable output ordering key = sort_key || import_resource.name @shared_writer.append_yaml(full_path, content, sort_key: key) else # Direct write for non-concurrent mode FileUtils.mkdir_p(File.dirname(full_path)) File.write(full_path, content) end full_path end |