philotic 1.1.1 → 1.2.0

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: b5aa6de95d72e998edad55939b1b194101189c96
4
- data.tar.gz: b1972e32e338076a218f18f96a32ca9150cb0ca1
3
+ metadata.gz: fb0f8544430bd4ed0961e39da04d9f8b31de77fb
4
+ data.tar.gz: 8179fe31b21760200bed1315dda3c2241998523b
5
5
  SHA512:
6
- metadata.gz: 3a3fc577e42079e2747e72b13905a831f1bdbccdfd7bbd6dae815e1fcb013fd1e8ee7e37d68444f4a773bea2c9005884c4f44d4be77ac20bae32de147f21a0a7
7
- data.tar.gz: 10075f5fd0473498dae8b45ea57eca725ffa48909eedb203cf31d9a8bcd7acb1a5f6b4642f275b313ccbb7f1a6f116ff0241b08b490187563357757461000cf0
6
+ metadata.gz: bf07ca965eb1503d85fa28910d37410d5076256f9dfe2f6d938643fa1cc0d43ce708541da7235f37172cd01da22520a695271d8b851248c7b9feb660a3e246b6
7
+ data.tar.gz: c37eedc369ed1c0f4257ba819f1596e6d41d177a0f4a1236f6fec432506b43f12f99a37b7a695532d7ef3ccf2c93f8fe9b517b4287c2003c75db32be1449cf3d
@@ -1,13 +1,17 @@
1
+ sudo: false
1
2
  language: ruby
2
3
  before_install: gem install bundler -v 1.10.6
3
4
  rvm:
4
5
  - 2.0.0
5
- - 2.1
6
- - 2.2
6
+ - 2.1.5
7
+ - 2.2.0
8
+ - 2.2.1
9
+ - 2.2.2
10
+ - 2.2.3
7
11
  - rbx-2
8
- # - jruby-19mode
12
+ - jruby-19mode
9
13
  - ruby-head
10
- # - jruby-head
14
+ - jruby-head
11
15
  script:
12
16
  - bundle exec rspec
13
17
  addons:
@@ -17,6 +21,11 @@ addons:
17
21
  notifications:
18
22
  hipchat:
19
23
  rooms:
20
- secure: akLY832/pt0+9Y2TFKpzW08bagPMY//AcQJ5JGzc0yd3hZbXTlkW4S8bMEclBeHBqLGCV6vaWeN90PiYwIBs4IWlxopPAop4BEWeqRvD8+B4fxarXYwejt54vH3v4iCnHhSNBpFJDbykyfL0f0g9fhvM48eHzhBXTxPZfpQ9nXs=
24
+ secure: HXE1RU8b95gp0/4QoQXws1dVSw+uHGg0wqb/q5EKBjvKXxaqfIrBWeZlTAn3ykz8HQja8YoUOlwFL7lpmwdbXlbmuSb0RPyqWURNvooDw3twn675E0dtf5vlKWbADsIK73Gs1LfR3Gpb0l/85T5P+/knNRkh9p43hqiRaW/LJ/M=
21
25
  template:
22
- - '%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}'
26
+ - "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}"
27
+ matrix:
28
+ allow_failures:
29
+ - rvm: jruby-19mode
30
+ - rvm: jruby-head
31
+ - rvm: ruby-head
data/README.md CHANGED
@@ -69,7 +69,12 @@ end
69
69
 
70
70
  ### Tested with the following Rubies
71
71
  * 2.0.0
72
- * 2.1.x
73
- * 2.2.x
74
- * rbx-2
75
- * ruby-head
72
+ * 2.1.5
73
+ * 2.2.0
74
+ * 2.2.1
75
+ * 2.2.2
76
+ * 2.2.3
77
+ * rbx*2
78
+ * jruby*19mode
79
+ * ruby*head
80
+ * jruby*head
@@ -7,6 +7,8 @@ require 'awesome_print'
7
7
 
8
8
  philotic = Philotic::Connection.new
9
9
 
10
+ MessageClass = Class.new(Philotic::Message)
11
+
10
12
  # override the message return handler
11
13
  philotic.config.message_return_handler = lambda do |basic_return, metadata, message|
12
14
  philotic.logger.warn { "Message returned. reply_text: #{basic_return.reply_text}" }
@@ -23,7 +25,7 @@ end
23
25
  # to keep the parent thread alive while the subscribers do their thing
24
26
  # but this infinite publish loop takes care of that
25
27
  loop do
26
- message = Philotic::Message.new({header_key: "header_#{[1, 2].sample}"}, {payload_key: 'payload_value'})
28
+ message = MessageClass.new({header_key: "header_#{[1, 2].sample}"}, {payload_key: 'payload_value'})
27
29
  philotic.publish message
28
30
  # only send a message every two seconds so we can see whats going on
29
31
  sleep 2
@@ -1,12 +1,6 @@
1
1
  require 'pathname'
2
2
 
3
3
  module Philotic
