Class: Saro::Dat::DatCmsManager
- Inherits:
-
Object
- Object
- Saro::Dat::DatCmsManager
- Defined in:
- lib/saro/dat/dat_cms_manager.rb
Constant Summary collapse
- DAT_CMS_API_VERSION =
"v1"- STOP_JOIN_TIMEOUT_SECONDS =
1.0
Instance Attribute Summary collapse
-
#last_error ⇒ Object
readonly
Returns the value of attribute last_error.
Class Method Summary collapse
Instance Method Summary collapse
- #get_manager ⇒ Object
-
#initialize(uri:, token:, interval_seconds: 60, verify_only: false, dat_manager: nil, connect_timeout_seconds: 5, sync_timeout_seconds: 15) ⇒ DatCmsManager
constructor
A new instance of DatCmsManager.
- #issue(plain, secure) ⇒ Object
- #parse(dat) ⇒ Object
- #stop ⇒ Object
- #stopped? ⇒ Boolean
- #sync ⇒ Object
- #sync_or_raise ⇒ Object
- #version ⇒ Object
Constructor Details
#initialize(uri:, token:, interval_seconds: 60, verify_only: false, dat_manager: nil, connect_timeout_seconds: 5, sync_timeout_seconds: 15) ⇒ DatCmsManager
Returns a new instance of DatCmsManager.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/saro/dat/dat_cms_manager.rb', line 18 def initialize(uri:, token:, interval_seconds: 60, verify_only: false, dat_manager: nil, connect_timeout_seconds: 5, sync_timeout_seconds: 15) @uri = uri @token = token @interval_seconds = interval_seconds @verify_only = verify_only @manager = dat_manager || DatManager.new @connect_timeout_seconds = connect_timeout_seconds @sync_timeout_seconds = sync_timeout_seconds @active_http = nil @version = 0 @lock = Mutex.new @lifecycle = Mutex.new @stop_cond = ConditionVariable.new @stopped = false @logger = Logger.new($stdout) @logger.level = Logger::DEBUG @last_error = Saro::Dat::Error.new(Saro::Dat::ErrorCode::CMS_NOT_SYNCED) sync if @interval_seconds > 0 schedule_sync end end |
Instance Attribute Details
#last_error ⇒ Object (readonly)
Returns the value of attribute last_error.
61 62 63 |
# File 'lib/saro/dat/dat_cms_manager.rb', line 61 def last_error @last_error end |
Class Method Details
.builder ⇒ Object
172 173 174 |
# File 'lib/saro/dat/dat_cms_manager.rb', line 172 def self.builder DatCmsManagerBuilder.new end |
.http_status_error(status) ⇒ Object
150 151 152 153 154 155 156 157 158 |
# File 'lib/saro/dat/dat_cms_manager.rb', line 150 def self.http_status_error(status) case status when 401 then Saro::Dat::Error.new(Saro::Dat::ErrorCode::CMS_UNAUTHORIZED, "http 401") when 403 then Saro::Dat::Error.new(Saro::Dat::ErrorCode::CMS_FORBIDDEN, "http 403") when 404 then Saro::Dat::Error.new(Saro::Dat::ErrorCode::CMS_ENDPOINT_NOT_FOUND, "http 404") when 500..599 then Saro::Dat::Error.new(Saro::Dat::ErrorCode::CMS_SERVER_ERROR, "http #{status}") else Saro::Dat::Error.new(Saro::Dat::ErrorCode::CMS_HTTP_STATUS, "http #{status}") end end |
Instance Method Details
#get_manager ⇒ Object
160 161 162 |
# File 'lib/saro/dat/dat_cms_manager.rb', line 160 def get_manager @manager end |
#issue(plain, secure) ⇒ Object
164 165 166 |
# File 'lib/saro/dat/dat_cms_manager.rb', line 164 def issue(plain, secure) @manager.issue(plain, secure) end |
#parse(dat) ⇒ Object
168 169 170 |
# File 'lib/saro/dat/dat_cms_manager.rb', line 168 def parse(dat) @manager.parse(dat) end |
#stop ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/saro/dat/dat_cms_manager.rb', line 44 def stop thread = nil @lifecycle.synchronize do return if @stopped @stopped = true @stop_cond.broadcast thread = @thread @active_http&.finish if @active_http&.started? end thread&.join(STOP_JOIN_TIMEOUT_SECONDS) nil end |
#stopped? ⇒ Boolean
57 58 59 |
# File 'lib/saro/dat/dat_cms_manager.rb', line 57 def stopped? @lifecycle.synchronize { @stopped } end |
#sync ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/saro/dat/dat_cms_manager.rb', line 67 def sync err = sync_or_raise @last_error = nil err rescue Saro::Dat::Error => e unless e.retry == :state @last_error = e @logger.error("[CRITICAL] DAT CMS SYNC #{@uri}: #{e.code} #{e.detail}") end nil rescue StandardError => e @last_error = Saro::Dat::Error.new(Saro::Dat::ErrorCode::CMS_UNKNOWN, "unclassified cms failure", cause: e) @logger.error("[CRITICAL] DAT CMS SYNC #{@uri}: #{e.}") nil end |
#sync_or_raise ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/saro/dat/dat_cms_manager.rb', line 83 def sync_or_raise unless @lock.try_lock @logger.debug("cms sync skipped, previous sync still running: #{@uri}") raise Saro::Dat::Error.new(Saro::Dat::ErrorCode::CMS_SYNC_IN_PROGRESS) end begin url = URI("#{@uri}?version=#{@version}") request = Net::HTTP::Get.new(url) request["Authorization"] = @token response = begin Net::HTTP.start(url.host, url.port, use_ssl: url.scheme == 'https', open_timeout: (@connect_timeout_seconds.zero? ? nil : @connect_timeout_seconds), read_timeout: (@sync_timeout_seconds.zero? ? nil : @sync_timeout_seconds)) do |http| @lifecycle.synchronize { @active_http = http } http.request(request) ensure @lifecycle.synchronize { @active_http = nil } end rescue StandardError => e raise Saro::Dat::Error.new(Saro::Dat::ErrorCode::CMS_UNREACHABLE, "cannot reach #{@uri}", cause: e) end status = response.code.to_i raise self.class.http_status_error(status) unless status.between?(200, 299) body = response.body raise Saro::Dat::Error.new(Saro::Dat::ErrorCode::CMS_MALFORMED, "response is empty") if body.nil? || body.empty? unless body.ascii_only? raise Saro::Dat::Error.new(Saro::Dat::ErrorCode::CMS_MALFORMED, "response is not strict ASCII") end lines = body.split("\n", 2) new_version_str = lines[0] new_certificates = lines.length == 2 ? lines[1].strip : "" unless new_version_str.match?(/\A[0-9]+\z/) raise Saro::Dat::Error.new(Saro::Dat::ErrorCode::CMS_MALFORMED, "version line is not a plain decimal integer") end new_version = new_version_str.to_i if new_certificates.empty? @logger.debug("No new certificate: #{url}") return nil end if new_version < @version @logger.warn("#{Saro::Dat::ErrorCode::CMS_VERSION_RESET}: #{@version} -> #{new_version}") end renew_count = begin @manager.imports(new_certificates, clear: false) rescue Saro::Dat::Error => e raise Saro::Dat::Error.new(Saro::Dat::ErrorCode::CMS_IMPORT_FAILED, "cannot apply received certificates", cause: e) end @version = new_version @logger.debug("Renewed #{renew_count} certificates for version #{new_version}: #{url}") nil ensure @lock.unlock end end |
#version ⇒ Object
63 64 65 |
# File 'lib/saro/dat/dat_cms_manager.rb', line 63 def version @version end |