usps-imis-api 0.11.15 → 0.11.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a832672e225e3d314dd72d58089ddb95650e261a6498281a31db365cbadf2c47
4
- data.tar.gz: edb5fd91281205f91e1b5891e7d6fff16cba99b6851cf53ec89e6c925e502612
3
+ metadata.gz: ab24b35210bcf8507b8a9222f77acb9333bc0386305c9cd8c606eab4aee6f11a
4
+ data.tar.gz: b84b925473193fe7493966070dc3b38d29d2495d8ed67cdddec80f4dbcf3c8e1
5
5
  SHA512:
6
- metadata.gz: fb3943d61228582bdef6e516060e816682f48ee6552188d1306f003cee9eb973e1c2c26db1f7a8025e45d60d885512878e4bb5bfbe99a93f59ede12ad0fa4611
7
- data.tar.gz: ec25020f0a3c138c0f250b5aadfb3e4cdf254172ab430ac587196fe5764a2f8c12a20339dddac2856ad80dade2671aca2eb5f95761461b6fd4b421ca89df8914
6
+ metadata.gz: '09a0c8b2c2c15741a4d4602d54ddb0e28839ff7ada31c37deb975a5214dd9e9d294751f8765e258f02b289a0af2bf1bc6c086fe39d5d9ff3c64d9ff6dc47c95e'
7
+ data.tar.gz: ee7cb6cc8de2752f2ed5812bdf5a279bee89babc2b9ca15253faf1010b054c6f3bdeb3b351987428e8e214a66205d560242f3db80edac401de34fb0406b50a83
data/lib/usps/imis/api.rb CHANGED
@@ -34,12 +34,17 @@ module Usps
34
34
  #
35
35
  attr_reader :lock_imis_id
36
36
 
37
+ # Tagged logger
38
+ #
39
+ attr_reader :logger
40
+
37
41
  # A new instance of +Api+
38
42
  #
39
43
  # @param imis_id [Integer, String] iMIS ID to select immediately on initialization
40
44
  #
41
45
  def initialize(imis_id: nil)
42
46
  self.imis_id = imis_id if imis_id
47
+ @logger ||= Imis.logger('Api')
43
48
  end
44
49
 
45
50
  # Manually set the current ID, if you already have it for a given member
@@ -66,8 +71,8 @@ module Usps
66
71
  logger.debug "Fetching iMIS ID for #{certificate}"
67
72
 
68
73
  begin
69
- result = query(Imis.configuration.imis_id_query_name, { certificate: }).tap { logger.debug it }
70
- page = result.page.tap { logger.debug it }
74
+ result = query(Imis.configuration.imis_id_query_name, { certificate: })
75
+ page = result.page.tap { logger.tagged('Response').debug it }
71
76
  self.imis_id = page.first['ID'].to_i
72
77
  rescue StandardError
73
78
  raise Errors::NotFoundError, 'Member not found'
@@ -76,11 +81,14 @@ module Usps
76
81
 
77
82
  # Run requests as DSL, with specific iMIS ID only maintained for this scope
78
83
  #
84
+ # Either +id+ or +certificate+ is required.
85
+ #
79
86
  # While in this block, changes to the value of +imis_id+ are not allowed
80
87
  #
81
88
  # If no block is given, this sets the iMIS ID and returns self.
82
89
  #
83
90
  # @param id [Integer, String] iMIS ID to select for requests within the block
91
+ # @param certificate [String] Certificate number to convert to iMIS ID and select for requests within the block
84
92
  #
85
93
  # @example
86
94
  # with(12345) do
@@ -89,9 +97,12 @@ module Usps
89
97
  #
90
98
  # @return [Usps::Imis::Api]
91
99
  #
92
- def with(id, &)
100
+ def with(id = nil, certificate: nil, &)
101
+ raise ArgumentError, 'Must provide id or certificate' unless id || certificate
102
+
93
103
  old_id = imis_id
94
- self.imis_id = id
104
+
105
+ id.nil? ? imis_id_for(certificate) : self.imis_id = id
95
106
  return self unless block_given?
96
107
 
97
108
  @lock_imis_id = true
@@ -185,24 +196,26 @@ module Usps
185
196
 
186
197
  private
187
198
 
188
- def logger = Imis.logger('Api')
189
-
190
199
  # Authenticate to the iMIS API, and store the access token and expiration time
191
200
  #
192
201
  def authenticate
193
- logger.debug 'Authenticating with iMIS'
194
-
195
- request = http_post
196
- request.body = URI.encode_www_form(
197
- grant_type: 'password',
198
- username: Imis.configuration.username,
199
- password: Imis.configuration.password
200
- )
201
- result = submit(uri, request)
202
- json = JSON.parse(result.body)
202
+ json = nil # Scope
203
+
204
+ logger.tagged('Auth') do
205
+ logger.info 'Authenticating with iMIS'
206
+
207
+ request = http_post
208
+ request.body = URI.encode_www_form(
209
+ grant_type: 'password',
210
+ username: Imis.configuration.username,
211
+ password: Imis.configuration.password
212
+ )
213
+ result = submit(uri, request)
214
+ json = JSON.parse(result.body)
215
+ end
203
216
 