4
- class << self
5
- def root
6
- ::Pathname.new File.expand_path('../../', __FILE__)
7
- end
8
- end
9
-
10
4
  end
11
5
 
12
6
  require 'philotic/constants'
@@ -17,6 +11,7 @@ require 'philotic/version'
17
11
  require 'philotic/config'
18
12
  require 'philotic/message'
19
13
  require 'philotic/publisher'
14
+ require 'philotic/serialization'
20
15
  require 'philotic/subscriber'
21
16
  require 'philotic/consumer'
22
17
  require 'philotic/logging'
@@ -1,46 +1,20 @@
1
1
  require 'yaml'
2
- require 'json'
2
+ require 'multi_json'
3
+ require 'oj'
3
4
  require 'singleton'
4
5
  require 'forwardable'
5
6
  require 'cgi'
6
7
  require 'bunny/session'
7
8
  require 'logger'
9
+ require 'philotic/config/defaults'
10
+ require 'active_support/inflections'
8
11
 
9
12
  module Philotic
10
13
  class Config
11
14
 
12
- ENV_PREFIX = 'PHILOTIC'
15
+ include Defaults
13
16
 
14
- DEFAULT_DISABLE_PUBLISH = false
15
- DEFAULT_INITIALIZE_NAMED_QUEUES = false
16
- DEFAULT_DELETE_EXISTING_QUEUES = false
17
- DEFAULT_LOG_LEVEL = Logger::DEBUG
18
- DEFAULT_RABBIT_SCHEME = 'amqp'
19
- DEFAULT_RABBIT_HOST = 'localhost'
20
- DEFAULT_RABBIT_PORT = 5672
21
- DEFAULT_RABBIT_USER = 'guest'
22
- DEFAULT_RABBIT_PASSWORD = 'guest'
23
- DEFAULT_RABBIT_VHOST = '%2f' # '/'
24
- DEFAULT_RABBIT_URL = "#{DEFAULT_RABBIT_SCHEME}://#{DEFAULT_RABBIT_USER}:#{DEFAULT_RABBIT_PASSWORD}@#{DEFAULT_RABBIT_HOST}:#{DEFAULT_RABBIT_PORT}/#{DEFAULT_RABBIT_VHOST}"
25
- DEFAULT_EXCHANGE_NAME = 'philotic.headers'
26
- DEFAULT_TIMEOUT = 2
27
- DEFAULT_ROUTING_KEY = nil
28
- DEFAULT_PERSISTENT = false
29
- DEFAULT_IMMEDIATE = false
30
- DEFAULT_MANDATORY = false
31
- DEFAULT_CONTENT_TYPE = 'application/json'
32
- DEFAULT_CONTENT_ENCODING = nil
33
- DEFAULT_PRIORITY = nil
34
- DEFAULT_MESSAGE_ID = nil
35
- DEFAULT_CORRELATION_ID = nil
36
- DEFAULT_REPLY_TO = nil
37
- DEFAULT_TYPE = nil
38
- DEFAULT_USER_ID = nil
39
- DEFAULT_APP_ID = nil
40
- DEFAULT_TIMESTAMP = nil
41
- DEFAULT_EXPIRATION = nil
42
- DEFAULT_CONNECTION_ATTEMPTS = 3
43
- DEFAULT_PREFETCH_COUNT = 0
17
+ ENV_PREFIX = 'PHILOTIC'
44
18
 
45
19
  attr_accessor :connection
46
20
 
@@ -53,29 +27,6 @@ module Philotic
53
27
  connection.logger
54
28
  end
55
29
 
56
- def defaults
57
- @defaults ||= Hash[Config.constants.select { |c| c.to_s.start_with? 'DEFAULT_' }.collect do |c|
58
- key = c.slice(8..-1).downcase.to_sym
59
-
60
- env_key = "#{ENV_PREFIX}_#{key}".upcase
61
-
62
- [key, ENV[env_key] || Config.const_get(c)]
63
- end
64
- ]
65
- end
66
-
67
- Config.constants.each do |c|
68
- if c.to_s.start_with? 'DEFAULT_'
69
- attr_symbol = c.slice(8..-1).downcase.to_sym
70
- attr_writer attr_symbol
71
- class_eval %Q{
72
- def #{attr_symbol}
73
- @#{attr_symbol} ||= defaults[:#{attr_symbol}]
74
- end
75
- }
76
- end
77
- end
78
-
79
30
  def log_level
80
31
  @log_level ||= defaults[:log_level].to_i
81
32
  end
@@ -88,20 +39,7 @@ module Philotic
88
39
  @prefetch_count ||= defaults[:prefetch_count].to_i
89
40
  end
90
41
 
