fluent-plugin-formatter-protobuf 0.1.1 → 0.4.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: ca1a8fea393af2eed56eac08ac8fe4f8122d0c1e5b5d36099580ff9e0c962c67
4
- data.tar.gz: 9670c004adcabfe98e6ae98fe46a45ebe2a55e08df52d08e169fa149af2d032b
3
+ metadata.gz: 1be52a5c380fb27bcda9d3773404892a45b787d81014934071dc272ad4b07249
4
+ data.tar.gz: ae15b5a83abe6bd2d6af1ebd41b4f47711f5f6ebda413d2b5ac799f900a140e5
5
5
  SHA512:
6
- metadata.gz: 8e8f996d0940c53666eae2cea2b7d9b47a6d57a15d6c2038c7d83accf592d89018e8c864731e5b574449cc7c5d2a9b4ea6f4153cbb9dbdd4de84cc3e5c8a57ec
7
- data.tar.gz: 6b398f92c55ad9f8f6bc92b8da8947a887fa8bc3b3bd838c7973552e8aa12e353e04fcd76e13f9d314ace7429ced3c47b877b69f4d8b6270f7aefcfc0cb72758
6
+ metadata.gz: d16537f2c02989d35d00edfed6db6c0fd4c4c5258ca59767a5682ab819863f25e7663a87c473fa490679bc3806de37237df0ec52e9bf918bdc05768ea0a0707f
7
+ data.tar.gz: 9f2d7044287ce06a11af7c91396fb1436fa695faf4537290488501fef631189662f19f27f636cc3e9f505734422a9f313aac2faf1431866aa863116322023f47
@@ -0,0 +1,48 @@
1
+ on:
2
+ push:
3
+ branches:
4
+ - main
5
+ name: release-please
6
+ jobs:
7
+ release-please:
8
+ environment: main
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: google-github-actions/release-please-action@v2
12
+ id: release
13
+ with:
14
+ token: ${{ secrets.GITHUB_TOKEN }}
15
+ release-type: ruby
16
+ version-file: "lib/fluent/plugin/version.rb"
17
+
18
+ - uses: actions/checkout@v2
19
+
20
+ - name: Set up Ruby 2.5
21
+ uses: ruby/setup-ruby@v1
22
+ with:
23
+ bundler-cache: true
24
+
25
+ - name: Publish to GPR
26
+ run: |
27
+ mkdir -p $HOME/.gem
28
+ touch $HOME/.gem/credentials
29
+ chmod 0600 $HOME/.gem/credentials
30
+ printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
31
+ gem build *.gemspec
32
+ gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
33
+ env:
34
+ GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
35
+ OWNER: ${{ github.repository_owner }}
36
+ if: ${{ steps.release.outputs.release_created }}
37
+
38
+ - name: Publish to RubyGems
39
+ run: |
40
+ mkdir -p $HOME/.gem
41
+ touch $HOME/.gem/credentials
42
+ chmod 0600 $HOME/.gem/credentials
43
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
44
+ gem build *.gemspec
45
+ gem push *.gem
46
+ env:
47
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
48
+ if: ${{ steps.release.outputs.release_created }}
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.2.0"
3
+ }
data/.rubocop.yml CHANGED
@@ -13,4 +13,8 @@ Style/FrozenStringLiteralComment:
13
13
  Metrics/MethodLength:
14
14
  Max: 100
15
15
  Exclude:
16
- - '**/*_pb.rb'
16
+ - '**/*_pb.rb'
17
+ Metrics/ClassLength:
18
+ Max: 140
19
+ Layout/LineLength:
20
+ Max: 150
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## [0.4.0](https://www.github.com/fluent-plugins-nursery/fluent-plugin-formatter-protobuf/compare/v0.3.0...v0.4.0) (2022-04-11)
4
+
5
+
6
+ ### Features
7
+
8
+ * Add configuration `ignore_unknown_fields` when decoding JSON ([734c638](https://www.github.com/fluent-plugins-nursery/fluent-plugin-formatter-protobuf/commit/734c638cd2e2405c52def5babbd61fa4d69b8c08))
9
+
10
+ ## [0.3.0](https://www.github.com/fluent-plugins-nursery/fluent-plugin-formatter-protobuf/compare/v0.2.0...v0.3.0) (2022-01-13)
11
+
12
+
13
+ ### Features
14
+
15
+ * Add new configuration - `format_field` ([797789b](https://www.github.com/fluent-plugins-nursery/fluent-plugin-formatter-protobuf/commit/797789b38d5a599c2c107979beb7edf66e384bd5))
data/README.md CHANGED
@@ -88,11 +88,14 @@ This plugin only supports Protobuf v3.
88
88
 
89
89
  ## Configuration
90
90
 
91
- |parameter| type | description | default |
92
- |---|--------------------|---------------------------------------------------------------|---------|
93
- |include_paths| array (optional) | Generated Ruby Protobuf class files path | `[]` |
94
- |class_name| string (required) | Ruby Protobuf class name. Used to encode into Protobuf binary ||
95
- |decode_json| boolean (optional) | Serializes record from canonical proto3 JSON mapping (https://developers.google.com/protocol-buffers/docs/proto3#json) into binary | `false` |
91
+ | parameter | type | description | default |
92
+ |-----------------------|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
93
+ | class_name | string (required) | Ruby Protobuf class name. Used to encode into Protobuf binary ||
94
+ | decode_json | boolean (optional) | Serializes record from canonical proto3 JSON mapping (https://developers.google.com/protocol-buffers/docs/proto3#json) into binary | `false` |
95
+ | ignore_unknown_fields | boolean (optional) | Ignore unknown fields when decoding JSON. This parameter is only used if `decode_json` is `true` | `true` |
96
+ | format_field | string (optional) | When defined, the plugin will only serialise the record in the given field rather than the whole record. This is potentially useful if you intend to use this formatter with the Kafka output plugin (https://github.com/fluent/fluent-plugin-kafka#output-plugin) for example, where your record contains a field to determine which Kafka topic to write to, or the Kafka headers to include, but you do not wish to include those data in the resulting proto3 binary. Defaults to serialising the entire record. | `''` |
97
+ | include_paths | array (required) | Generated Ruby Protobuf class files path | `[]` |
98
+ | require_method | string (optional) | Determine how to bring the generated Ruby Protobuf class files into scope. If your generated Ruby Protobuf class files are provided by a Ruby Gem, you may want to use 'require'. If you are providing the generated files as files, you may want to use 'require_relative' | `require` |
96
99
 
97
100
  ## Tips
98
101
 
data/RELEASE.md CHANGED
@@ -1,9 +1,4 @@
1
1
  # Release
2
2
 
3
- ## Instructions
4
- To release the gem to Github package manager and Ruby Gems,
5
-
6
- 1. Update `lib/fluent/plugin/version.rb`
7
- 2. Create a pull request and merge it into `main`
8
- 3. Manually creating a release on Github with a tag indicating the new version number e.g. `vMAJOR.MINOR.PATCH`
9
- 4. GitHub Actions will automatically run and publish to RubyGems and GitHub repository
3
+ This repository follow conventional commit and semantic versioning, and the release to RubyGems.org and GitHub Ruby
4
+ Repository is managed by [release-please](https://github.com/google-github-actions/release-please-action).
@@ -30,12 +30,50 @@ module Fluent
30
30
  class ProtobufFormatter < Fluent::Plugin::Formatter
31
31
  Fluent::Plugin.register_formatter('protobuf', self)
32
32
 
33
- config_param :include_paths, :array, default: [], desc: 'Generated Ruby Protobuf class files path'
34
-
35
- config_param :class_name, :string, desc: 'Ruby Protobuf class name. Used to encode into Protobuf binary'
36
-
37
- config_param :decode_json, :bool, default: false,
38
- desc: 'Serializes record from canonical proto3 JSON mapping (https://developers.google.com/protocol-buffers/docs/proto3#json) into binary' # rubocop:disable Layout/LineLength
33
+ config_param :class_name,
34
+ :string,
35
+ desc: 'Ruby Protobuf class name. Used to encode into Protobuf binary'
36
+
37
+ config_param :decode_json,
38
+ :bool,
39
+ default: false,
40
+ desc: <<~DESC
41
+ Serializes record from canonical proto3 JSON mapping (https://developers.google.com/protocol-buffers/docs/proto3#json) into binary'
42
+ DESC
43
+
44
+ config_param :ignore_unknown_fields,
45
+ :bool,
46
+ default: true,
47
+ desc: <<~DESC
48
+ Ignore unknown fields when decoding JSON. This parameter is only used if `decode_json` is `true`
49
+ DESC
50
+
51
+ config_param :format_field,
52
+ :string,
53
+ default: '',
54
+ desc: <<~DESC
55
+ When defined, the plugin will only serialise the record in the given field rather than the whole record.
56
+ This is potentially useful if you intend to use this formatter with the Kafka output plugin
57
+ (https://github.com/fluent/fluent-plugin-kafka#output-plugin) for example, where your record contains
58
+ a field to determine which Kafka topic to write to, or the Kafka headers to include, but you do not
59
+ wish to include those data in the resulting proto3 binary.
60
+
61
+ Defaults to serialising the whole record.
62
+ DESC
63
+
64
+ config_param :include_paths,
65
+ :array,
66
+ default: [],
67
+ desc: 'Generated Ruby Protobuf class files path'
68
+
69
+ config_param :require_method,
70
+ :string,
71
+ default: 'require',
72
+ desc: <<~DESC
73
+ Determine how to bring the generated Ruby Protobuf class files into scope. If your generated Ruby Protobuf class files
74
+ are provided by a Ruby Gem, you would want to use \'require\'. If you are providing the generated files as files, you
75
+ may want to use \'require_relative\''
76
+ DESC
39
77
 
40
78
  def configure(conf)
41
79
  super(conf)
@@ -55,18 +93,21 @@ module Fluent
55
93
  end
56
94
 
57
95
  def format(_tag, _time, record)
58
- protobuf_msg = @decode_json ? @protobuf_class.decode_json(Oj.dump(record)) : @protobuf_class.new(record)
96
+ format_record = @format_field == '' ? record : record[@format_field]
97
+
98
+ protobuf_msg = if @decode_json
99
+ @protobuf_class.decode_json(Oj.dump(format_record),
100
+ { ignore_unknown_fields: @ignore_unknown_fields })
101
+ else
102
+ @protobuf_class.new(format_record)
103
+ end
59
104
  @protobuf_class.encode(protobuf_msg)
60
105
  end
61
106
 
62
107
  def require_proto!(filename)
63
- if Pathname.new(filename).absolute?
64
- require filename
65
- else
66
- require_relative filename
67
- end
108
+ Kernel.method(@require_method.to_sym).call(filename)
68
109
  rescue LoadError => e
69
- raise Fluent::ConfigError, "Unable to load file '#{filename}'. Reason: #{e.inspect}"
110
+ raise Fluent::ConfigError, "Unable to load file '#{filename}'. Reason: #{e.message}"
70
111
  end
71
112
  end
72
113
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Fluent
4
4
  module Plugin
5
- VERSION = '0.1.1'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
@@ -0,0 +1,13 @@
1
+ {
2
+ "packages": {
3
+ ".": {
4
+ "releaseType": "ruby",
5
+ "draft": false,
6
+ "prerelease": false,
7
+ "bumpMinorPreMajor": true,
8
+ "bumpPatchForMinorPreMajor": true,
9
+ "changelogPath": "CHANGELOG.md",
10
+ "versioning": "default"
11
+ }
12
+ }
13
+ }
@@ -18,8 +18,8 @@ GEM
18
18
  tzinfo-data (~> 1.0)
19
19
  webrick (>= 1.4.2, < 1.8.0)
20
20
  yajl-ruby (~> 1.0)
21
- google-protobuf (3.19.1)
22
- google-protobuf (3.19.1-x86_64-linux)
21
+ google-protobuf (3.19.2)
22
+ google-protobuf (3.19.2-x86_64-linux)
23
23
  http_parser.rb (0.7.0)
24
24
  msgpack (1.4.2)
25
25
  serverengine (2.2.4)
@@ -13,6 +13,7 @@ class ProtobufFormatterTest < Test::Unit::TestCase
13
13
  # Relative to the plugin file
14
14
  VALID_INCLUDE_PATHS_RELATIVE = '../../../test/proto/addressbook_pb.rb'
15
15
 
16
+ # rubocop:disable Metrics/BlockLength
16
17
  sub_test_case 'configure' do
17
18
  test 'fail if include_paths is empty' do
18
19
  assert_raise(Fluent::ConfigError) do
@@ -34,7 +35,11 @@ class ProtobufFormatterTest < Test::Unit::TestCase
34
35
 
35
36
  test 'success if given valid relative paths in include paths' do
36
37
  assert_nothing_raised do
37
- create_driver({ class_name: 'tutorial.AddressBook', include_paths: [VALID_INCLUDE_PATHS_RELATIVE] })
38
+ create_driver({
39
+ class_name: 'tutorial.AddressBook',
40
+ include_paths: [VALID_INCLUDE_PATHS_RELATIVE],
41
+ require_method: 'require_relative'
42
+ })
38
43
  end
39
44
  end
40
45
 
@@ -44,38 +49,97 @@ class ProtobufFormatterTest < Test::Unit::TestCase
44
49
  end
45
50
  end
46
51
  end
47
-
48
- stub_ruby_hash = { people: [{ name: 'Masahiro', id: 1337,
49
- email: 'repeatedly _at_ gmail.com',
50
- last_updated: {
51
- seconds: 1_638_489_505,
52
- nanos: 318_000_000
53
- } }] }
52
+ # rubocop:enable Metrics/BlockLength
53
+
54
+ stub_ruby_hash = { 'people' => [{ 'name' => 'Masahiro', 'id' => 1337,
55
+ 'email' => 'repeatedly _at_ gmail.com',
56
+ 'last_updated' => {
57
+ 'seconds' => 1_638_489_505,
58
+ 'nanos' => 318_000_000
59
+ } }] }
60
+ # rubocop:disable Metrics/BlockLength
54
61
  sub_test_case 'format' do
55
62
  test 'encodes into Protobuf binary' do
56
63
  formatter = create_formatter({ class_name: 'tutorial.AddressBook',
57
64
  include_paths: VALID_INCLUDE_PATHS_ABSOLUTE })
58
65
 
66
+ formatted = formatter.format('some-tag', 1234, stub_ruby_hash)
67
+ address_book = Tutorial::AddressBook.new(stub_ruby_hash)
68
+ assert_equal(Tutorial::AddressBook.encode(address_book), formatted)
69
+ end
70
+
71
+ test 'encodes a particular field instead of the entire record if format_field is defined' do
72
+ formatter = create_formatter({ class_name: 'tutorial.AddressBook',
73
+ include_paths: VALID_INCLUDE_PATHS_ABSOLUTE,
74
+ format_field: 'data' })
75
+
59
76
  formatted = formatter.format('some-tag', 1234,
60
- { people: [{ name: 'Masahiro', id: 1337, email: 'repeatedly _at_ gmail.com',
61
- last_updated: { seconds: 1_638_489_505, nanos: 318_000_000 } }] })
77
+ {
78
+ 'topic' => 'some-kafka-topic',
79
+ 'headers' => {},
80
+ 'data' => stub_ruby_hash
81
+ })
62
82
  address_book = Tutorial::AddressBook.new(stub_ruby_hash)
63
83
  assert_equal(Tutorial::AddressBook.encode(address_book), formatted)
64
84
  end
65
85
 
66
- test 'encodes Protobuf JSON format into Protobuf binary if config_param decode_json is true' do
86
+ test 'encodes Protobuf JSON format into Protobuf binary if config_param decode_json is true and if incoming JSON contains unknown fields' do
67
87
  formatter = create_formatter({ class_name: 'tutorial.AddressBook',
68
88
  decode_json: true,
69
89
  include_paths: VALID_INCLUDE_PATHS_ABSOLUTE })
70
90
 
71
91
  formatted = formatter.format('some-tag', 1234,
72
- { people: [{ name: 'Masahiro', id: 1337, email: 'repeatedly _at_ gmail.com',
73
- last_updated: '2021-12-02T23:58:25.318Z' }] })
92
+ {
93
+ 'people' => [
94
+ {
95
+ 'name' => 'Masahiro',
96
+ 'id' => 1337,
97
+ 'email' => 'repeatedly _at_ gmail.com',
98
+ 'last_updated' => '2021-12-02T23:58:25.318Z',
99
+ 'some-unknown-fields' => 'this field is not specified in the .proto message'
100
+ }
101
+ ]
102
+ })
74
103
 
75
104
  address_book = Tutorial::AddressBook.new(stub_ruby_hash)
76
105
  assert_equal(Tutorial::AddressBook.encode(address_book), formatted)
77
106
  end
107
+
108
+ test 'throws exception when formatting JSON with unknown fields and ignore_unknown_fields is `false`' do
109
+ formatter = create_formatter({ class_name: 'tutorial.AddressBook',
110
+ decode_json: true,
111
+ ignore_unknown_fields: false,
112
+ include_paths: VALID_INCLUDE_PATHS_ABSOLUTE })
113
+
114
+ assert_raise(Google::Protobuf::ParseError) do
115
+ formatter.format('some-tag', 1234,
116
+ {
117
+ 'people' => [
118
+ {
119
+ 'name' => 'Masahiro',
120
+ 'id' => 1337,
121
+ 'email' => 'repeatedly _at_ gmail.com',
122
+ 'last_updated' => '2021-12-02T23:58:25.318Z',
123
+ 'some-unknown-fields' => 'this field is not specified in the .proto message'
124
+ }
125
+ ]
126
+ })
127
+ end
128
+ end
129
+
130
+ test 'encodes Ruby hash into Protobuf binary if generated files are provided by a Gem' do
131
+ formatter = create_formatter({
132
+ class_name: 'google.protobuf.Duration',
133
+ # Provided by the google-protobuf gem
134
+ include_paths: ['google/protobuf/duration_pb'],
135
+ require_method: 'require'
136
+ })
137
+ formatted = formatter.format('some-tag', 1234, { seconds: 1, nanos: 340_012 })
138
+ duration = Google::Protobuf::Duration.new({ seconds: 1, nanos: 340_012 })
139
+ assert_equal(Google::Protobuf::Duration.encode(duration), formatted)
140
+ end
78
141
  end
142
+ # rubocop:enable Metrics/BlockLength
79
143
 
80
144
  private
81
145
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-formatter-protobuf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ray Tung
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-06 00:00:00.000000000 Z
11
+ date: 2022-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -138,10 +138,12 @@ extra_rdoc_files: []
138
138
  files:
139
139
  - ".github/workflows/build-and-test.yml"
140
140
  - ".github/workflows/codeql-analysis.yml"
141
- - ".github/workflows/publish.yml"
141
+ - ".github/workflows/release-please.yml"
142
142
  - ".gitignore"
143
+ - ".release-please-manifest.json"
143
144
  - ".rubocop.yml"
144
145
  - ".ruby-version"
146
+ - CHANGELOG.md
145
147
  - Gemfile
146
148
  - LICENSE
147
149
  - README.md
@@ -152,6 +154,7 @@ files:
152
154
  - fluent-plugin-formatter-protobuf.gemspec
153
155
  - lib/fluent/plugin/formatter_protobuf.rb
154
156
  - lib/fluent/plugin/version.rb
157
+ - release-please-config.json
155
158
  - test/helper.rb
156
159
  - test/integration/Gemfile
157
160
  - test/integration/Gemfile.lock
@@ -1,96 +0,0 @@
1
- name: Publish
2
-
3
- on:
4
- push:
5
- tags:
6
- - v0.*
7
-
8
- jobs:
9
- lint:
10
- name: Lint
11
- runs-on: ubuntu-latest
12
- permissions:
13
- packages: write
14
- contents: read
15
-
16
- steps:
17
- - uses: actions/checkout@v2
18
- - name: Set up Ruby 2.5
19
- uses: ruby/setup-ruby@v1
20
- with:
21
- bundler-cache: true
22
- - name: "Unit test"
23
- run: "bundle exec rake lint:check"
24
-
25
- test:
26
- name: Unit test
27
- runs-on: ubuntu-latest
28
- permissions:
29
- packages: write
30
- contents: read
31
-
32
- steps:
33
- - uses: actions/checkout@v2
34
- - name: Set up Ruby 2.5
35
- uses: ruby/setup-ruby@v1
36
- with:
37
- bundler-cache: true
38
- - name: "Unit test"
39
- run: "bundle exec rake test:unit"
40
-
41
- publish-to-gpr:
42
- needs:
43
- - lint
44
- - test
45
- name: Build + Publish to GPR
46
- runs-on: ubuntu-latest
47
- permissions:
48
- packages: write
49
- contents: read
50
-
51
- steps:
52
- - uses: actions/checkout@v2
53
- - name: Set up Ruby 2.5
54
- uses: ruby/setup-ruby@v1
55
- with:
56
- bundler-cache: true
57
-
58
- - name: Publish to GPR
59
- run: |
60
- mkdir -p $HOME/.gem
61
- touch $HOME/.gem/credentials
62
- chmod 0600 $HOME/.gem/credentials
63
- printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
64
- gem build *.gemspec
65
- gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
66
- env:
67
- GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
68
- OWNER: ${{ github.repository_owner }}
69
-
70
- publish-to-ruby-gems:
71
- needs:
72
- - lint
73
- - test
74
- name: Build + Publish to RubyGems
75
- runs-on: ubuntu-latest
76
- permissions:
77
- packages: write
78
- contents: read
79
-
80
- steps:
81
- - uses: actions/checkout@v2
82
- - name: Set up Ruby 2.5
83
- uses: ruby/setup-ruby@v1
84
- with:
85
- bundler-cache: true
86
-
87
- - name: Publish to RubyGems
88
- run: |
89
- mkdir -p $HOME/.gem
90
- touch $HOME/.gem/credentials
91
- chmod 0600 $HOME/.gem/credentials
92
- printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
93
- gem build *.gemspec
94
- gem push *.gem
95
- env:
96
- GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"