action_mailer_kafka 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +158 -0
  3. data/.gitignore +18 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +64 -0
  6. data/Appraisals +21 -0
  7. data/CHANGELOG.md +6 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.md +23 -0
  10. data/README.md +138 -0
  11. data/Rakefile +6 -0
  12. data/action_mailer_kafka.gemspec +52 -0
  13. data/bin/console +14 -0
  14. data/bin/setup +8 -0
  15. data/example/.gitignore +21 -0
  16. data/example/Gemfile +39 -0
  17. data/example/README.rdoc +10 -0
  18. data/example/Rakefile +6 -0
  19. data/example/app/assets/images/.keep +0 -0
  20. data/example/app/assets/javascripts/application.js +16 -0
  21. data/example/app/assets/javascripts/users.js.coffee +3 -0
  22. data/example/app/assets/stylesheets/application.css +15 -0
  23. data/example/app/assets/stylesheets/scaffolds.css.scss +69 -0
  24. data/example/app/assets/stylesheets/users.css.scss +3 -0
  25. data/example/app/controllers/application_controller.rb +5 -0
  26. data/example/app/controllers/concerns/.keep +0 -0
  27. data/example/app/controllers/users_controller.rb +82 -0
  28. data/example/app/helpers/application_helper.rb +2 -0
  29. data/example/app/helpers/users_helper.rb +2 -0
  30. data/example/app/jobs/send_email_job.rb +8 -0
  31. data/example/app/mailers/.keep +0 -0
  32. data/example/app/mailers/example_mailer.rb +6 -0
  33. data/example/app/models/.keep +0 -0
  34. data/example/app/models/concerns/.keep +0 -0
  35. data/example/app/models/user.rb +2 -0
  36. data/example/app/views/example_mailer/sample_email.html.erb +398 -0
  37. data/example/app/views/example_mailer/sample_email.text.erb +2 -0
  38. data/example/app/views/layouts/application.html.erb +14 -0
  39. data/example/app/views/users/_form.html.erb +25 -0
  40. data/example/app/views/users/edit.html.erb +6 -0
  41. data/example/app/views/users/index.html.erb +27 -0
  42. data/example/app/views/users/index.json.jbuilder +4 -0
  43. data/example/app/views/users/new.html.erb +5 -0
  44. data/example/app/views/users/show.html.erb +14 -0
  45. data/example/app/views/users/show.json.jbuilder +1 -0
  46. data/example/config/application.rb +23 -0
  47. data/example/config/boot.rb +4 -0
  48. data/example/config/database.yml +11 -0
  49. data/example/config/environment.rb +5 -0
  50. data/example/config/environments/development.rb +43 -0
  51. data/example/config/environments/production.rb +105 -0
  52. data/example/config/environments/test.rb +39 -0
  53. data/example/config/initializers/backtrace_silencers.rb +7 -0
  54. data/example/config/initializers/cookies_serializer.rb +3 -0
  55. data/example/config/initializers/filter_parameter_logging.rb +4 -0
  56. data/example/config/initializers/inflections.rb +16 -0
  57. data/example/config/initializers/mime_types.rb +4 -0
  58. data/example/config/initializers/session_store.rb +3 -0
  59. data/example/config/initializers/wrap_parameters.rb +14 -0
  60. data/example/config/locales/en.yml +23 -0
  61. data/example/config/routes.rb +4 -0
  62. data/example/config/secrets.yml +22 -0
  63. data/example/config.ru +4 -0
  64. data/example/db/migrate/20141111080045_create_users.rb +10 -0
  65. data/example/db/migrate/20141115060216_create_delayed_jobs.rb +22 -0
  66. data/example/db/schema.rb +40 -0
  67. data/example/db/seeds.rb +7 -0
  68. data/example/public/404.html +67 -0
  69. data/example/public/422.html +67 -0
  70. data/example/public/500.html +66 -0
  71. data/example/public/favicon.ico +0 -0
  72. data/example/public/robots.txt +5 -0
  73. data/example/vendor/assets/javascripts/.keep +0 -0
  74. data/example/vendor/assets/stylesheets/.keep +0 -0
  75. data/gemfiles/.bundle/config +2 -0
  76. data/gemfiles/mail_2_5.gemfile +7 -0
  77. data/gemfiles/mail_2_6.gemfile +7 -0
  78. data/gemfiles/mail_2_7.gemfile +7 -0
  79. data/gemfiles/rails_4.gemfile +7 -0
  80. data/gemfiles/rails_5.gemfile +7 -0
  81. data/lib/action_mailer_kafka/delivery_method.rb +139 -0
  82. data/lib/action_mailer_kafka/error.rb +22 -0
  83. data/lib/action_mailer_kafka/railtie.rb +7 -0
  84. data/lib/action_mailer_kafka/version.rb +3 -0
  85. data/lib/action_mailer_kafka.rb +10 -0
  86. data/logo.png +0 -0
  87. metadata +328 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b7345d1145d840492978828091a1a9ebe4b3c08b