204
217
  @token = json['access_token']
205
- @token_expiration = Time.now - json['expires_in'] - 60
218
+ @token_expiration = Time.now + json['expires_in'] - 60
206
219
  end
207
220
 
208
221
  # URI for the authentication endpoint
@@ -25,12 +25,17 @@ module Usps
25
25
  #
26
26
  attr_reader :ordinal
27
27
 
28
+ # Tagged logger
29
+ #
30
+ attr_reader :logger
31
+
28
32
  # A new instance of +BusinessObject+
29
33
  #
30
34
  def initialize(api, business_object_name, ordinal: nil)
31
35
  @api = api
32
36
  @business_object_name = business_object_name
33
37
  @ordinal = ordinal
38
+ @logger ||= Imis.logger('BusinessObject')
34
39
  end
35
40
 
36
41
  # Run a query on the entire business object
@@ -132,12 +137,10 @@ module Usps
132
137
 
133
138
  # Ruby 3.5 instance variable filter
134
139
  #
135
- def instance_variables_to_inspect = instance_variables - %i[@api]
140
+ def instance_variables_to_inspect = instance_variables - %i[@api @logger]
136
141
 
137
142
  private
138
143
 
139
- def logger = Imis.logger('BusinessObject')
140
-
141
144
  # Construct a business object API endpoint address
142
145
  #
143
146
  def uri(id: nil)
@@ -186,7 +189,7 @@ module Usps
186
189
 
187
190
  response = submit(uri, authorize(http_get))
188
191
  result = Data.from_json(response.body)
189
- JSON.pretty_generate(result).split("\n").each { logger.debug " -> #{it}" }
192
+ logger.json result
190
193
  result
191
194
  end
192
195
 
@@ -198,7 +201,7 @@ module Usps
198
201
  request.body = JSON.dump(body)
199
202
  response = submit(uri, authorize(request))
200
203
  result = Data.from_json(response.body)
201
- JSON.pretty_generate(result).split("\n").each { logger.debug " -> #{it}" }
204
+ logger.json result
202
205
  result
203
206
  end
204
207
  end
@@ -8,8 +8,14 @@ module Usps
8
8
  class Interface
9
9
  NAME = 'USPS iMIS API - Ruby'
10
10
 
11
+ # Options passed in from the command line
12
+ #
11
13
  attr_reader :options
12
14
 
15
+ # Tagged logger
16
+ #
17
+ attr_reader :logger
18
+
13
19
  def self.run(...) = new(...).run
14
20
 
15
21
  def initialize(**)
@@ -17,9 +23,14 @@ module Usps
17
23
  validate_options!
18
24
  configure! if options[:config]
19
25
  logging!
26
+ @logger ||= Imis.logger('CommandLine')
20
27
  end
21
28
 
22
29
  def run
30
+ logger.info 'Running'
31
+ logger.debug 'CLI Options:'
32
+ logger.json options
33
+
23
34
  set_member
24
35
 
25
36
  result = simplify(perform!)
@@ -60,6 +71,8 @@ module Usps
60
71
  else
61
72
  # Query
62
73
  end
74
+
75
+ logger.debug "iMIS ID: #{api.imis_id}"
63
76
  end
64
77
 
65
78
  # rubocop:disable Metrics
@@ -118,8 +131,10 @@ module Usps
118
131
 
119
132
  # Hash includes Usps::Imis::Data
120
133
  if data.is_a?(Hash) && !options[:business_objects]
134
+ logger.debug 'Returning simplified Data#properties'
121
135
  data.properties(include_ids: options[:include_ids])
122
136
  elsif data.is_a?(Array) && data.all? { it.is_a?(Hash) }
137
+ logger.debug 'Returning simplified Array<Data#properties>'
123
138
  data.map { it.properties(include_ids: options[:include_ids]) }
124
139
  else
125
140
  data
@@ -128,7 +143,10 @@ module Usps
128
143
 
129
144
  # :nocov:
130
145
  def output(&block)
131
- return if ENV.fetch('SUPPRESS_OUTPUT', false)
146
+ if ENV.fetch('SUPPRESS_OUTPUT', false)
147
+ logger.debug 'Output suppressed'
148
+ return
149
+ end
132
150
 
133
151
  puts JSON.dump(block.call) if block_given?
134
152
  end
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'logger'
4
+ require_relative 'logger_formatter'
5
+
3
6
  module Usps
4
7
  module Imis