91
- attr_writer :connection_failed_handler, :connection_loss_handler, :message_return_handler
92
-
93
- def connection_failed_handler
94
- @connection_failed_handler ||= lambda do |settings|
95
- logger.error { "RabbitMQ connection failure: #{sanitized_rabbit_url}" }
96
- end
97
- end
98
-
99
- def connection_loss_handler
100
- @connection_loss_handler ||= lambda do |conn, settings|
101
- logger.warn { "RabbitMQ connection loss: #{sanitized_rabbit_url}" }
102
- conn.reconnect(false, 2)
103
- end
104
- end
42
+ attr_writer :message_return_handler
105
43
 
106
44
  def message_return_handler
107
45
  @message_return_handler ||= lambda do |basic_return, metadata, payload|
@@ -118,7 +56,7 @@ module Philotic
118
56
  current_value = send("rabbit_#{setting}")
119
57
 
120
58
  # only use the value from the URI if the existing value is nil or the default
121
- if settings[setting] && [self.class.const_get("default_rabbit_#{setting}".upcase), nil].include?(current_value)
59
+ if settings[setting] && [Defaults.const_get("rabbit_#{setting}".upcase), nil].include?(current_value)
122
60
  send("rabbit_#{setting}=", settings[setting])
123
61
  end
124
62
  end
@@ -146,5 +84,14 @@ module Philotic
146
84
  config = YAML.load_file(filename)
147
85
  load_config(config[env])
148
86
  end
87
+
88
+ def serializations
89
+ self.serializations = MultiJson.load(defaults[:serializations]) unless @serializations
90
+ @serializations
91
+ end
92
+
93
+ def content_type
94
+ Philotic::Serialization::Serializer.factory(serializations.last).content_type
95
+ end
149
96
  end
150
- end
97
+ end
@@ -0,0 +1,71 @@
1
+ require 'logger'
2
+
3
+ module Philotic
4
+ class Config
5
+ module Defaults
6
+
7
+ DISABLE_PUBLISH = false
8
+ INITIALIZE_NAMED_QUEUES = false
9
+ DELETE_EXISTING_QUEUES = false
10
+ LOG_LEVEL = Logger::DEBUG
11
+ RABBIT_SCHEME = 'amqp'
12
+ RABBIT_HOST = 'localhost'
13
+ RABBIT_PORT = 5672
14
+ RABBIT_USER = 'guest'
15
+ RABBIT_PASSWORD = 'guest'
16
+ RABBIT_VHOST = '%2f' # '/'
17
+ RABBIT_URL = "#{RABBIT_SCHEME}://#{RABBIT_USER}:#{RABBIT_PASSWORD}@#{RABBIT_HOST}:#{RABBIT_PORT}/#{RABBIT_VHOST}"
18
+ EXCHANGE_NAME = 'philotic.headers'
19
+ ROUTING_KEY = nil
20
+ PERSISTENT = false
21
+ IMMEDIATE = false
22
+ MANDATORY = false
23
+ SERIALIZATIONS = '["json"]' # serializations is expected to be a JSON ray of strings
24
+ CONTENT_TYPE = 'application/json'
25
+ CONTENT_ENCODING = nil
26
+ PRIORITY = nil
27
+ MESSAGE_ID = nil
28
+ CORRELATION_ID = nil
29
+ REPLY_TO = nil
30
+ TYPE = nil
31
+ USER_ID = nil
32
+ APP_ID = nil
33
+ TIMESTAMP = nil
34
+ EXPIRATION = nil
35
+ CONNECTION_ATTEMPTS = 3
36
+ PREFETCH_COUNT = 0
37
+ AUTOMATICALLY_RECOVER = true
38
+ NETWORK_RECOVERY_INTERVAL = 5 # seconds
39
+ CONTINUATION_TIMEOUT = 4000 # ms
40
+ RAISE_ERROR_ON_PUBLISH = false
41
+ ENCRYPTION_KEY = nil
42
+
43
+
44
+ def defaults
45
+ @defaults ||= Hash[Philotic::Config::Defaults.constants.map do |c|
46
+ key = c.downcase.to_sym
47
+
48
+ env_key = "#{ENV_PREFIX}_#{key}".upcase
49
+
50
+ [key, ENV[env_key] || Philotic::Config::Defaults.const_get(c)]
51
+ end
52
+ ]
53
+ end
54
+
55
+ def self.included(base)
56
+ Philotic::Config::Defaults.constants.each do |c|
57
+ attr_symbol = c.downcase.to_sym
58
+ base.send(:attr_writer, attr_symbol)
59
+ base.class_eval %Q{
60
+ def #{attr_symbol}
61
+ unless defined? @#{attr_symbol}
62
+ @#{attr_symbol} = defaults[:#{attr_symbol}]
63
+ end
64
+ @#{attr_symbol}
65
+ end
66
+ }
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -82,9 +82,9 @@ module Philotic
82
82
 
83
83
  def connection_settings
84
84
  {
85
- timeout: config.timeout.to_i,
86
- automatic_recovery: true,
87
- on_tcp_connection_failure: config.connection_failed_handler,
85
+ automatically_recover: config.automatically_recover,
86
+ network_recovery_interval: config.network_recovery_interval,
87
+ continuation_timeout: config.continuation_timeout,
88
88
  }
