active_elastic_job 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2c8395a6c3ac158c58cf57615c9df6bbe847ea76
4
- data.tar.gz: 33b4188334606d4df92dd4fff85e2fc6a5558629
3
+ metadata.gz: f7f80373d7f57286083c91bfb62632d463df9b7a
4
+ data.tar.gz: 30ad4c79acf1d9a8393092bdf430f7416b606239
5
5
  SHA512:
6
- metadata.gz: e53f0f7464e92f180bbd19af890a8069dbecafab7032865c4eb8f83052c7f01a3497c83383e023c996097875c4208fb70b1274e83e868fb80d50257eaeb53390
7
- data.tar.gz: 44fab25e6c687772f19b01816ee56f94ccefc06e517a541b5aad1363f9a72f289d6a65713f5e663d89a7dda86844d070ca5ad8e4c3f0670b93102b5760958e17
6
+ metadata.gz: 72d3f884abb6f6b16d0c43fe2c537ba64d80acba7e65ff2a97faaea99d16b4e6b45666aeb33f232b95cf227b8d16af172385bc9dfcc5d978720fe97f3ea6742a
7
+ data.tar.gz: b5f4204e84cc39de88f67f321fbc758021b1fbcbb698cc7c991e1a1e0e14b0b9d6d177f92f92191840a01e9e72e29e4b5796886dfa4d2482e310889b89eafda1
@@ -1,4 +1,4 @@
1
- require 'digest'
1
+ require 'openssl'
2
2
  module ActiveElasticJob
3
3
  # This module provides methods that calculate the MD5 digest for Amazon
4
4
  # SQS message bodies and message attributes.
@@ -29,35 +29,30 @@ module ActiveElasticJob
29
29
  'Number' => 1
30
30
  }
31
31
 
32
- CHARSET_ENCODING = Encoding::UTF_8
32
+ NORMALIZED_ENCODING = Encoding::UTF_8
33
33
 
34
- # Returns MD5 digest of +message_body+.
35
34
  def md5_of_message_body(message_body)
36
35
  OpenSSL::Digest::MD5.hexdigest(message_body)
37
36
  end
38
37
 
39
- # Returns MD5 digest of +message_attributes+.
40
- #
41
- # The calculation follows the official algorithm which
42
- # is specified by Amazon.
43
38
  def md5_of_message_attributes(message_attributes)
44
- encoded = message_attributes.each.with_object({ }) do |(name, v), hash|
45
- hash[name.to_s] = ""
46
- data_type = v['data_type'] || v[:data_type]
39
+ encoded = { }
40
+ message_attributes.each do |name, attribute|
41
+ name = name.to_s
42
+ encoded[name] = String.new
43
+ encoded[name] << encode_length_and_bytes(name) <<
44
+ encode_length_and_bytes(attribute[:data_type]) <<
45
+ [TRANSPORT_TYPE_ENCODINGS[attribute[:data_type]]].pack('C'.freeze)
47
46
 
48
- hash[name.to_s] << encode_length_and_bytes(name.to_s) <<
49
- encode_length_and_bytes(data_type) <<
50
- [ TRANSPORT_TYPE_ENCODINGS[data_type] ].pack('C')
51
-
52
- if string_value = v['string_value'] || v[:string_value]
53
- hash[name.to_s] << encode_length_and_string(string_value)
54
- elsif binary_value = v['binary_value'] || v[:binary_value]
55
- hash[name.to_s] << encode_length_and_bytes(binary_value)
47
+ if string_value = attribute[:string_value]
48
+ encoded[name] << encode_length_and_string(string_value)
49
+ elsif binary_value = attribute[:binary_value]
50
+ encoded[name] << encode_length_and_bytes(binary_value)
56
51
  end
57
52
  end
58
53
 
59
- buffer = encoded.keys.sort.reduce("") do |b, name|
60
- b << encoded[name]
54
+ buffer = encoded.keys.sort.reduce(String.new) do |string, name|
55
+ string << encoded[name]
61
56
  end
62
57
  OpenSSL::Digest::MD5.hexdigest(buffer)
63
58
  end
@@ -65,15 +60,13 @@ module ActiveElasticJob
65
60
  private
66
61
 
67
62
  def encode_length_and_string(string)
68
- return '' if string.nil?
69
63
  string = String.new(string)