4
+ data.tar.gz: ffdb7a81954a33a0e03bad1f3e5757403af7743a
5
+ SHA512:
6
+ metadata.gz: a4db5bd4229ff0091911ac61c188f33029c4c0f67bda9b147fd6a91267b1fc435087e63b5c2e75aa875771cbeb2e65a0ee1461625583b6c7d5f5de6a3c5b8f40
7
+ data.tar.gz: dfd02e92da664c07175beb643cff16cdfa572df8c5be70eb90bfbf1cb9ce620e9ce07728df08b5ed271092f40b62c0ade9b1fc78c6cf23f178142d1b026f2076
@@ -0,0 +1,158 @@
1
+ version: 2
2
+ jobs:
3
+ rubycritic:
4
+ docker:
5
+ - image: circleci/ruby:2.3
6
+ environment:
7
+ LOG_LEVEL: DEBUG
8
+ steps:
9
+ - checkout
10
+ - restore_cache:
11
+ keys:
12
+ - v1-dependencies-{{ checksum "eh-mailer.gemspec" }}
13
+ # fallback to using the latest cache if no exact match is found
14
+ - v1-dependencies-
15
+ - run:
16
+ name: install dependencies
17
+ command: |
18
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
19
+
20
+ - save_cache:
21
+ paths:
22
+ - ./vendor/bundle
23
+ key: v1-dependencies-{{ checksum "eh-mailer.gemspec" }}
24
+ - run: bundle exec rubycritic -s 90 --no-browser -f console --suppress-ratings lib/
25
+
26
+ rubocop:
27
+ docker:
28
+ - image: circleci/ruby:2.3
29
+ environment:
30
+ LOG_LEVEL: DEBUG
31
+ steps:
32
+ - checkout
33
+ - restore_cache:
34
+ keys:
35
+ - v1-dependencies-{{ checksum "eh-mailer.gemspec" }}
36
+ # fallback to using the latest cache if no exact match is found
37
+ - v1-dependencies-
38
+ - run:
39
+ name: install dependencies
40
+ command: |
41
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
42
+
43
+ - save_cache:
44
+ paths:
45
+ - ./vendor/bundle
46
+ key: v1-dependencies-{{ checksum "eh-mailer.gemspec" }}
47
+ - run: bundle exec rubocop
48
+
49
+ unit:
50
+ docker:
51
+ - image: circleci/ruby:2.3
52
+ environment:
53
+ LOG_LEVEL: DEBUG
54
+ working_directory: ~/app
55
+ steps:
56
+ - checkout
57
+
58
+ # download and cache dependencies
59
+ - restore_cache:
60
+ keys:
61
+ - v1-dependencies-{{ checksum "eh-mailer.gemspec" }}
62
+ # fallback to using the latest cache if no exact match is found
63
+ - v1-dependencies-
64
+
65
+ - run:
66
+ name: install dependencies
67
+ command: |
68
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
69
+ bundle exec appraisal install
70
+
71
+ - save_cache:
72
+ paths:
73
+ - ./vendor/bundle
74
+ key: v1-dependencies-{{ checksum "eh-mailer.gemspec" }}
75
+
76
+ # run tests!
77
+ - run:
78
+ name: run tests
79
+ command: |
80
+ mkdir /tmp/test-results
81
+ TEST_FILES="$(circleci tests glob "spec/units/**/*_spec.rb" | \
82
+ circleci tests split --split-by=timings)"
83
+
84
+ COVERAGE=true bundle exec appraisal rspec \
85
+ --format progress \
86
+ --color \
87
+ $TEST_FILES
88
+
89
+ # collect reports
90
+ - store_test_results:
91
+ path: /tmp/test-results
92
+ - store_artifacts:
93
+ path: /tmp/test-results
94
+ destination: test-results
95
+
96
+ integration_rails_4:
97
+ docker:
98
+ - image: circleci/ruby:2.3
99
+ environment:
100
+ LOG_LEVEL: DEBUG
101
+ INTEGRATION_TEST: true
102
+ - image: wurstmeister/zookeeper
103
+ - image: wurstmeister/kafka:0.11.0.1
104
+ environment:
105
+ KAFKA_ADVERTISED_HOST_NAME: localhost
106
+ KAFKA_ADVERTISED_PORT: 9092
107
+ KAFKA_PORT: 9092
108
+ KAFKA_ZOOKEEPER_CONNECT: localhost:2181
109
+ KAFKA_DELETE_TOPIC_ENABLE: true
110
+
111
+ working_directory: ~/app
112
+ steps:
113
+ - checkout
114
+ - run:
115
+ name: install dependencies
116
+ command: |
117
+ BUNDLE_GEMFILE=./gemfiles/rails_4.gemfile bundle install --path ~/app/vendor/bundle
118
+ - run:
119
+ name: run integration tests
120
+ command: |
121
+ bundle exec rspec spec/integrations/rails_integration_spec.rb
122
+
123
+ integration_rails_5:
124
+ docker:
125
+ - image: circleci/ruby:2.3
126
+ environment:
127
+ LOG_LEVEL: DEBUG
128
+ INTEGRATION_TEST: true
129
+ - image: wurstmeister/zookeeper
130
+ - image: wurstmeister/kafka:0.11.0.1
131
+ environment:
132
+ KAFKA_ADVERTISED_HOST_NAME: localhost
133
+ KAFKA_ADVERTISED_PORT: 9092
134
+ KAFKA_PORT: 9092
135
+ KAFKA_ZOOKEEPER_CONNECT: localhost:2181
136
+ KAFKA_DELETE_TOPIC_ENABLE: true
137
+
138
+ working_directory: ~/app
139
+ steps:
140
+ - checkout
141
+ - run:
142
+ name: install dependencies
143
+ command: |
144
+ BUNDLE_GEMFILE=./gemfiles/rails_5.gemfile bundle install --path ~/app/vendor/bundle
145
+ - run:
146
+ name: run integration tests
147
+ command: |
148
+ bundle exec rspec spec/integrations/rails_integration_spec.rb
149
+
150
+ workflows:
151
+ version: 2
152
+ test:
153
+ jobs:
154
+ - unit
155
+ - integration_rails_4
156
+ - integration_rails_5
157
+ - rubycritic
158
+ - rubocop
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ tags
13
+ .byebug_history
14
+ Gemfile.lock
15
+ gemfiles/*.gemfile.lock
16
+ coverage
17
+ tmp
18
+ vendor
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,64 @@
1
+ require: rubocop-rspec
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 2.3
5
+ Exclude:
6
+ - 'vendor/**/*'
7
+ - 'Rakefile'
8
+ - 'scripts/**/*'
9
+ - 'bin/*'
10
+ - 'example/**/*'
11
+ - 'gemfiles/*'
12
+ - 'Appraisals'
13
+ - 'tmp/**/*'
14
+
15
+ Style/GuardClause:
16
+ Enabled: no
17
+
18
+ Style/Documentation:
19
+ Enabled: no
20
+
21
+ Style/HashSyntax:
22
+ Enabled: no
23
+
24
+ Style/IfUnlessModifier:
25
+ Enabled: no
26
+
27
+ RSpec/NestedGroups:
28
+ Max: 4
29
+
30
+ RSpec/ExampleLength:
31
+ Enabled: no
32
+
33
+ RSpec/MultipleExpectations:
34
+ Enabled: no
35
+
36
+ RSpec/EmptyExampleGroup:
37
+ Enabled: no
38
+
39
+ RSpec/DescribeClass:
40
+ Enabled: no
41
+
42
+ Metrics/BlockLength:
43
+ Enabled: no
44
+
45
+ Metrics/MethodLength:
46
+ Enabled: no
47
+
48
+ Metrics/AbcSize:
49
+ Enabled: no
50
+
51
+ Metrics/ClassLength:
52
+ Enabled: no
53
+
54
+ Metrics/ParameterLists:
55
+ Enabled: no
56
+
57
+ Lint/UnusedMethodArgument:
58
+ Enabled: no
59
+
60
+ Style/FrozenStringLiteralComment:
61
+ Enabled: no
62
+
63
+ Metrics/LineLength:
64
+ Max: 120
data/Appraisals ADDED
@@ -0,0 +1,21 @@
1
+ if ENV['INTEGRATION_TEST']
2
+ appraise "rails-4" do
3
+ gem "rails", "~> 4.0"
4
+ end
5
+
6
+ appraise "rails-5" do
7
+ gem "rails", "~> 5.0"
8
+ end
9
+ else
10
+ appraise "mail-2-5" do
11
+ gem "mail", "~> 2.5.2"
12
+ end
13
+
14
+ appraise "mail-2-6" do
15
+ gem "mail", "~> 2.6.0"
16
+ end
17
+
18
+ appraise "mail-2-7" do
19
+ gem "mail", "~> 2.7.0"
20
+ end
21
+ end
data/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+ Changes and additions to the library will be listed here.
3
+
4
+ ## 0.1.0
5
+ - Open source the gem.
6
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in action_mailer_kafka.gemspec
4
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2019 Luong Vo
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
data/README.md ADDED
@@ -0,0 +1,138 @@
1
+ # ActionMailerKafka
2
+ [![CircleCI](https://circleci.com/gh/luong-komorebi/action-mailer-kafka/tree/master.svg?style=svg)](https://circleci.com/gh/luong-komorebi/action-mailer-kafka/tree/master)
3
+
4
+
5
+ <p align="center">
6
+ <img src="./logo.png">
7
+ </p>
8
+
9
+ This gem is a unified interface to send emails to Kafka message queue. It takes care of the transport layer by defining a delivery method for `action-mailer`.
10
+
11
+ To see the gem in action, go to example folder and start the example rails app.
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'action_mailer_kafka'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install action_mailer_kafka
28
+
29
+ ## Usage
30
+
31
+ ### Rails
32
+
33
+ This Gem is tested with Rails version 4. and 5.
34
+
35
+ To use the gem, change action mailer's delivery method to `action_mailer_kafka`
36
+
37
+ ```ruby
38
+ # for example, in config/environments/production.rb
39
+ config.action_mailer.delivery_method = :action_mailer_kafka
40
+ ```
41
+
42
+ #### Kafa settings
43
+ The gem accepts 2 kinds of kafka setting params:
44
+
45
+ 1. Your Kafka publish proc
46
+
47
+
48
+ With this option, you should config as below:
49
+
50
+ ```ruby
51
+ config.action_mailer.action_mailer_kafka_settings = {
52
+ kafka_mail_topic: 'YourKafkaTopic',
53
+ kafka_publish_proc: proc do |message_data, default_message_topic|
54
+ YourKafkaClientInstance.publish(message_data, default_message_topic)
55
+ end
56
+ }
57
+ ```
58
+
59
+ and the data would go through your publish process.
60
+
61
+
62
+ 2. Your kafka client info
63
+
64
+ With this option, the library will generate a kafka instance for you:
65
+
66
+ ```ruby
67
+ config.action_mailer.action_mailer_kafka_settings = {
68
+ kafka_mail_topic: 'YourKafkaTopic',
69
+ kafka_client_info: {
70
+ seed_brokers: ['localhost:9090'],
71
+ logger: logger,
72
+ ssl_ca_cert: File.read('/path/to/cert')
73
+ # For more option on what to pass here, see https://github.com/zendesk/ruby-kafka/blob/master/lib/kafka/client.rb#L20
74
+ }
75
+ }
76
+ ```
77
+
78
+ Other settings params:
79
+ - `raise_on_delivery_error` : a boolean value that decides if this library should raise error.
80
+ - `logger` : pass your own logger instance.
81
+ - `fallback`: fallback method in case Kafka fails due to message being too big or other errors.
82
+ + `fallback_delivery_method`
83
+ + `fallback_delivery_method_settings`
84
+
85
+ Example of smtp as a fallback method:
86
+ ```ruby
87
+ config.action_mailer.action_mailer_kafka_settings = {
88
+ kafka_mail_topic: 'Mail.Mails.Send.Staging',
89
+ kafka_client_info: {
90
+ # .....
91
+ },
92
+ fallback: {
93
+ fallback_delivery_method: :smtp,
94
+ fallback_delivery_method_settings: {
95
+ address: 'smtp.sendgrid.net',
96
+ port: (ENV['SENDGRID_SMTP_PORT'] || 587).to_i,
97
+ authentication: :plain,
98
+ user_name: ENV['SENDGRID_USERNAME'],
99
+ password: ENV['SENDGRID_PASSWORD']
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ #### Service name
106
+
107
+ Because the email is sent to Kafka may come from a microservice in your system, an additional field to specify that would be useful. By default, if there is no service name added, the gem will ignore the service name. If provided, the serice name would become a value to the `author` field to the kafka message
108
+
109
+ ```ruby
110
+ config.action_mailer.action_mailer_kafka_settings = {
111
+ sevice_name: 'local app'
112
+ }
113
+ ```
114
+
115
+ ### Other frameworks
116
+
117
+ Not tested. But this gem is not tight coupled with Rails. It just needs action-mailer.
118
+
119
+ ### Custom headers
120
+
121
+ The gem would only accepts custom headers for emails which follow [RFC822](tools.ietf.org/html/rfc822) (which means that a custom header should begin with 'X-'). Other custom headers would not be parsed and sent to Kafka to be consumed.
122
+
123
+
124
+ ## Gem Development
125
+
126
+ ### Testing
127
+ - To run the test, do ` bundle exec rspec `.
128
+ - To run just the unit tests: ` bundle exec rspec spec/units `
129
+ - To run just the integration tests: ` bundle exec rspec spec/integrations `
130
+ - To see the coverage of your codes, run ` COVERAGE=true bundle exec rspec `. If coverage drops below 80%, CI will fail
131
+ - To see quality reporter, run ` bundle exec rubycritic -s 90 --suppress-ratings app/ `. If quality score drops below 90, CI will fail
132
+ - On CI, the test is run with multiple versions of `mail` and `rails` gems to ensure compatability. If you want to run such tests on your local machine:
133
+ - To run unit tests:
134
+ - First of all, install all dependencies with: ` bundle exec appraisal install `
135
+ - To run the unit tests, run ` bundle exec appraisal rspec spec/units `
136
+ - To run integration tests:
137
+ - First of all, install all dependencies with: ` INTEGRATION_TEST='true' bundle exec appraisal install `
138
+ - To run the unit tests, run ` bundle exec appraisal rspec spec/integrations `