5
8
  # API Configuration
@@ -16,7 +19,8 @@ module Usps
16
19
  @imis_id_query_name = ENV.fetch('IMIS_ID_QUERY_NAME', nil)
17
20
  @username = ENV.fetch('IMIS_USERNAME', nil)
18
21
  @password = ENV.fetch('IMIS_PASSWORD', nil)
19
- @logger = ActiveSupport::TaggedLogging.new(Logger.new($stdout, level: :info))
22
+ @base_logger = Logger.new($stdout, level: :info)
23
+ @logger = ActiveSupport::TaggedLogging.new(@base_logger)
20
24
 
21
25
  yield self if block_given?
22
26
 
@@ -28,7 +32,8 @@ module Usps
28
32
  end
29
33
 
30
34
  def logger=(logger)
31
- @logger = ActiveSupport::TaggedLogging.new(logger)
35
+ @base_logger = logger.tap { it.formatter = LoggerFormatter.new }
36
+ @logger = ActiveSupport::TaggedLogging.new(@base_logger)
32
37
  end
33
38
 
34
39
  def silence!
@@ -48,7 +53,7 @@ module Usps
48
53
 
49
54
  # Ruby 3.5 instance variable filter
50
55
  #
51
- def instance_variables_to_inspect = instance_variables - %i[@password @logger]
56
+ def instance_variables_to_inspect = instance_variables - %i[@password @base_logger @logger]
52
57
 
53
58
  # Parameters to filter out of logging