70
- string.encode!(CHARSET_ENCODING)
64
+ string.encode!(NORMALIZED_ENCODING)
71
65
  encode_length_and_bytes(string)
72
66
  end
73
67
 
74
68
  def encode_length_and_bytes(bytes)
75
- return '' if bytes.nil?
76
- [ bytes.bytesize, bytes ].pack("L>a#{bytes.bytesize}")
69
+ [bytes.bytesize, bytes].pack('L>a*'.freeze)
77
70
  end
78
71
  end
79
72
  end
@@ -13,20 +13,22 @@ module ActiveElasticJob
13
13
  @secret = secret
14
14
  end
15
15
 
16
- def verify!(message, digest)
16
+ def verify(message, digest)
17
17
  if message.nil? || message.blank? || digest.nil? || digest.blank?
18
- raise InvalidDigest
18
+ return false
19
19
  end
20
20
 
21
- unless ActiveSupport::SecurityUtils.secure_compare(digest, generate_digest(message))
22
- raise InvalidDigest
23
- end
24
- true
21
+ return ActiveSupport::SecurityUtils.secure_compare(
22
+ digest, generate_digest(message))
23
+ end
24
+
25
+ def verify!(message, digest)
26
+ raise InvalidDigest unless verify(message, digest)
25
27
  end
26
28
 
27
29
  def generate_digest(message)
28
30
  require 'openssl' unless defined?(OpenSSL)
29
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get('SHA1').new, @secret, message)
31
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, @secret, message)
30
32
  end
31
33
  end
32
34
  end
@@ -5,8 +5,8 @@ module ActiveElasticJob
5
5
  # This middleware intercepts requests which are sent by the SQS daemon
6
6
  # running in {Amazon Elastic Beanstalk worker environments}[http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features-managing-env-tiers.html].
7
7
  # It does this by looking at the +User-Agent+ header.
8
- # Furthermore, it verifies the digest which is sent along with a legit SQS message,
9
- # and passed as an HTTP header in the resulting request.
8
+ # Furthermore, it verifies the digest which is sent along with a legit SQS
9
+ # message, and passed as an HTTP header in the resulting request.
10
10
  # The digest is based on Rails' +secrets.secret_key_base+.
11
11
  # Therefore, the application running in the web environment, which generates
12
12
  # the digest, and the application running in the worker
@@ -36,11 +36,20 @@ module ActiveElasticJob
36
36
  job = JSON.load(request.body)
37
37
  ActiveJob::Base.execute(job)
38
38
  rescue ActiveElasticJob::MessageVerifier::InvalidDigest => e
39
- return ['403', {CONTENT_TYPE_HEADER_NAME => 'text/plain' }, ["incorrect digest"]]
39
+ return [
40
+ '403',
41
+ {CONTENT_TYPE_HEADER_NAME => 'text/plain' },
42
+ ["incorrect digest"]]
40
43
  rescue StandardError => e
41
- return ['500', {CONTENT_TYPE_HEADER_NAME => 'text/plain' }, [e.message]]
44
+ return [
45
+ '500',
46
+ {CONTENT_TYPE_HEADER_NAME => 'text/plain' },
47
+ [e.message]]
42
48
  end
43
- return [OK_RESPONSE_CODE , {CONTENT_TYPE_HEADER_NAME => CONTENT_TYPE }, [ '' ]]
49
+ return [
50
+ OK_RESPONSE_CODE ,
51
+ {CONTENT_TYPE_HEADER_NAME => CONTENT_TYPE },
52
+ [ '' ]]
44
53
  end
45
54
  @app.call(env)
46
55
  end
@@ -2,7 +2,7 @@ module ActiveElasticJob
2
2
  module VERSION
3
3
  MAJOR = 1
4
4
  MINOR = 4
5
- TINY = 0
5
+ TINY = 1
6
6
  PRE = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
@@ -8,9 +8,11 @@ module ActiveJob
8
8
  # environments}[http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features-managing-env-tiers.html].
9
9
  #
10
10
  # This adapter serializes job objects and sends them as a message to an
11
- # Amazon SQS queue specified by the job's queue name, see <tt>ActiveJob::Base.queue_as</tt>
11
+ # Amazon SQS queue specified by the job's queue name,
12
+ # see <tt>ActiveJob::Base.queue_as</tt>
12
13
  #
13
- # To use Active Elastic Job, set the queue_adapter config to +:active_elastic_job+.
14
+ # To use Active Elastic Job, set the queue_adapter config
15
+ # to +:active_elastic_job+.
14
16
  #
