fluent-plugin-gcloud-pubsub-custom 1.2.0 → 1.5.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
  SHA256:
3
- metadata.gz: 76c67cd4a1690b17057f8961cc06136afe5ae3d56adfc6dc37c49190c845368b
4
- data.tar.gz: f0cf742945f94fcfc05e2364ad4881dce89c1bc6dfc723143236390ae8a90a53
3
+ metadata.gz: 374946914ce3cfc2d8118fc8f0b4f98d9b3b9a588f2a44b05f540cf39f79b416
4
+ data.tar.gz: b593cb71d7b4305d3bb230829a7a7653038dbd33f180ba0f1d1903429203dddf
5
5
  SHA512:
6
- metadata.gz: 671c29ebbef19b4155100aa6bedfdb686ee2bb79310e8c5ccb553806fde095cbd6c3ea5ff225eecfc29f6607ffc270205490873e564d3b2dfc713ce190cb26c0
7
- data.tar.gz: 158b3b2aa6f5f59e5fe0d8e8cfe6e1dbb2cf1e49541a6d0b8d9e21e15f0d4f8a536ea120bc76ef255a8b66c250ca1c92351bfa087c82eac00851a2f2b033307d
6
+ metadata.gz: a926442360078e78350dae24fef50412bbd9fbca6bbfd5a0ede662c47c9e2b5eef815ad5da6b23e5ffe76014b22138f530768add2dbdb39d0dface069f1315f9
7
+ data.tar.gz: 7aa23e9902f6720b8e755031bcba63a49c69fb43d1f6600fb69d681197dbe8b25fcdbbaba48bac844ab331254c01307da5ea4c999f7cb13ca49ff65682e53ef7
@@ -0,0 +1,25 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby-version: ['2.4', '2.5', '2.6', '2.7']
16
+
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - name: Set up Ruby
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby-version }}
23
+ bundler-cache: true
24
+ - name: Run tests
25
+ run: bundle exec rake test
@@ -1,5 +1,32 @@
1
1
  ## ChangeLog
2
2
 
3
+ ### Release 1.5.0 - 2021/01/26
4
+
5
+ - Bump up google-cloud-pubsub to v2.3.x
6
+ - Add `endpoint` parameter
7
+ - Add gzip compression/decompression feature
8
+
9
+ ### Release 1.4.0 - 2020/08/11
10
+
11
+ - Bump up google-cloud-pubsub to v0.39.x
12
+ - In preparation for updating to v1.x
13
+ - Output plugin
14
+ - Add `dest_project` parameter
15
+
16
+ ### Release 1.3.2 - 2019/08/16
17
+
18
+ - Input plugin
19
+ - Make `topic` parameter optional
20
+
21
+ ### Release 1.3.1 - 2018/06/08
22
+
23
+ - Input plugin
24
+ - Dumps raw string to logs for parsing errors
25
+
26
+ ### Release 1.3.0 - 2018/05/18
27
+
28
+ - Make attributes available
29
+
3
30
  ### Release 1.2.0 - 2018/04/24
4
31
 
5
32
  - Output plugin
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # fluent-plugin-gcloud-pubsub-custom
2
2
 