54
59
  #
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'logger_formatter'
4
+
5
+ module Usps
6
+ module Imis
7
+ # Formatted logger with additional helpers
8
+ #
9
+ class Logger < ::Logger
10
+ def initialize(...)
11
+ super
12
+ self.formatter = LoggerFormatter.new
13
+ end
14
+
15
+ def multiline(string)
16
+ string.split("\n").each { |line| debug(line) }
17
+ end
18
+
19
+ def json(data)
20
+ tagged('JSON') { multiline(JSON.pretty_generate(data)) }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Usps
4
+ module Imis
5
+ # Formats log statements
6
+ #
7
+ class LoggerFormatter < ::Logger::Formatter
8
+ def call(severity, time, _progname, message)
9
+ log_chunks = [
10
+ format('%-5s', severity.to_s),
11
+ "[#{$PROCESS_ID}]",
12
+ "[#{time.strftime('%Y-%m-%d %H:%M:%S %Z')}]",
13
+ '[iMIS Ruby API]',
14
+ '|',
15
+ formatted_tags,
16
+ '|',
17
+ message.sub(/^#{Regexp.escape(tags_text)}/, '')
18
+ ]
19
+ "#{log_chunks.join(' ')}\n"
20
+ end
21
+
22
+ private
23
+
24
+ def formatted_tags
25
+ tags = current_tags || []
26
+ tags&.any? ? tags.join(' | ') : ''
27
+ end
28
+ end
29
+ end
30
+ end
@@ -21,11 +21,16 @@ module Usps
21
21
  #
22
22
  attr_reader :api
23
23
 
24
+ # Tagged logger
25
+ #
26
+ attr_reader :logger
27
+
24
28
  # A new instance of +Mapper+
25
29
  #
26
30
  def initialize(api = nil, imis_id: nil)
27
31
  @api = api || Api.new
28
32
  @api.imis_id = imis_id if imis_id
33
+ @logger ||= Imis.logger('Mapper')
29
34
  end
30
35
 
31
36
  # Get a member's data for a specific field by arbitrary field name
@@ -107,12 +112,10 @@ module Usps
107
112
 
108
113
  # Ruby 3.5 instance variable filter
109
114
  #
110
- def instance_variables_to_inspect = instance_variables - %i[@api]
115
+ def instance_variables_to_inspect = instance_variables - %i[@api @logger]
111
116
 
112
117
  private
113
118
 
114
- def logger = Imis.logger('Mapper')
115
-
116
119
  def map_update(field_key)
117
120
  missing_mapping!(field_key) unless FIELD_MAPPING.key?(field_key.to_sym)
118
121
 
@@ -10,9 +10,14 @@ module Usps
10
10
  #
11
11
  attr_reader :api
12
12
 
13
+ # Tagged logger
14
+ #
15
+ attr_reader :logger
16
+
13
17
  def initialize(api = nil, imis_id: nil)
14
18
  @api = api || Api.new
15
19
  @api.imis_id = imis_id if imis_id
20
+ @logger ||= Imis.logger('Panel')
16
21
  end
17
22
 
18
23
  # Get a specific object from the Panel
@@ -100,12 +105,10 @@ module Usps
100
105
 
101
106
  # Ruby 3.5 instance variable filter
102
107
  #
103
- def instance_variables_to_inspect = instance_variables - %i[@api]
108
+ def instance_variables_to_inspect = instance_variables - %i[@api @logger]
104
109
 
105
110
  private
106
111
 
107
- def logger = Imis.logger('Panel')
108
-
109
112
  def business_object
110
113
  raise Errors::PanelUnimplementedError.from(self.class.name, 'business_object')
111
114
  end
@@ -40,6 +40,10 @@ module Usps
40
40
  #
41
41
  attr_reader :next_page
42
42
 
43
+ # Tagged logger
44
+ #
45
+ attr_reader :logger
46
+
43
47
  # A new instance of +Query+
44
48
  #
45
49
  # @param api [Api] Parent to use for making requests
@@ -55,7 +59,9 @@ module Usps
55
59
  @page_size = page_size
56
60
  @offset = offset
57
61
  @count = 0
62
+ @logger ||= Imis.logger('Query', query_type)
58
63
 
64
+ logger.debug inspect
59
65
  logger.debug "URI: #{uri}"
60
66
  end
61
67
 
@@ -92,9 +98,9 @@ module Usps
92
98
 
93
99
  @count += result['Count'] || 0
94
100
  total = result['TotalCount']
95
- logger.info " -> #{@count} / #{total} #{'item'.pluralize(total)}"
96
- logger.debug ' -> Query page data:'
97
- JSON.pretty_generate(result).split("\n").each { logger.debug " -> #{it}" }
101
+ logger.info "#{@count} / #{total} #{'item'.pluralize(total)}"
102
+ logger.debug 'Query page data:'
103
+ logger.json result
98
104
 
99
105
  @offset = result['NextOffset']
100
106
  @next_page = result['HasNext']
@@ -120,7 +126,7 @@ module Usps
120
126
 
121
127
  # Ruby 3.5 instance variable filter
122
128
  #
123
- def instance_variables_to_inspect = instance_variables - %i[@api]
129
+ def instance_variables_to_inspect = instance_variables - %i[@api @logger]
124
130
 
125
131
  private
126
132
 
@@ -139,8 +145,6 @@ module Usps
139
145
  "#{Imis::BusinessObject::API_PATH}/#{query_name}?#{path_params.to_query}"
140
146
  end
141
147
  end
142
-
143
- def logger = Imis.logger("#{query_type} Query")
144
148
  end
145
149
  end
146
150
  end
@@ -7,7 +7,7 @@ module Usps
7
7
  module Requests
8
8
  private
9
9
 
10
- def logger = Imis.logger
10
+ def logger = raise("#{self.class.name} must implement #logger")
11
11
 
12
12
  def token = api.token
13
13
  def token_expiration = api.token_expiration
@@ -39,12 +39,15 @@ module Usps
39
39
 
40
40
  def submit(uri, request)
41
41
  logger.info 'Submitting request to iMIS'
42
- logger.debug " -> #{request.class.name.demodulize.upcase} #{uri}"
43
- sanitized_request_body(request).split("\n").each { logger.debug " -> #{it}" }
44
- client(uri).request(request).tap do |result|
45
- raise Errors::ResponseError.from(result) unless result.is_a?(Net::HTTPSuccess)
42
+ logger.tagged('Request') do
43
+ logger.debug "#{request.class.name.demodulize.upcase} #{uri}"
44
+ logger.multiline sanitized_request_body(request)
46
45
 
47
- logger.info 'Request succeeded'
46
+ client(uri).request(request).tap do |result|
47
+ raise Errors::ResponseError.from(result) unless result.is_a?(Net::HTTPSuccess)
48
+
49
+ logger.info 'Request succeeded'
50
+ end
48
51
  end
49
52
  end
50
53
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Usps
4
4
  module Imis
5
- VERSION = '0.11.15'
5
+ VERSION = '0.11.17'
6
6
  end
7
7
  end
data/lib/usps/imis.rb CHANGED
@@ -51,7 +51,7 @@ module Usps
51
51
 
52
52
  # Logger (with optional nested tags) to write to
53
53
  #
54
- def logger(*tags) = configuration.logger.tagged('iMIS', *tags)
54
+ def logger(*) = configuration.logger.tagged(*)
55
55
 
56
56
  # Gem version
57
57
  #
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: usps-imis-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.15
4
+ version: 0.11.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Fiander
@@ -93,6 +93,8 @@ files:
93
93
  - lib/usps/imis/errors/panel_unimplemented_error.rb
94
94
  - lib/usps/imis/errors/response_error.rb
95
95
  - lib/usps/imis/errors/unexpected_property_type_error.rb
96
+ - lib/usps/imis/logger.rb
97
+ - lib/usps/imis/logger_formatter.rb
96
98
  - lib/usps/imis/mapper.rb
97
99
  - lib/usps/imis/mocks.rb
98
100
  - lib/usps/imis/mocks/business_object.rb