89
89
  end
90
90
 
@@ -1,47 +1,39 @@
1
1
  module Philotic
2
2
 
3
- CONNECTION_OPTIONS = [
4
- :rabbit_host,
5
- :connection_failed_handler,
6
- :connection_loss_handler,
7
- :timeout,
8
- ]
9
- EXCHANGE_OPTIONS = [
10
- :exchange_name,
11
- :message_return_handler,
12
- ]
13
- MESSAGE_OPTIONS = [
14
- :routing_key,
15
- :persistent,
16
- :immediate,
17
- :mandatory,
18
- :content_type,
19
- :content_encoding,
20
- :priority,
21
- :message_id,
22
- :correlation_id,
23
- :reply_to,
24
- :type,
25
- :user_id,
26
- :app_id,
27
- :timestamp,
28
- :expiration,
3
+ MESSAGE_OPTIONS = [
4
+ :routing_key,
5
+ :persistent,
6
+ :immediate,
7
+ :mandatory,
8
+ :content_type,
9
+ :content_encoding,
10
+ :priority,
11
+ :message_id,
12
+ :correlation_id,
13
+ :reply_to,
14
+ :type,
15
+ :user_id,
16
+ :app_id,
17
+ :timestamp,
18
+ :expiration,
29
19
  ]
30
20
 
31
21
  PHILOTIC_HEADERS = [
32
- :philotic_firehose,
33
- :philotic_product,
34
- :philotic_component,
35
- :philotic_message_type,
22
+ :philotic_firehose,
23
+ :philotic_product,
24
+ :philotic_component,
25
+ :philotic_message_type,
26
+ :philotic_serializations,
27
+
36
28
  ]
37
29
 
38
30
  DEFAULT_NAMED_QUEUE_OPTIONS = {
39
- auto_delete: false,
40
- durable: true
31
+ auto_delete: false,
32
+ durable: true
41
33
  }
42
34
  DEFAULT_ANONYMOUS_QUEUE_OPTIONS = {
43
- auto_delete: true,
44
- durable: false
35
+ auto_delete: true,
36
+ durable: false
45
37
  }
46
38
 
47
39
  DEFAULT_SUBSCRIBE_OPTIONS = {}
@@ -1,5 +1,6 @@
1
1
  require 'philotic/constants'
2
2
  require 'philotic/singleton'
3
+ require 'active_support/inflections'
3
4
 
4
5
  module Philotic
5
6
  class Message
@@ -30,9 +31,10 @@ module Philotic
30
31
 
31
32
  def initialize(routables={}, payloads={}, connection=nil)
32
33
  raise NotInstantiableError if self.class == Philotic::Message
33
- self.timestamp = Time.now.to_i
34
- self.philotic_firehose = true
35
- self.connection = connection
34
+ self.timestamp = Time.now.to_i
35
+ self.philotic_firehose = true
36
+ self.connection = connection
37
+ self.philotic_serializations = self.connection.config.serializations
36
38
 
37
39
  # dynamically insert any passed in routables into both attr_routable
38
40
  # and attr_payload
@@ -1,4 +1,5 @@
1
1
  require 'philotic/constants'
2
+ require 'philotic/serialization/serializer'
2
3
 
3
4
  module Philotic
4
5
  class Publisher
@@ -26,6 +27,7 @@ module Philotic
26
27
  rescue => e
27
28
  message.publish_error = e
28
29
  logger.error e.message
30
+ raise e if config.raise_error_on_publish
29
31
  end
30
32
  message
31
33
  end
@@ -55,7 +57,7 @@ module Philotic
55
57
 
56
58
  payload = normalize_payload_times(payload)
57
59
 
58
- connection.exchange.publish(payload.to_json, metadata)
60
+ connection.exchange.publish(Philotic::Serialization::Serializer.dump(payload, metadata), metadata)
59
61
  log_message_published(:debug, metadata, payload, 'published message')
60
62
  true
61
63
  end
@@ -0,0 +1,8 @@
1
+ require 'philotic/serialization/serializer'
2
+ require 'philotic/serialization/encryptor'
3
+ require 'philotic/serialization/json'
4
+
5
+ module Philotic
6
+ module Serialization
7
+ end
8
+ end
@@ -0,0 +1,56 @@
1
+ require 'encryptor'
2
+ require 'philotic/serialization/serializer'
3
+ require 'base64'
4
+
5
+ module Philotic
6
+ module Serialization
7
+ module Encryptor
8
+ extend self
9
+
10
+ def content_type
11
+ 'application/json'
12
+ end
13
+
14
+ def serialization
15
+ :encrypted
16
+ end
17
+
18
+ def default_encryption_key
19
+ Philotic.config.encryption_key
20
+ end
21
+
22
+ def random_salt
23
+ Base64.encode64 SecureRandom.random_bytes(256)
24
+ end
25
+
26
+ def default_algorithm
27
+ 'aes-256-cbc'
28
+ end
29
+
30
+ def random_iv(algorithm = default_algorithm)
31
+ OpenSSL::Cipher::Cipher.new(algorithm).random_iv
32
+ end
33
+
34
+ def key
35
+ @key ||= default_encryption_key
36
+ end
37
+
38
+ def dump(payload, metadata)
39
+ metadata[:headers][:encryption] ||= {}
40
+ algorithm = (metadata[:headers][:encryption][:algorithm] ||= default_algorithm)
41
+ iv = Base64.decode64(metadata[:headers][:encryption][:iv] ||= Base64.encode64(random_iv(algorithm)))
42
+ salt = Base64.decode64(metadata[:headers][:encryption][:salt] ||= Base64.encode64(random_salt))
43
+ Base64.encode64 ::Encryptor.encrypt(payload, key: key, iv: iv, salt: salt)
44
+ end
45
+
46
+ def load(payload, metadata)
47
+ headers = metadata[:headers].deep_dup.deep_symbolize_keys
48
+
49
+ iv = Base64.decode64 headers[:encryption][:iv]
50
+ salt = Base64.decode64 headers[:encryption][:salt]
51
+ ::Encryptor.decrypt(Base64.decode64(payload), key: key, iv: iv, salt: salt)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ Philotic::Serialization::Serializer.register Philotic::Serialization::Encryptor
@@ -0,0 +1,29 @@
1
+ require 'multi_json'
2
+ require 'oj'
3
+
4
+ require 'philotic/serialization/serializer'
5
+
6
+ module Philotic
7
+ module Serialization
8
+ module Json
9
+ extend self
10
+
11
+ def content_type
12
+ 'application/json'
13
+ end
14
+
15
+ def serialization
16
+ :json
17
+ end
18
+
19
+ def dump(payload, metadata)
20
+ MultiJson.dump payload
21
+ end
22
+
23
+ def load(payload, metadata)
24
+ MultiJson.load payload
25
+ end
26
+ end
27
+ end
28
+ end
29
+ Philotic::Serialization::Serializer.register Philotic::Serialization::Json
@@ -0,0 +1,44 @@
1
+ module Philotic
2
+ module Serialization
3
+ module Serializer
4
+ extend self
5
+
6
+ def serializers
7
+ @serializers ||= {}
8
+ end
9
+
10
+ def factory(serialization)
11
+ serialization = serialization.to_s.downcase.to_sym
12
+ @serializers[serialization]
13
+ end
14
+
15
+ def register(serializer)
16
+ serializers[serializer.serialization] = serializer
17
+ end
18
+
19
+ # return the fully deserialized payload
20
+ def load(payload, metadata)
21
+ _transform(:load, payload, metadata)
22
+ end
23
+
24
+ def dump(payload, metadata)
25
+ _transform(:dump, payload, metadata)
26
+ end
27
+
28
+ private
29
+ def _transform(dump_or_load, payload, metadata)
30
+ headers = metadata[:headers].deep_dup.deep_symbolize_keys
31
+
32
+ serializations = headers[:philotic_serializations]
33
+
34
+ serializations.reverse! if(dump_or_load == :load)
35
+
36
+ serializations.reduce(payload.dup) do |transformed, serialization|
37
+ serializer = factory serialization
38
+ (serializer &&
39
+ serializer.public_send(dump_or_load, transformed, metadata)) || transformed
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,5 +1,6 @@
1
1
  require 'philotic/constants'
2
2
  require 'philotic/message'
3
+ require 'philotic/serialization/serializer'
3
4
 
4
5
  module Philotic
5
6
  class Subscriber
@@ -20,7 +21,7 @@ module Philotic
20
21
 
21
22
  def subscription_callback(&block)
22
23
  lambda do |delivery_info, metadata, payload|
23
- hash_payload = JSON.parse payload
24
+ hash_payload = Philotic::Serialization::Serializer.load(payload, metadata)
24
25
 
25
26
  message = Class.new(Philotic::Message).new(metadata[:headers], hash_payload)
26
27
  message.delivery_info = delivery_info
@@ -1,3 +1,3 @@
1
1
  module Philotic
2
- VERSION = '1.1.1'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -17,16 +17,18 @@ Gem::Specification.new do |gem|
17
17
  gem.licenses = ['MIT']
18
18
 
19
19
  gem.add_development_dependency 'awesome_print', '~> 1.6'
20
- gem.add_development_dependency 'codeclimate-test-reporter', '~> 0.4'
21
20
  gem.add_development_dependency 'bundler', '~> 1.10'
21
+ gem.add_development_dependency 'codeclimate-test-reporter', '~> 0.4'
22
22
  gem.add_development_dependency 'pry', '~> 0.10'
23
23
  gem.add_development_dependency 'rake', '~> 10.4'
24
24
  gem.add_development_dependency 'rspec', '~> 3.3'
25
25
  gem.add_development_dependency 'rspec-its', '~> 1.2'
26
- gem.add_development_dependency 'timecop', '~> 0.8'
27
26
  gem.add_development_dependency 'simplecov', '~> 0.10'
27
+ gem.add_development_dependency 'timecop', '~> 0.8'
28
28
 
29
29
  gem.add_dependency 'activesupport', '>= 3.2'
30
+ gem.add_dependency 'encryptor', '~> 1.3'
30
31
  gem.add_dependency 'bunny', '~> 2.2'
31
- gem.add_dependency 'json', '>= 1.8'
32
- end
32
+ gem.add_dependency 'multi_json', '~> 1.11'
33
+ gem.add_dependency 'oj', '~> 2.12'
34
+ end
@@ -1,9 +1,6 @@
1
1
  defaults: &defaults
2
2
  #connection settings
3
3
  rabbit_host: localhost
4
- # connection_failed_handler: method/proc
5
- # connection_loss_handler: method/proc
6
- timeout: 2
7
4
 
8
5
  #exchange settings
9
6
  exchange_name: philotic.headers
@@ -14,7 +11,6 @@ defaults: &defaults
14
11
  persistent: false
15
12
  immediate: false
16
13
  mandatory: false
17
- content_type: ~
18
14
  content_encoding: ~
19
15
  priority: ~
20
16
  message_id: ~
@@ -4,13 +4,37 @@ require 'philotic/connection'
4
4
 
5
5
  describe Philotic::Config do
6
6
 
7
- describe '#defaults' do
8
- end
7
+ describe '#load_file' do
8
+ let(:config_file_path) { './philotic.yml.example' }
9
+ let(:config) { YAML.load_file(config_file_path)['test'] }
10
+
11
+ subject { described_class.new(instance_double Philotic::Connection) }
9
12
 
10
- describe '#load' do
13
+ it 'properly loads config' do
14
+ subject.load_file config_file_path, 'test'
15
+ expect(config.keys).to_not be :empty?
16
+ config.keys.each do |key|
17
+ expect(subject.send(key)).to eq config[key]
18
+ end
19
+ end
11
20
  end
12
21
 
13
- describe '#load_file' do
22
+
23
+ describe '#message_return_handler' do
24
+ let(:logger) { instance_double(Logger) }
25
+ let(:basic_return) { instance_double(Bunny::ReturnInfo) }
26
+ let(:metadata) { instance_double(Bunny::Session) }
27
+ let(:payload) { {foo: 'bar'}.to_json }
28
+ let(:connection) { instance_double(Philotic::Connection, logger: logger) }
29
+
30
+ subject { described_class.new(connection) }
31
+
32
+ it 'logs a warning do' do
33
+
34
+ expect(logger).to receive(:warn)
35
+ subject.message_return_handler.call basic_return, metadata, payload
36
+ end
37
+
14
38
  end
15
39
 
16
40
  describe '#parse_rabbit_uri' do
@@ -24,20 +48,20 @@ describe Philotic::Config do
24
48
  it do
25
49
  should change {
26
50
  [
27
- config.rabbit_user,
28
- config.rabbit_password,
29
- config.rabbit_host,
30
- config.rabbit_port,
31
- config.rabbit_vhost,
51
+ config.rabbit_user,
52
+ config.rabbit_password,
53
+ config.rabbit_host,
54
+ config.rabbit_port,
55
+ config.rabbit_vhost,
32
56
  ]
33
57
  }
34
- .to [
35
- 'user',
36
- 'pass',
37
- 'host',
38
- 12345,
39
- 'vhost',
40
- ]
58
+ .to [
59
+ 'user',
60
+ 'pass',
61
+ 'host',
62
+ 12345,
63
+ 'vhost',
64
+ ]
41
65
  end
42
66
  end
43
67
  end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ module Philotic
5
+ module Serialization
6
+ describe Encryptor do
7
+ let(:encryption_key) { 'super_secret_key' }
8
+
9
+ describe '.content_type' do
10
+ specify { expect(subject.content_type).to eq 'application/json' }
11
+ end
12
+
13
+ describe '.serialization' do
14
+ specify { expect(subject.serialization).to eq :encrypted }
15
+ end
16
+
17
+ describe '.default_encryption_key' do
18
+ it 'pulls the key from Philotic.config' do
19
+ expect(Philotic.config).to receive(:encryption_key) { encryption_key }
20
+ expect(subject.default_encryption_key).to eq encryption_key
21
+ end
22
+
23
+ describe 'encryption' do
24
+ let(:metadata) { {headers: {}} }
25
+ let(:payload) {'payload'}
26
+
27
+ it 'encrypts and decrypts the payload' do
28
+ expect(Philotic.config).to receive(:encryption_key) { encryption_key }
29
+
30
+ expect(subject.load(subject.dump(payload, metadata), metadata)).to eq payload
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -204,7 +204,9 @@ describe Philotic::Message do
204
204
  end
205
205
 
206
206
  describe '.publish' do
207
- let (:connection) { double }
207
+ let (:connection) { instance_double Philotic::Connection }
208
+ let (:config) { instance_double Philotic::Config }
209
+ let (:serializations) { ['json'].to_json }
208
210
  let(:headers) do
209
211
  {
210
212
  header1: 'h1',
@@ -222,7 +224,10 @@ describe Philotic::Message do
222
224
  end
223
225
  subject { Philotic::Message }
224
226
  specify do
225
- expect_any_instance_of(Philotic::Message).to receive(:connection).and_return(connection)
227
+ expect_any_instance_of(Philotic::Message).to receive(:connection).twice.and_return(connection)
228
+ expect(connection).to receive(:config).and_return(config)
229
+ expect(config).to receive(:serializations).and_return(serializations)
230
+
226
231
  expect(connection).to receive(:publish) do |message|
227
232
  expect(message.headers).to include(headers)
228
233
  expect(message.payload).to eq payloads
@@ -22,21 +22,22 @@ describe Philotic::Publisher do
22
22
  it 'should call _publish with the right values' do
23
23
  Timecop.freeze
24
24
  expect(subject).to receive(:_publish).with(
25
- {
26
- subject: 'Hello',
27
- message: 'How are you?'
25
+ {
26
+ subject: 'Hello',
27
+ message: 'How are you?'
28
+ },
29
+ {
30
+ headers: {
31
+ philotic_firehose: true,
32
+ philotic_product: nil,
33
+ philotic_component: nil,
34
+ philotic_message_type: nil,
35
+ philotic_serializations: Philotic.config.serializations,
36
+ hue: :M,
37
+ available: true,
28
38
  },
29
- {
30
- headers: {
31
- philotic_firehose: true,
32
- philotic_product: nil,
33
- philotic_component: nil,
34
- philotic_message_type: nil,
35
- hue: :M,
36
- available: true,
37
- },
38
- timestamp: Time.now.to_i
39
- }
39
+ timestamp: Time.now.to_i
40
+ }
40
41
  )
41
42
  expect(message).to_not be_published
42
43
  subject.publish(message)
@@ -80,38 +81,39 @@ describe Philotic::Publisher do
80
81
  expect(subject.connection).to receive(:connect!)
81
82
  expect(subject.connection).to receive(:connected?).and_return(true)
82
83
  metadata = {
83
- routing_key: nil,
84
- persistent: false,
85
- immediate: false,
86
- mandatory: false,
87
- content_type: 'application/json',
88
- content_encoding: nil,
89
- priority: nil,
90
- message_id: nil,
91
- correlation_id: nil,
92
- reply_to: nil,
93
- type: nil,
94
- user_id: nil,
95
- app_id: nil,
96
- expiration: nil,
97
- headers: {
98
- philotic_firehose: true,
99
- philotic_product: nil,
100
- philotic_component: nil,
101
- philotic_message_type: nil,
102
- hue: :M,
103
- available: true,
104
- },
105
- timestamp: Time.now.to_i
84
+ routing_key: nil,
85
+ persistent: false,
86
+ immediate: false,
87
+ mandatory: false,
88
+ content_type: 'application/json',
89
+ content_encoding: nil,
90
+ priority: nil,
91
+ message_id: nil,
92
+ correlation_id: nil,
93
+ reply_to: nil,
94
+ type: nil,
95
+ user_id: nil,
96
+ app_id: nil,
97
+ expiration: nil,
98
+ headers: {
99
+ philotic_firehose: true,
100
+ philotic_product: nil,
101
+ philotic_component: nil,
102
+ philotic_message_type: nil,
103
+ philotic_serializations: Philotic.config.serializations,
104
+ hue: :M,
105
+ available: true,
106
+ },
107
+ timestamp: Time.now.to_i
106
108
  }
107
109
 
108
110
 
109
111
  expect(exchange).to receive(:publish).with(
110
- {
111
- subject: 'Hello',
112
- message: 'How are you?'
113
- }.to_json,
114
- metadata
112
+ {
113
+ subject: 'Hello',
114
+ message: 'How are you?'
115
+ }.to_json,
116
+ metadata
115
117
  )
116
118
  expect(message).to_not be_published
117
119
  subject.publish(message)
@@ -7,6 +7,23 @@ require 'philotic/subscriber'
7
7
 
8
8
  describe Philotic::Subscriber do
9
9
 
10
+ describe '#logger' do
11
+ let(:logger) { instance_double(Logger) }
12
+ let(:connection) { instance_double(Philotic::Connection, logger: logger) }
13
+ subject { described_class.new connection }
14
+ it 'is the connection logger' do
15
+ expect(subject.logger).to be subject.connection.logger
16
+ end
17
+ end
18
+
19
+ describe '#config' do
20
+ let(:config) { instance_double(Philotic::Config) }
21
+ let(:connection) { instance_double(Philotic::Connection, config: config) }
22
+ subject { described_class.new connection }
23
+ it 'is the connection logger' do
24
+ expect(subject.config).to be subject.connection.config
25
+ end
26
+ end
10
27
 
11
28
  describe '#subscription_callback' do
12
29
 
@@ -18,7 +35,7 @@ describe Philotic::Subscriber do
18
35
  end
19
36
 
20
37
  let(:delivery_info) { double }
21
- let(:metadata) { {headers: {header_1: 'foo'}} }
38
+ let(:metadata) { {headers: {header_1: 'foo', philotic_serializations: Philotic.config.serializations}} }
22
39
  let(:payload) { {message: 'body'} }
23
40
 
24
41
  it 'hydrates received messages' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philotic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Keyes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-12 00:00:00.000000000 Z
11
+ date: 2015-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -25,33 +25,33 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.6'
27
27
  - !ruby/object:Gem::Dependency
28
- name: codeclimate-test-reporter
28
+ name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.4'
33
+ version: '1.10'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.4'
40
+ version: '1.10'
41
41
  - !ruby/object:Gem::Dependency
42
- name: bundler
42
+ name: codeclimate-test-reporter
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.10'
47
+ version: '0.4'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.10'
54
+ version: '0.4'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: pry
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -109,33 +109,33 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1.2'
111
111
  - !ruby/object:Gem::Dependency
112
- name: timecop
112
+ name: simplecov
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '0.8'
117
+ version: '0.10'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '0.8'
124
+ version: '0.10'
125
125
  - !ruby/object:Gem::Dependency
126
- name: simplecov
126
+ name: timecop
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '0.10'
131
+ version: '0.8'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '0.10'
138
+ version: '0.8'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: activesupport
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +150,20 @@ dependencies:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '3.2'
153
+ - !ruby/object:Gem::Dependency
154
+ name: encryptor
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '1.3'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '1.3'
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: bunny
155
169
  requirement: !ruby/object:Gem::Requirement
@@ -165,19 +179,33 @@ dependencies:
165
179
  - !ruby/object:Gem::Version
166
180
  version: '2.2'
167
181
  - !ruby/object:Gem::Dependency
168
- name: json
182
+ name: multi_json
169
183
  requirement: !ruby/object:Gem::Requirement
170
184
  requirements:
171
- - - ">="
185
+ - - "~>"
172
186
  - !ruby/object:Gem::Version
173
- version: '1.8'
187
+ version: '1.11'
174
188
  type: :runtime
175
189
  prerelease: false
176
190
  version_requirements: !ruby/object:Gem::Requirement
177
191
  requirements:
178
- - - ">="
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '1.11'
195
+ - !ruby/object:Gem::Dependency
196
+ name: oj
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '2.12'
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
179
207
  - !ruby/object:Gem::Version
180
- version: '1.8'
208
+ version: '2.12'
181
209
  description: Lightweight, opinionated wrapper for using RabbitMQ headers exchanges
182
210
  email:
183
211
  - nkeyes@gmail.com
@@ -204,6 +232,7 @@ files:
204
232
  - examples/subscribing/named_queue.rb
205
233
  - lib/philotic.rb
206
234
  - lib/philotic/config.rb
235
+ - lib/philotic/config/defaults.rb
207
236
  - lib/philotic/connection.rb
208
237
  - lib/philotic/constants.rb
209
238
  - lib/philotic/consumer.rb
@@ -213,6 +242,10 @@ files:
213
242
  - lib/philotic/logging/message.rb
214
243
  - lib/philotic/message.rb
215
244
  - lib/philotic/publisher.rb
245
+ - lib/philotic/serialization.rb
246
+ - lib/philotic/serialization/encryptor.rb
247
+ - lib/philotic/serialization/json.rb
248
+ - lib/philotic/serialization/serializer.rb
216
249
  - lib/philotic/singleton.rb
217
250
  - lib/philotic/subscriber.rb
218
251
  - lib/philotic/tasks.rb
@@ -226,6 +259,7 @@ files:
226
259
  - spec/philotic/connection_spec.rb
227
260
  - spec/philotic/consumer_spec.rb
228
261
  - spec/philotic/logging/logger_spec.rb
262
+ - spec/philotic/logging/serialization/encryptor_spec.rb
229
263
  - spec/philotic/message_spec.rb
230
264
  - spec/philotic/publisher_spec.rb
231
265
  - spec/philotic/subscriber_spec.rb
@@ -261,6 +295,7 @@ test_files:
261
295
  - spec/philotic/connection_spec.rb
262
296
  - spec/philotic/consumer_spec.rb
263
297
  - spec/philotic/logging/logger_spec.rb
298
+ - spec/philotic/logging/serialization/encryptor_spec.rb
264
299
  - spec/philotic/message_spec.rb
265
300
  - spec/philotic/publisher_spec.rb
266
301
  - spec/philotic/subscriber_spec.rb