3
- [![Build Status](https://travis-ci.org/mia-0032/fluent-plugin-gcloud-pubsub-custom.svg?branch=master)](https://travis-ci.org/mia-0032/fluent-plugin-gcloud-pubsub-custom)
3
+ ![Test](https://github.com/mia-0032/fluent-plugin-gcloud-pubsub-custom/workflows/Test/badge.svg)
4
4
  [![Gem Version](https://badge.fury.io/rb/fluent-plugin-gcloud-pubsub-custom.svg)](http://badge.fury.io/rb/fluent-plugin-gcloud-pubsub-custom)
5
5
 
6
6
  This plugin is forked from https://github.com/mdoi/fluent-plugin-gcloud-pubsub
@@ -60,6 +60,7 @@ Use `gcloud_pubsub` output plugin.
60
60
  max_messages 1000
61
61
  max_total_size 9800000
62
62
  max_message_size 4000000
63
+ endpoint <Endpoint URL>
63
64
  <buffer>
64
65
  @type memory
65
66
  flush_interval 1s
@@ -81,6 +82,8 @@ Use `gcloud_pubsub` output plugin.
81
82
  - `topic` (required)
82
83
  - Set topic name to publish.
83
84
  - You can use placeholder in this param. See: https://docs.fluentd.org/v1.0/articles/buffer-section
85
+ - `dest_project` (optional, default: `nil`)
86
+ - Set your destination GCP project if you publish messages cross project.
84
87
  - `autocreate_topic` (optional, default: `false`)
85
88
  - If set to `true`, specified topic will be created when it doesn't exist.
86
89
  - `max_messages` (optional, default: `1000`)
@@ -91,6 +94,12 @@ Use `gcloud_pubsub` output plugin.
91
94
  - See https://cloud.google.com/pubsub/quotas#other_limits
92
95
  - `max_message_size` (optional, default: `4000000` = `4MB`)
93
96
  - Messages exceeding `max_message_size` are not published because Pub/Sub clients cannot receive it.
97
+ - `attribute_keys` (optional, default: `[]`)
98
+ - Publishing the set fields as attributes.
99
+ - `endpoint`(optional)
100
+ - Set Pub/Sub service endpoint. For more information, see [Service Endpoints](https://cloud.google.com/pubsub/docs/reference/service_apis_overview#service_endpoints)
101
+ - `compression` (optional, default: `nil`)
102
+ - If set to `gzip`, messages will be compressed with gzip.
94
103
 
95
104
  ### Pull messages
96
105
 
@@ -131,8 +140,8 @@ Use `gcloud_pubsub` input plugin.
131
140
  - Set your credential file path.
132
141
  - Running fluentd on GCP, you can use scope instead of specifying this.
133
142
  - You can also use environment variable such as `GCLOUD_KEYFILE`.
134
- - `topic` (required)
135
- - Set topic name to pull.
143
+ - `topic` (optional)
144
+ - Set topic name that the subscription belongs to.
136
145
  - `subscription` (required)
137
146
  - Set subscription name to pull.
138
147
  - `max_messages` (optional, default: `100`)
@@ -144,6 +153,8 @@ Use `gcloud_pubsub` input plugin.
144
153
  - Pulling messages by intervals of specified seconds.
145
154
  - `pull_threads` (optional, default: `1`)
146
155
  - Set number of threads to pull messages.
156
+ - `attribute_keys` (optional, default: `[]`)
157
+ - Specify the key of the attribute to be emitted as the field of record.
147
158
  - `parse_error_action` (optional, default: `exception`)
148
159
  - Set error type when parsing messages fails.
149
160
  - `exception`: Raise exception. Messages are not acknowledged.
@@ -154,6 +165,8 @@ Use `gcloud_pubsub` input plugin.
154
165
  - Bind IP address for HTTP RPC.
155
166
  - `rpc_port` (optional, default: `24680`)
156
167
  - Port for HTTP RPC.
168
+ - `decompression` (optional, default: `nil`)
169
+ - If set to `gzip`, messages will be decompressed with gzip.
157
170
 
158
171
  ## Contributing
159
172
 
data/Rakefile CHANGED
@@ -7,6 +7,7 @@ Rake::TestTask.new(:test) do |test|
7
7
  test.libs << 'lib' << 'test'
8
8
  test.test_files = FileList['test/plugin/test_*.rb']
9
9
  test.verbose = true
10
+ test.warning = false
10
11
  end
11
12
 
12
13
  task :default => [:build]
@@ -7,17 +7,16 @@ Gem::Specification.new do |gem|
7
7
  gem.license = "MIT"
8
8
  gem.homepage = "https://github.com/mia-0032/fluent-plugin-gcloud-pubsub-custom"
9
9
  gem.summary = gem.description
10
- gem.version = "1.2.0"
10
+ gem.version = "1.5.0"
11
11
  gem.authors = ["Yoshihiro MIYAI"]
12
12
  gem.email = "msparrow17@gmail.com"
13
- gem.has_rdoc = false
14
13
  gem.files = `git ls-files`.split("\n")
15
14
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
15
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
16
  gem.require_paths = ['lib']
18
17
 
19
18
  gem.add_runtime_dependency "fluentd", [">= 0.14.15", "< 2"]
20
- gem.add_runtime_dependency "google-cloud-pubsub", "~> 0.30.0"
19
+ gem.add_runtime_dependency "google-cloud-pubsub", "~> 2.3.1"
21
20
 
22
21
  gem.add_development_dependency "bundler"
23
22
  gem.add_development_dependency "rake"
@@ -7,19 +7,40 @@ module Fluent
7
7
  class RetryableError < Error
8
8
  end
9
9
 
10
+ class Message
11
+ attr_reader :message, :attributes
12
+ def initialize(message, attributes={})
13
+ @message = message
14
+ @attributes = attributes
15
+ end
16
+
17
+ def bytesize()
18
+ attr_size = 0
19
+ @attributes.each do |key, val|
20
+ attr_size += key.bytesize + val.bytesize
21
+ end
22
+ @message.bytesize + attr_size
23
+ end
24
+ end
25
+
10
26
  class Publisher
11
- def initialize(project, key, autocreate_topic)
12
- @pubsub = Google::Cloud::Pubsub.new project_id: project, credentials: key
27
+ def initialize(project, key, autocreate_topic, dest_project, endpoint)
28
+ @pubsub = Google::Cloud::Pubsub.new project_id: project, credentials: key, endpoint: endpoint
13
29
  @autocreate_topic = autocreate_topic
30
+ @dest_project = dest_project
14
31
  @topics = {}
15
32
  end
16
33
 
17
34
  def topic(topic_name)
18
35
  return @topics[topic_name] if @topics.has_key? topic_name
19
36
 
20
- client = @pubsub.topic topic_name
21
- if client.nil? && @autocreate_topic
22
- client = @pubsub.create_topic topic_name
37
+ if @dest_project.nil?
38
+ client = @pubsub.topic topic_name
39
+ if client.nil? && @autocreate_topic
40
+ client = @pubsub.create_topic topic_name
41
+ end
42
+ else
43
+ client = @pubsub.topic topic_name, project: @dest_project
23
44
  end
24
45
  if client.nil?
25
46
  raise Error.new "topic:#{topic_name} does not exist."
@@ -32,7 +53,7 @@ module Fluent
32
53
  def publish(topic_name, messages)
33
54
  topic(topic_name).publish do |batch|
34
55
  messages.each do |m|
35
- batch.publish m
56
+ batch.publish m.message, m.attributes
36
57
  end
37
58
  end
38
59
  rescue Google::Cloud::UnavailableError, Google::Cloud::DeadlineExceededError, Google::Cloud::InternalError => ex
@@ -43,8 +64,12 @@ module Fluent
43
64
  class Subscriber
44
65
  def initialize(project, key, topic_name, subscription_name)
45
66
  pubsub = Google::Cloud::Pubsub.new project_id: project, credentials: key
46
- topic = pubsub.topic topic_name
47
- @client = topic.subscription subscription_name
67
+ if topic_name.nil?
68
+ @client = pubsub.subscription subscription_name
69
+ else
70
+ topic = pubsub.topic topic_name
71
+ @client = topic.subscription subscription_name
72
+ end
48
73
  raise Error.new "subscription:#{subscription_name} does not exist." if @client.nil?
49
74
  end
50
75
 
@@ -1,6 +1,7 @@
1
1
  require 'json'
2
2
  require 'webrick'
3
3
 
4
+ require 'fluent/plugin/compressable'
4
5
  require 'fluent/plugin/input'
5
6
  require 'fluent/plugin/parser'
6
7
 
@@ -8,6 +9,8 @@ require 'fluent/plugin/gcloud_pubsub/client'
8
9
 
9
10
  module Fluent::Plugin
10
11
  class GcloudPubSubInput < Input
12
+ include Fluent::Plugin::Compressable
13
+
11
14
  Fluent::Plugin.register_input('gcloud_pubsub', self)
12
15
 
13
16
  helpers :compat_parameters, :parser, :thread
@@ -26,7 +29,7 @@ module Fluent::Plugin
26
29
  desc 'Set your credential file path.'
27
30
  config_param :key, :string, default: nil
28
31
  desc 'Set topic name to pull.'
29
- config_param :topic, :string
32
+ config_param :topic, :string, default: nil
30
33
  desc 'Set subscription name to pull.'
31
34
  config_param :subscription, :string
32
35
  desc 'Pulling messages by intervals of specified seconds.'
@@ -37,6 +40,8 @@ module Fluent::Plugin
37
40
  config_param :return_immediately, :bool, default: true
38
41
  desc 'Set number of threads to pull messages.'
39
42
  config_param :pull_threads, :integer, default: 1
43
+ desc 'Specify the key of the attribute to be acquired as a record'
44
+ config_param :attribute_keys, :array, default: []
40
45
  desc 'Set error type when parsing messages fails.'
41
46
  config_param :parse_error_action, :enum, default: :exception, list: [:exception, :warning]
42
47
  # for HTTP RPC
@@ -46,6 +51,8 @@ module Fluent::Plugin
46
51
  config_param :rpc_bind, :string, default: '0.0.0.0'
47
52
  desc 'Port for HTTP RPC.'
48
53
  config_param :rpc_port, :integer, default: 24680
54
+ desc 'Decompress messages'
55
+ config_param :decompression, :string, default: nil
49
56
 
50
57
  config_section :parse do
51
58
  config_set_default :@type, DEFAULT_PARSER_TYPE
@@ -112,6 +119,11 @@ module Fluent::Plugin
112
119
  end
113
120
 
114
121
  @parser = parser_create
122
+ @decompress = if @decompression == 'gzip'
123
+ method(:gzip_decompress)
124
+ else
125
+ method(:no_decompress)
126
+ end
115
127
  end
116
128
 
117
129
  def start
@@ -166,6 +178,14 @@ module Fluent::Plugin
166
178
  record.delete(@tag_key) || @tag
167
179
  end
168
180
 
181
+ def gzip_decompress(message)
182
+ decompress message
183
+ end
184
+
185
+ def no_decompress(message)
186
+ message
187
+ end
188
+
169
189
  def start_rpc
170
190
  log.info "listening http rpc server on http://#{@rpc_bind}:#{@rpc_port}/"
171
191
  @rpc_srv = WEBrick::HTTPServer.new(
@@ -219,16 +239,21 @@ module Fluent::Plugin
219
239
  end
220
240
 
221
241
  messages.each do |m|
222
- line = m.message.data.chomp
242
+ line = @decompress.call(m.message.data).chomp
243
+ attributes = m.attributes
223
244
  @parser.parse(line) do |time, record|
224
245
  if time && record
246
+ @attribute_keys.each do |key|
247
+ record[key] = attributes[key]
248
+ end
249
+
225
250
  event_streams[@extract_tag.call(record)].add(time, record)
226
251
  else
227
252
  case @parse_error_action
228
253
  when :exception
229
- raise FailedParseError.new "pattern not match: #{line.inspect}"
254
+ raise FailedParseError.new "pattern not match: #{line}"
230
255
  else
231
- log.warn 'pattern not match', record: line.inspect
256
+ log.warn 'pattern not match', record: line
232
257
  end
233
258
  end
234
259
  end
@@ -1,9 +1,11 @@
1
+ require 'fluent/plugin/compressable'
1
2
  require 'fluent/plugin/output'
2
3
  require 'fluent/plugin/gcloud_pubsub/client'
3
4
  require 'fluent/plugin_helper/inject'
4
5
 
5
6
  module Fluent::Plugin
6
7
  class GcloudPubSubOutput < Output
8
+ include Fluent::Plugin::Compressable
7
9
  include Fluent::PluginHelper::Inject
8
10
 
9
11
  Fluent::Plugin.register_output('gcloud_pubsub', self)
@@ -19,6 +21,8 @@ module Fluent::Plugin
19
21
  config_param :key, :string, :default => nil
20
22
  desc 'Set topic name to publish.'
21
23
  config_param :topic, :string
24
+ desc "Set your dest GCP project if publishing cross project"
25
+ config_param :dest_project, :string, :default => nil
22
26
  desc "If set to `true`, specified topic will be created when it doesn't exist."
23
27
  config_param :autocreate_topic, :bool, :default => false
24
28
  desc 'Publishing messages count per request to Cloud Pub/Sub.'
@@ -27,6 +31,12 @@ module Fluent::Plugin
27
31
  config_param :max_total_size, :integer, :default => 9800000 # 9.8MB
28
32
  desc 'Limit bytesize per message.'
29
33
  config_param :max_message_size, :integer, :default => 4000000 # 4MB
34
+ desc 'Publishing the set field as an attribute'
35
+ config_param :attribute_keys, :array, :default => []
36
+ desc 'Set service endpoint'
37
+ config_param :endpoint, :string, :default => nil
38
+ desc 'Compress messages'
39
+ config_param :compression, :string, :default => nil
30
40
 
31
41
  config_section :buffer do
32
42
  config_set_default :@type, DEFAULT_BUFFER_TYPE
@@ -41,16 +51,25 @@ module Fluent::Plugin
41
51
  super
42
52
  placeholder_validate!(:topic, @topic)
43
53
  @formatter = formatter_create
54
+ @compress = if @compression == 'gzip'
55
+ method(:gzip_compress)
56
+ else
57
+ method(:no_compress)
58
+ end
44
59
  end
45
60
 
46
61
  def start
47
62
  super
48
- @publisher = Fluent::GcloudPubSub::Publisher.new @project, @key, @autocreate_topic
63
+ @publisher = Fluent::GcloudPubSub::Publisher.new @project, @key, @autocreate_topic, @dest_project, @endpoint
49
64
  end
50
65
 
51
66
  def format(tag, time, record)
52
67
  record = inject_values_to_record(tag, time, record)
53
- @formatter.format(tag, time, record).to_msgpack
68
+ attributes = {}
69
+ @attribute_keys.each do |key|
70
+ attributes[key] = record.delete(key)
71
+ end
72
+ [@compress.call(@formatter.format(tag, time, record)), attributes].to_msgpack
54
73
  end
55
74
 
56
75
  def formatted_to_msgpack_binary?
@@ -67,7 +86,8 @@ module Fluent::Plugin
67
86
  messages = []
68
87
  size = 0
69
88
 
70
- chunk.msgpack_each do |msg|
89
+ chunk.msgpack_each do |msg, attr|
90
+ msg = Fluent::GcloudPubSub::Message.new(msg, attr)
71
91
  if msg.bytesize > @max_message_size
72
92
  log.warn 'Drop a message because its size exceeds `max_message_size`', size: msg.bytesize
73
93
  next
@@ -99,5 +119,13 @@ module Fluent::Plugin
99
119
  log.debug "send message topic:#{topic} length:#{messages.length} size:#{messages.map(&:bytesize).inject(:+)}"
100
120
  @publisher.publish(topic, messages)
101
121
  end
122
+
123
+ def gzip_compress(message)
124
+ compress message
125
+ end
126
+
127
+ def no_compress(message)
128
+ message
129
+ end
102
130
  end
103
131
  end
@@ -10,22 +10,14 @@ end
10
10
  require 'test/unit'
11
11
  require "test/unit/rr"
12
12
 
13
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
- $LOAD_PATH.unshift(File.dirname(__FILE__))
13
+ $LOAD_PATH.unshift(File.expand_path("../../", __FILE__))
15
14
 
16
- require 'fluent/test'
17
- unless ENV.has_key?('VERBOSE')
18
- nulllogger = Object.new
19
- nulllogger.instance_eval {|obj|
20
- def method_missing(method, *args)
21
- # pass
22
- end
23
- }
24
- $log = nulllogger
25
- end
15
+ require "fluent/test"
16
+ require "fluent/test/driver/output"
17
+ require "fluent/test/helpers"
26
18
 
27
19
  require 'fluent/plugin/in_gcloud_pubsub'
28
20
  require 'fluent/plugin/out_gcloud_pubsub'
29
21
 
30
- class Test::Unit::TestCase
31
- end
22
+ Test::Unit::TestCase.include(Fluent::Test::Helpers)
23
+ Test::Unit::TestCase.extend(Fluent::Test::Helpers)
@@ -1,7 +1,8 @@
1
1
  require 'net/http'
2
2
  require 'json'
3
3
 
4
- require_relative "../test_helper"
4
+ require_relative "../helper"
5
+ require 'fluent/plugin/compressable'
5
6
  require "fluent/test/driver/input"
6
7
 
7
8
  class GcloudPubSubInputTest < Test::Unit::TestCase
@@ -18,13 +19,16 @@ class GcloudPubSubInputTest < Test::Unit::TestCase
18
19
 
19
20
  class DummyInvalidMsgData
20
21
  def data
21
- return 'foo:bar'
22
+ 'foo:bar'
22
23
  end
23
24
  end
24
25
  class DummyInvalidMessage
25
26
  def message
26
27
  DummyInvalidMsgData.new
27
28
  end
29
+ def attributes
30
+ {"attr_1" => "a", "attr_2" => "b"}
31
+ end
28
32
  end
29
33
 
30
34
  def create_driver(conf=CONFIG)
@@ -53,6 +57,7 @@ class GcloudPubSubInputTest < Test::Unit::TestCase
53
57
  return_immediately true
54
58
  pull_interval 2
55
59
  pull_threads 3
60
+ attribute_keys attr-test
56
61
  enable_rpc true
57
62
  rpc_bind 127.0.0.1
58
63
  rpc_port 24681
@@ -67,6 +72,7 @@ class GcloudPubSubInputTest < Test::Unit::TestCase
67
72
  assert_equal(1000, d.instance.max_messages)
68
73
  assert_equal(true, d.instance.return_immediately)
69
74
  assert_equal(3, d.instance.pull_threads)
75
+ assert_equal(['attr-test'], d.instance.attribute_keys)
70
76
  assert_equal(true, d.instance.enable_rpc)
71
77
  assert_equal('127.0.0.1', d.instance.rpc_bind)
72
78
  assert_equal(24681, d.instance.rpc_port)
@@ -78,6 +84,7 @@ class GcloudPubSubInputTest < Test::Unit::TestCase
78
84
  assert_equal(100, d.instance.max_messages)
79
85
  assert_equal(true, d.instance.return_immediately)
80
86
  assert_equal(1, d.instance.pull_threads)
87
+ assert_equal([], d.instance.attribute_keys)
81
88
  assert_equal(false, d.instance.enable_rpc)
82
89
  assert_equal('0.0.0.0', d.instance.rpc_bind)
83
90
  assert_equal(24680, d.instance.rpc_port)
@@ -126,13 +133,16 @@ class GcloudPubSubInputTest < Test::Unit::TestCase
126
133
  sub_test_case 'emit' do
127
134
  class DummyMsgData
128
135
  def data
129
- return '{"foo": "bar"}'
136
+ '{"foo": "bar"}'
130
137
  end
131
138
  end
132
139
  class DummyMessage
133
140
  def message
134
141
  DummyMsgData.new
135
142
  end
143
+ def attributes
144
+ {"attr_1" => "a", "attr_2" => "b"}
145
+ end
136
146
  end
137
147
 
138
148
  class DummyMsgDataWithTagKey
@@ -140,7 +150,7 @@ class GcloudPubSubInputTest < Test::Unit::TestCase
140
150
  @tag = tag
141
151
  end
142
152
  def data
143
- return '{"foo": "bar", "test_tag_key": "' + @tag + '"}'
153
+ '{"foo": "bar", "test_tag_key": "' + @tag + '"}'
144
154
  end
145
155
  end
146
156
  class DummyMessageWithTagKey
@@ -150,6 +160,25 @@ class GcloudPubSubInputTest < Test::Unit::TestCase
150
160
  def message
151
161
  DummyMsgDataWithTagKey.new @tag
152
162
  end
163
+ def attributes
164
+ {"attr_1" => "a", "attr_2" => "b"}
165
+ end
166
+ end
167
+
168
+ class DummyMsgDataGzipped
169
+ include Fluent::Plugin::Compressable
170
+
171
+ def data
172
+ compress '{"foo": "bar"}'
173
+ end
174
+ end
175
+ class DummyMessageGzipped
176
+ def message
177
+ DummyMsgDataGzipped.new
178
+ end
179
+ def attributes
180
+ {"attr_1" => "a", "attr_2" => "b"}
181
+ end
153
182
  end
154
183
 
155
184
  setup do
@@ -235,6 +264,38 @@ class GcloudPubSubInputTest < Test::Unit::TestCase
235
264
  assert_true d.events.empty?
236
265
  end
237
266
 
267
+ test 'with attributes' do
268
+ messages = Array.new(1, DummyMessage.new)
269
+ @subscriber.pull(immediate: true, max: 100).at_least(1) { messages }
270
+ @subscriber.acknowledge(messages).at_least(1)
271
+
272
+ d = create_driver("#{CONFIG}\nattribute_keys attr_1")
273
+ d.run(expect_emits: 1, timeout: 3)
274
+ emits = d.events
275
+
276
+ assert(1 <= emits.length)
277
+ emits.each do |tag, time, record|
278
+ assert_equal("test", tag)
279
+ assert_equal({"foo" => "bar", "attr_1" => "a"}, record)
280
+ end
281
+ end
282
+
283
+ test 'with gzip decompression' do
284
+ messages = Array.new(1, DummyMessageGzipped.new)
285
+ @subscriber.pull(immediate: true, max: 100).at_least(1) { messages }
286
+ @subscriber.acknowledge(messages).at_least(1)
287
+
288
+ d = create_driver("#{CONFIG}\ndecompression gzip")
289
+ d.run(expect_emits: 1, timeout: 3)
290
+ emits = d.events
291
+
292
+ assert_equal(1, emits.length)
293
+ emits.each do |tag, time, record|
294
+ assert_equal("test", tag)
295
+ assert_equal({"foo" => "bar"}, record)
296
+ end
297
+ end
298
+
238
299
  test 'invalid messages with parse_error_action warning' do
239
300
  messages = Array.new(1, DummyInvalidMessage.new)
240
301
  @subscriber.pull(immediate: true, max: 100).at_least(1) { messages }
@@ -1,10 +1,12 @@
1
1
  # coding: utf-8
2
- require_relative "../test_helper"
2
+ require_relative "../helper"
3
+ require 'fluent/plugin/compressable'
3
4
  require "fluent/test/driver/output"
4
5
  require "fluent/test/helpers"
5
6
 
6
7
  class GcloudPubSubOutputTest < Test::Unit::TestCase
7
8
  include Fluent::Test::Helpers
9
+ include Fluent::Plugin::Compressable
8
10
 
9
11
  CONFIG = %[
10
12
  project project-test
@@ -62,6 +64,17 @@ class GcloudPubSubOutputTest < Test::Unit::TestCase
62
64
 
63
65
  assert_equal(true, d.instance.autocreate_topic)
64
66
  end
67
+
68
+ test '"dest_project" can be specified' do
69
+ d = create_driver(%[
70
+ project project-test
71
+ topic topic-test
72
+ key key-test
73
+ dest_project dest-project-test
74
+ ])
75
+
76
+ assert_equal("dest-project-test", d.instance.dest_project)
77
+ end
65
78
  end
66
79
 
67
80
  sub_test_case 'topic' do
@@ -69,6 +82,13 @@ class GcloudPubSubOutputTest < Test::Unit::TestCase
69
82
  @publisher = mock!
70
83
  @pubsub_mock = mock!
71
84
  stub(Google::Cloud::Pubsub).new { @pubsub_mock }
85
+
86
+ @old_report_on_exception = Thread.report_on_exception
87
+ Thread.report_on_exception = false
88
+ end
89
+
90
+ teardown do
91
+ Thread.report_on_exception = @old_report_on_exception
72
92
  end
73
93
 
74
94
  test '"autocreate_topic" is enabled' do
@@ -87,6 +107,21 @@ class GcloudPubSubOutputTest < Test::Unit::TestCase
87
107
  end
88
108
  end
89
109
 
110
+ test '"dest_project" is set' do
111
+ d = create_driver(%[
112
+ project project-test
113
+ topic topic-test
114
+ key key-test
115
+ dest_project dest-project-test
116
+ ])
117
+
118
+ @publisher.publish.once
119
+ @pubsub_mock.topic("topic-test", {:project=>"dest-project-test"}).once { @publisher }
120
+ d.run(default_tag: "test") do
121
+ d.feed(@time, {"a" => "b"})
122
+ end
123
+ end
124
+
90
125
  test '40x error occurred on connecting to Pub/Sub' do
91
126
  d = create_driver
92
127
 
@@ -147,6 +182,13 @@ class GcloudPubSubOutputTest < Test::Unit::TestCase
147
182
  @publisher = mock!
148
183
  @pubsub_mock = mock!.topic(anything) { @publisher }
149
184
  stub(Google::Cloud::Pubsub).new { @pubsub_mock }
185
+
186
+ @old_report_on_exception = Thread.report_on_exception
187
+ Thread.report_on_exception = false
188
+ end
189
+
190
+ teardown do
191
+ Thread.report_on_exception = @old_report_on_exception
150
192
  end
151
193
 
152
194
  test 'messages are divided into "max_messages"' do
@@ -220,7 +262,24 @@ class GcloudPubSubOutputTest < Test::Unit::TestCase
220
262
  d.run(default_tag: 'test') do
221
263
  d.feed({"foo" => "bar"})
222
264
  end
223
- assert_equal({"tag" => 'test', "foo" => "bar"}, JSON.parse(MessagePack.unpack(d.formatted.first)))
265
+ assert_equal({"tag" => 'test', "foo" => "bar"}, JSON.parse(MessagePack.unpack(d.formatted.first)[0]))
266
+ end
267
+
268
+ test 'with gzip compression' do
269
+ d = create_driver(%[
270
+ project project-test
271
+ topic topic-test
272
+ key key-test
273
+ compression gzip
274
+ ])
275
+ test_msg = {"a" => "abc"}
276
+
277
+ @publisher.publish.once
278
+ d.run(default_tag: "test") do
279
+ d.feed(test_msg)
280
+ end
281
+
282
+ assert_equal(test_msg, JSON.parse(decompress(MessagePack.unpack(d.formatted.first)[0])))
224
283
  end
225
284
  end
226
285
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-gcloud-pubsub-custom
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoshihiro MIYAI
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-24 00:00:00.000000000 Z
11
+ date: 2021-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -36,14 +36,14 @@ dependencies:
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 0.30.0
39
+ version: 2.3.1
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: 0.30.0
46
+ version: 2.3.1
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -106,8 +106,8 @@ executables: []
106
106
  extensions: []
107
107
  extra_rdoc_files: []
108
108
  files:
109
+ - ".github/workflows/test.yml"
109
110
  - ".gitignore"
110
- - ".travis.yml"
111
111
  - CHANGELOG.md
112
112
  - Gemfile
113
113
  - LICENSE
@@ -117,14 +117,14 @@ files:
117
117
  - lib/fluent/plugin/gcloud_pubsub/client.rb
118
118
  - lib/fluent/plugin/in_gcloud_pubsub.rb
119
119
  - lib/fluent/plugin/out_gcloud_pubsub.rb
120
+ - test/helper.rb
120
121
  - test/plugin/test_in_gcloud_pubsub.rb
121
122
  - test/plugin/test_out_gcloud_pubsub.rb
122
- - test/test_helper.rb
123
123
  homepage: https://github.com/mia-0032/fluent-plugin-gcloud-pubsub-custom
124
124
  licenses:
125
125
  - MIT
126
126
  metadata: {}
127
- post_install_message:
127
+ post_install_message:
128
128
  rdoc_options: []
129
129
  require_paths:
130
130
  - lib
@@ -139,12 +139,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
139
  - !ruby/object:Gem::Version
140
140
  version: '0'
141
141
  requirements: []
142
- rubyforge_project:
143
- rubygems_version: 2.7.3
144
- signing_key:
142
+ rubygems_version: 3.1.2
143
+ signing_key:
145
144
  specification_version: 4
146
145
  summary: Google Cloud Pub/Sub input/output plugin for Fluentd event collector
147
146
  test_files:
147
+ - test/helper.rb
148
148
  - test/plugin/test_in_gcloud_pubsub.rb
149
149
  - test/plugin/test_out_gcloud_pubsub.rb
150
- - test/test_helper.rb
@@ -1,25 +0,0 @@
1
- language: ruby
2
-
3
- rvm:
4
- - 2.1
5
- - 2.2
6
- - 2.3.6
7
- - 2.4.3
8
- - 2.5.0
9
- - ruby-head
10
-
11
- gemfile:
12
- - Gemfile
13
-
14
- branches:
15
- only:
16
- - master
17
-
18
- before_install: gem update bundler
19
- script: bundle exec rake test
20
-
21
- sudo: false
22
-
23
- matrix:
24
- allow_failures:
25
- - rvm: ruby-head