15
17
  # Rails.application.config.active_job.queue_adapter = :active_elastic_job
16
18
  class ActiveElasticJobAdapter
@@ -34,9 +36,9 @@ which exceeds the allowed maximum of #{MAX_MESSAGE_SIZE} bytes imposed by Amazon
34
36
  end
35
37
 
36
38
  # Raised when job queue does not exist. The job queue is determined by
37
- # <tt>ActiveJob::Base.queue_as</tt>. You can either: (1) create a new Amazon
38
- # SQS queue and attach a worker environment to it, or (2) select a different
39
- # queue for your jobs.
39
+ # <tt>ActiveJob::Base.queue_as</tt>. You can either: (1) create a new
40
+ # Amazon SQS queue and attach a worker environment to it, or (2) select a
41
+ # different queue for your jobs.
40
42
  #
41
43
  # Example:
42
44
  # * Open your AWS console and create an SQS queue named +high_priority+ in
@@ -49,12 +51,12 @@ which exceeds the allowed maximum of #{MAX_MESSAGE_SIZE} bytes imposed by Amazon
49
51
  # end
50
52
  class NonExistentQueue < Error
51
53
  def initialize(queue_name)
52
- msg = <<-MSG
53
- The job is bound to queue at #{queue_name}. Unfortunately a queue
54
- with this name does not exist in this region. Either create an Amazon SQS queue
55
- named #{queue_name} - you can do this in AWS console, make sure to select
56
- region '#{ENV['AWS_REGION']}' - or you select another queue for your jobs.
57
- MSG
54
+ msg = "The job is bound to queue at #{queue_name}. " <<
55
+ "Unfortunately a queue with this name does not exist in this " <<
56
+ "region. Either create an Amazon SQS queue named #{queue_name} - " <<
57
+ "you can do this in AWS console, make sure to select region " <<
58
+ "'#{ENV['AWS_REGION']}' - or you select another queue for your jobs."
59
+
58
60
  super msg
59
61
  end
60
62
  end
@@ -62,11 +64,12 @@ region '#{ENV['AWS_REGION']}' - or you select another queue for your jobs.
62
64
  # Raised when calculated MD5 digest does not match the MD5 Digest
63
65
  # of the response from Amazon SQS.
64
66
  class MD5MismatchError < Error
65
- def initialize( message_id)
66
- msg = <<-MSG
67
- MD5 returned by Amazon SQS does not match the calculation on the original request.
68
- The message with Message ID #{message_id} sent to SQS might be corrupted.
69
- MSG
67
+ def initialize(message_id)
68
+ msg = "MD5 returned by Amazon SQS does not match the calculation " <<
69
+ "on the original request. The message with Message ID " <<
70
+ "#{message_id} sent to SQS might be corrupted."
71
+
72
+ super msg
70
73
  end
71
74
  end
72
75
 
@@ -128,13 +131,14 @@ The message with Message ID #{message_id} sent to SQS might be corrupted.
128
131
  def calculate_delay(timestamp)
129
132
  delay = (timestamp - Time.current.to_f).to_i + 1
130
133
  if delay > MAX_DELAY_IN_MINUTES.minutes
131
- msg =<<-MSG
132
- Jobs cannot be scheduled more than #{MAX_DELAY_IN_MINUTES} minutes into the future.
133
- See http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html
134
- for further details!
135
- MSG
136
- raise RangeError
134
+ msg = "Jobs cannot be scheduled more than " <<
135
+ "#{MAX_DELAY_IN_MINUTES} minutes into the future. " <<
136
+ "See http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html" <<
137
+ " for further details!"
138
+
139
+ raise RangeError, msg
137
140
  end
141
+ delay = 0 if delay < 0
138
142
  delay
139
143
  end
140
144
 
@@ -158,7 +162,7 @@ for further details!
158
162
  @verifier.generate_digest(messsage_body)
159
163
  end
160
164
 
161
- def verify_md5_digests!(response, messsage_body, message_attributes = nil)
165
+ def verify_md5_digests!(response, messsage_body, message_attributes)
162
166
  if md5_of_message_body(messsage_body) != response.md5_of_message_body
163
167
  raise MD5MismatchError, response.message_id
164
168
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_elastic_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tawan Sierek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-09 00:00:00.000000000 Z
11
+ date: 2016-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk