fluent-plugin-sendgrid-event 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: af4ed2dd208e0d2ee36d2a06ff960dd1456cc82d
4
+ data.tar.gz: db3a6d8ce63603e354f3248168f8f0214170f1c1
5
+ SHA512:
6
+ metadata.gz: b9d8efaf4a385570a44231b0a244a21d3aaa94e23637a19acc58e511e365b8d0e5e605345fb3b23a7a01d222fe7e75f3fd4db2357c6c027a039d13f3899b1f09
7
+ data.tar.gz: 89a2bb97ba30d6dec52de424e5b80dbf31bdd0a2e11ffa73539389189b48be9250c41834076803bdbec3e06b3dd094ecad909f2f3dc029ddf34020aa47dc813d
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .ruby-version
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-sendgrid-event.gemspec
4
+ gemspec
@@ -0,0 +1,47 @@
1
+ # fluent-plugin-sendgrid-event
2
+
3
+ Fluentd input plugin to receive sendgrid event.
4
+
5
+ SendGrid is a delivering email platform. Please visit below link for the specification of event webhook.
6
+ https://sendgrid.com/docs/API_Reference/Webhooks/event.html
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'fluent-plugin-sendgrid-event'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install fluent-plugin-sendgrid-event
23
+
24
+ ## Usage
25
+
26
+ The following is an example of configuration.
27
+
28
+ ```
29
+ <source>
30
+ type sendgrid_event
31
+ host 127.0.0.1
32
+ port 9191
33
+ tag sendgrid
34
+ </source>
35
+ ```
36
+
37
+ ## Contributing
38
+
39
+ 1. Fork it ( http://github.com/hiroakis/fluent-plugin-sendgrid-event/fork )
40
+ 2. Create your feature branch (git checkout -b my-new-feature)
41
+ 3. Commit your changes (git commit -am 'Add some feature')
42
+ 4. Push to the branch (git push origin my-new-feature)
43
+ 5. Create new Pull Request
44
+
45
+ ## License
46
+
47
+ MIT
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.pattern = 'test/**/test_*.rb'
7
+ test.verbose = true
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "fluent-plugin-sendgrid-event"
7
+ spec.version = "0.0.1"
8
+ spec.authors = ["Hiroaki Sano"]
9
+ spec.email = ["hiroaki.sano.9stories@gmail.com"]
10
+
11
+ spec.summary = %q{Fluent input plugin to receive sendgrid event.}
12
+ spec.homepage = "https://github.com/hiroakis/fluent-plugin-sendgrid-event"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files`.split("\n")
16
+ spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.10"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "test-unit"
23
+
24
+ spec.add_runtime_dependency "fluentd"
25
+ end
@@ -0,0 +1,83 @@
1
+ module Fluent
2
+ class SendGridEventInput < Input
3
+ Plugin.register_input('sendgrid_event', self)
4
+
5
+ config_param :tag, :string, :default => nil
6
+ config_param :host, :string, :default => "0.0.0.0"
7
+ config_param :port, :integer, :default => 9191
8
+ config_param :request_uri, :string, :default => "/"
9
+
10
+ unless method_defined?(:log)
11
+ define_method("log") { $log }
12
+ end
13
+
14
+ def initialize
15
+ super
16
+ end
17
+
18
+ def configure(conf)
19
+ log.trace "in_sendgrid_event: configure"
20
+ super
21
+
22
+ if @tag.nil?
23
+ raise Fluent::ConfigError, "sendgrid_event: 'tag' parameter is required"
24
+ end
25
+ end
26
+
27
+ def start
28
+ log.trace "in_sendgrid_event: start"
29
+ super
30
+
31
+ @thread = Thread.new(&method(:run))
32
+ end
33
+
34
+ def shutdown
35
+ log.trace "in_sendgrid_event: shutdown"
36
+ super
37
+
38
+ @server.shutdown
39
+ Thread.kill(@thread)
40
+ end
41
+
42
+ def run
43
+ log.trace "in_sendgrid_event: run"
44
+ listen = {
45
+ :BindAddress => @host,
46
+ :Port => @port
47
+ }
48
+
49
+ @server = WEBrick::HTTPServer.new(listen)
50
+ @server.mount_proc(@request_uri) do |req, res|
51
+ begin
52
+ if req.request_method == "POST" && req.body
53
+ events = JSON.parse(req.body)
54
+ events.each do |event|
55
+ emit_event(event)
56
+ end
57
+ log.trace "in_sendgrid_event: success"
58
+ res.status = 200
59
+ else
60
+ log.error "in_sendgrid_event: invalid request"
61
+ res.status = 400
62
+ end
63
+ rescue JSON::ParserError => e
64
+ log.error "in_sendgrid_event: #{e}"
65
+ res.status = 400
66
+ rescue WEBrick::HTTPStatus::LengthRequired => e
67
+ log.error "in_sendgrid_event: #{e}"
68
+ res.status = 411
69
+ rescue Exception => e
70
+ log.warn "in_sendgrid_event: Retry: Reason: #{e}"
71
+ log.warn "#{e.backtrace.join('\n')}"
72
+ res.status = 503
73
+ end
74
+ end
75
+ @server.start
76
+ end # The end of run method
77
+
78
+ def emit_event(event)
79
+ log.trace "in_sendgrid_event: emit_event"
80
+ Engine.emit("#{tag}", Engine.now, event)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ require 'fluent/test'
15
+ unless ENV.has_key?('VERBOSE')
16
+ nulllogger = Object.new
17
+ nulllogger.instance_eval {|obj|
18
+ def method_missing(method, *args)
19
+ # pass
20
+ end
21
+ }
22
+ $log = nulllogger
23
+ end
24
+
25
+ require 'fluent/plugin/in_sendgrid_event'
26
+
27
+ class Test::Unit::TestCase
28
+ end
@@ -0,0 +1,134 @@
1
+ require 'helper'
2
+
3
+ class SendGridEventTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ Fluent::Test.setup
7
+ end
8
+
9
+ CONFIG = %[
10
+ type sendgrid_event
11
+ host 127.0.0.1
12
+ port 9191
13
+ tag sendgrid.event
14
+ ]
15
+
16
+ def create_driver(conf=CONFIG, tag='test')
17
+ Fluent::Test::OutputTestDriver.new(Fluent::SendGridEventInput, tag).configure(conf)
18
+ end
19
+
20
+ def test_configuration
21
+ d = create_driver
22
+ assert_equal '127.0.0.1', d.instance.host
23
+ assert_equal 9191, d.instance.port
24
+ assert_equal 'sendgrid.event', d.instance.tag
25
+ end
26
+
27
+ def test_configuration_with_empty_tag
28
+ assert_raise(Fluent::ConfigError) {
29
+ create_driver %[
30
+ type sendgrid_event
31
+ host 127.0.0.1
32
+ port 9191
33
+ # tag sendgrid.event
34
+ ]
35
+ }
36
+ end
37
+
38
+ # This data is from https://sendgrid.com/docs/API_Reference/Webhooks/event.html
39
+ def valid_event_json
40
+ [
41
+ {
42
+ "sg_message_id":"sendgrid_internal_message_id",
43
+ "email": "john.doe@sendgrid.com",
44
+ "timestamp": 1337197600,
45
+ "smtp-id": "<4FB4041F.6080505@sendgrid.com>",
46
+ "event": "processed"
47
+ },
48
+ {
49
+ "sg_message_id":"sendgrid_internal_message_id",
50
+ "email": "john.doe@sendgrid.com",
51
+ "timestamp": 1337966815,
52
+ "category": "newuser",
53
+ "event": "click",
54
+ "url": "https://sendgrid.com"
55
+ },
56
+ {
57
+ "sg_message_id":"sendgrid_internal_message_id",
58
+ "email": "john.doe@sendgrid.com",
59
+ "timestamp": 1337969592,
60
+ "smtp-id": "<20120525181309.C1A9B40405B3@Example-Mac.local>",
61
+ "event": "group_unsubscribe",
62
+ "asm_group_id": 42
63
+ }
64
+ ].to_json
65
+ end
66
+
67
+ def invalid_event_json
68
+ valid_event_json.gsub!(":", ";")
69
+ end
70
+
71
+ def send_event(post_data)
72
+ require 'net/http'
73
+ http = Net::HTTP.new("localhost", 9191)
74
+ req = Net::HTTP::Post.new('/')
75
+ req.body = post_data
76
+ req["Content-Type"] = "application/json"
77
+ res = http.request(req)
78
+ res
79
+ end
80
+
81
+ def test_with_valid_event_json
82
+ d = create_driver %[
83
+ type sendgrid_event
84
+ host 127.0.0.1
85
+ port 9191
86
+ tag sendgrid.event
87
+ ]
88
+
89
+ d.run do
90
+ res = send_event(valid_event_json)
91
+ assert_equal("200", res.code)
92
+ end
93
+
94
+ assert_equal(3, d.emits.size)
95
+
96
+ assert_equal("sendgrid.event", d.emits[0][0])
97
+ assert_equal("sendgrid_internal_message_id", d.emits[0][2]["sg_message_id"])
98
+ assert_equal("john.doe@sendgrid.com", d.emits[0][2]["email"])
99
+ assert_equal(1337197600, d.emits[0][2]["timestamp"])
100
+ assert_equal("<4FB4041F.6080505@sendgrid.com>", d.emits[0][2]["smtp-id"])
101
+ assert_equal("processed", d.emits[0][2]["event"])
102
+
103
+ assert_equal("sendgrid.event", d.emits[1][0])
104
+ assert_equal("sendgrid_internal_message_id", d.emits[1][2]["sg_message_id"])
105
+ assert_equal("john.doe@sendgrid.com", d.emits[1][2]["email"])
106
+ assert_equal(1337966815, d.emits[1][2]["timestamp"])
107
+ assert_equal("newuser", d.emits[1][2]["category"])
108
+ assert_equal("click", d.emits[1][2]["event"])
109
+ assert_equal("https://sendgrid.com", d.emits[1][2]["url"])
110
+
111
+ assert_equal("sendgrid.event", d.emits[2][0])
112
+ assert_equal("sendgrid_internal_message_id", d.emits[2][2]["sg_message_id"])
113
+ assert_equal("john.doe@sendgrid.com", d.emits[2][2]["email"])
114
+ assert_equal(1337969592, d.emits[2][2]["timestamp"])
115
+ assert_equal("<20120525181309.C1A9B40405B3@Example-Mac.local>", d.emits[2][2]["smtp-id"])
116
+ assert_equal("group_unsubscribe", d.emits[2][2]["event"])
117
+ assert_equal(42, d.emits[2][2]["asm_group_id"])
118
+ end
119
+
120
+ def test_invalid_event_json
121
+ d = create_driver %[
122
+ type sendgrid_event
123
+ host 127.0.0.1
124
+ port 9191
125
+ tag sendgrid.event
126
+ ]
127
+
128
+ d.run do
129
+ res = send_event(invalid_event_json)
130
+ assert_equal("400", res.code)
131
+ end
132
+ assert_equal(0, d.emits.size)
133
+ end
134
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-sendgrid-event
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Hiroaki Sano
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: test-unit
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: fluentd
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - hiroaki.sano.9stories@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - README.md
79
+ - Rakefile
80
+ - fluent-plugin-sendgrid-event.gemspec
81
+ - lib/fluent/plugin/in_sendgrid_event.rb
82
+ - test/helper.rb
83
+ - test/plugin/test_in_sendgrid_event.rb
84
+ homepage: https://github.com/hiroakis/fluent-plugin-sendgrid-event
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 2.4.5
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: Fluent input plugin to receive sendgrid event.
108
+ test_files:
109
+ - test/helper.rb
110
+ - test/plugin/test_in_sendgrid_event.rb