logstash-codec-protobuf 1.3.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +56 -0
  3. data/CONTRIBUTORS +12 -0
  4. data/DEVELOPER.md +2 -0
  5. data/Gemfile +11 -0
  6. data/LICENSE +202 -0
  7. data/NOTICE.TXT +4 -0
  8. data/README.md +184 -0
  9. data/docs/index.asciidoc +241 -0
  10. data/google-protobuf-lib-update.md +57 -0
  11. data/lib/logstash/codecs/protobuf.rb +804 -0
  12. data/logstash-codec-protobuf.gemspec +33 -0
  13. data/spec/codecs/pb2_spec.rb +236 -0
  14. data/spec/codecs/pb3_decode_spec.rb +665 -0
  15. data/spec/codecs/pb3_encode_spec.rb +243 -0
  16. data/spec/helpers/pb2/ColourTestcase.pb.rb +35 -0
  17. data/spec/helpers/pb2/ColourTestcase.proto +24 -0
  18. data/spec/helpers/pb2/event.pb.rb +19 -0
  19. data/spec/helpers/pb2/event.proto +12 -0
  20. data/spec/helpers/pb2/header/header.pb.rb +16 -0
  21. data/spec/helpers/pb2/header/header.proto +8 -0
  22. data/spec/helpers/pb2/human.pb.rb +26 -0
  23. data/spec/helpers/pb2/unicorn.pb.rb +19 -0
  24. data/spec/helpers/pb2/unicorn_event.pb.rb +24 -0
  25. data/spec/helpers/pb3/FantasyHorse_pb.rb +48 -0
  26. data/spec/helpers/pb3/PhoneDirectory_pb.rb +37 -0
  27. data/spec/helpers/pb3/ProbeResult_pb.rb +26 -0
  28. data/spec/helpers/pb3/ResultListComposerRequest_pb.rb +25 -0
  29. data/spec/helpers/pb3/dnsmessage_pb.rb +82 -0
  30. data/spec/helpers/pb3/events_pb.rb +17 -0
  31. data/spec/helpers/pb3/header/header.proto3 +7 -0
  32. data/spec/helpers/pb3/header/header_pb.rb +12 -0
  33. data/spec/helpers/pb3/integertest_pb.rb +18 -0
  34. data/spec/helpers/pb3/messageA_pb.rb +16 -0
  35. data/spec/helpers/pb3/messageB_pb.rb +15 -0
  36. data/spec/helpers/pb3/rum2_pb.rb +87 -0
  37. data/spec/helpers/pb3/rum3_pb.rb +87 -0
  38. data/spec/helpers/pb3/rum_pb.rb +87 -0
  39. data/spec/helpers/pb3/struct_test_pb.rb +21 -0
  40. data/spec/helpers/pb3/unicorn_pb.rb +31 -0
  41. metadata +175 -0
@@ -0,0 +1,33 @@
1
+ Gem::Specification.new do |s|
2
+
3
+ s.name = 'logstash-codec-protobuf'
4
+ s.version = '1.3.0'
5
+ s.licenses = ['Apache License (2.0)']
6
+ s.summary = "Reads protobuf messages and converts to Logstash Events"
7
+ s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
8
+ s.authors = ["Inga Feick"]
9
+ s.email = 'inga.feick@trivago.com'
10
+ s.require_paths = ["lib"]
11
+ s.platform = "java"
12
+
13
+ # Files
14
+ s.files = Dir["lib/**/*","spec/**/*","*.gemspec","*.md","CONTRIBUTORS","Gemfile","LICENSE","NOTICE.TXT", "vendor/jar-dependencies/**/*.jar", "vendor/jar-dependencies/**/*.rb", "VERSION", "docs/**/*"]
15
+
16
+ # Tests
17
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
18
+
19
+ # Special flag to let us know this is actually a logstash plugin
20
+ s.metadata = { "logstash_plugin" => "true", "logstash_group" => "codec" }
21
+
22
+ # Gem dependencies
23
+ s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
24
+ s.add_runtime_dependency 'google-protobuf', '3.23.4' # for protobuf 3
25
+ # 3.23 is the latest version not requiring a ruby update.
26
+ # An upgrade to 3.24.3 would require ruby 2.7
27
+ # The earliest jruby supporting 2.7 ruby is 9.4 but
28
+ # there's an issue with openssl in that. Also logstash itself is using only version 9.3
29
+ # https://github.com/elastic/logstash/blob/main/.ruby-version
30
+ s.add_runtime_dependency 'ruby-protocol-buffers' # for protobuf 2
31
+ s.add_development_dependency 'logstash-devutils'
32
+
33
+ end
@@ -0,0 +1,236 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/codecs/protobuf"
4
+ require "logstash/event"
5
+
6
+ require 'protocol_buffers' # https://github.com/codekitchen/ruby-protocol-buffers, for protobuf2
7
+
8
+ require_relative '../helpers/pb2/header/header.pb.rb'
9
+ require_relative '../helpers/pb2/event.pb.rb'
10
+
11
+
12
+ describe LogStash::Codecs::Protobuf do
13
+
14
+ pb_include_path = File.expand_path(".") + "/spec/helpers"
15
+
16
+ context "#test1" do
17
+
18
+
19
+
20
+ #### Test case 1: Decode simple protobuf bytes for unicorn ####################################################################################################################
21
+ let(:plugin_unicorn) { LogStash::Codecs::Protobuf.new("class_name" => "Animal::Unicorn", "include_path" => [pb_include_path + '/pb2/unicorn.pb.rb']) }
22
+ before do
23
+ plugin_unicorn.register
24
+ end
25
+
26
+ it "should return an event from protobuf encoded data" do
27
+
28
+ data = {:colour => 'rainbow', :horn_length => 18, :last_seen => 1420081471, :has_wings => true}
29
+ unicorn = Animal::Unicorn.new(data)
30
+
31
+ plugin_unicorn.decode(unicorn.serialize_to_string) do |event|
32
+ expect(event.get("colour") ).to eq(data[:colour] )
33
+ expect(event.get("horn_length") ).to eq(data[:horn_length] )
34
+ expect(event.get("last_seen") ).to eq(data[:last_seen] )
35
+ expect(event.get("has_wings") ).to eq(data[:has_wings] )
36
+ end
37
+ end # it
38
+
39
+ end
40
+
41
+ #### Test case 2: Decode complex protobuf bytes for human #####################################################################################################################
42
+
43
+ context "#test2" do
44
+
45
+
46
+ let(:plugin_human) { LogStash::Codecs::Protobuf.new("class_name" => "Animal::Human", "include_path" => [pb_include_path + '/pb2/human.pb.rb']) }
47
+ before do
48
+ plugin_human.register
49
+ end
50
+
51
+ it "should return an event from complex nested protobuf encoded data" do
52
+
53
+ data_gm = {:first_name => 'Elisabeth', :last_name => "Oliveoil", :middle_names => ["Maria","Johanna"], :vegetarian=>true}
54
+ grandmother = Animal::Human.new(data_gm)
55
+ data_m = {:first_name => 'Annemarie', :last_name => "Smørebrød", :mother => grandmother}
56
+ mother = Animal::Human.new(data_m)
57
+ data_f = {:first_name => 'Karl', :middle_names => ["Theodor-Augustin"], :last_name => "Falkenstein"}
58
+ father = Animal::Human.new(data_f)
59
+ data = {:first_name => 'Hugo', :middle_names => ["Heinz", "Peter"], :last_name => "Smørebrød",:father => father, :mother => mother}
60
+ hugo = Animal::Human.new(data)
61
+
62
+ plugin_human.decode(hugo.serialize_to_string) do |event|
63
+ expect(event.get("first_name") ).to eq(data[:first_name] )
64
+ expect(event.get("middle_names") ).to eq(data[:middle_names] )
65
+ expect(event.get("last_name") ).to eq(data[:last_name] )
66
+ expect(event.get("[mother][first_name]") ).to eq(data_m[:first_name] )
67
+ expect(event.get("[father][first_name]") ).to eq(data_f[:first_name] )
68
+ expect(event.get("[mother][last_name]") ).to eq(data_m[:last_name] )
69
+ expect(event.get("[mother][mother][last_name]") ).to eq(data_gm[:last_name] )
70
+ expect(event.get("[mother][mother][first_name]") ).to eq(data_gm[:first_name] )
71
+ expect(event.get("[mother][mother][middle_names]") ).to eq(data_gm[:middle_names] )
72
+ expect(event.get("[mother][mother][vegetarian]") ).to eq(data_gm[:vegetarian] )
73
+ expect(event.get("[father][last_name]") ).to eq(data_f[:last_name] )
74
+ expect(event.get("[father][middle_names]") ).to eq(data_f[:middle_names] )
75
+ end
76
+ end # it
77
+ end # context
78
+
79
+
80
+ #### Test case 3: Decoder test for enums #####################################################################################################################
81
+
82
+ context "#test3" do
83
+
84
+
85
+ let(:plugin_col) { LogStash::Codecs::Protobuf.new("class_name" => "ColourProtoTest", "include_path" => [pb_include_path + '/pb2/ColourTestcase.pb.rb']) }
86
+ before do
87
+ plugin_col.register
88
+ end
89
+
90
+ it "should return an event from protobuf encoded data with enums" do
91
+
92
+ data = {:least_liked => ColourProtoTest::Colour::YELLOW, :favourite_colours => \
93
+ [ColourProtoTest::Colour::BLACK, ColourProtoTest::Colour::BLUE], :booleantest => [true, false, true]}
94
+ pb = ColourProtoTest.new(data)
95
+
96
+ plugin_col.decode(pb.serialize_to_string) do |event|
97
+ expect(event.get("least_liked") ).to eq(data[:least_liked] )
98
+ expect(event.get("favourite_colours") ).to eq(data[:favourite_colours] )
99
+ expect(event.get("booleantest") ).to eq(data[:booleantest] )
100
+ end
101
+ end # it
102
+
103
+
104
+ end # context test3
105
+
106
+
107
+ #### Test case 4: Encode simple protobuf bytes for unicorn ####################################################################################################################
108
+
109
+ context "#encodePB2-a" do
110
+ subject do
111
+ next LogStash::Codecs::Protobuf.new("class_name" => "Animal::UnicornEvent", "include_path" => [pb_include_path + '/pb2/unicorn_event.pb.rb'])
112
+ end
113
+
114
+ event = LogStash::Event.new("colour" => "pink", "horn_length" => 12, "last_seen" => 1410081999, "has_wings" => true)
115
+
116
+ it "should return protobuf encoded data from a simple event" do
117
+ subject.on_event do |event, data|
118
+ expect(data).to be_a(String)
119
+ unicorn = Animal::UnicornEvent.parse(data)
120
+
121
+ expect(unicorn.colour ).to eq(event.get("colour") )
122
+ expect(unicorn.horn_length ).to eq(event.get("horn_length") )
123
+ expect(unicorn.last_seen ).to eq(event.get("last_seen") )
124
+ expect(unicorn.has_wings ).to eq(event.get("has_wings") )
125
+
126
+ end # subject.on_event
127
+ subject.encode(event)
128
+ end # it
129
+ end # context
130
+
131
+
132
+
133
+
134
+ #### Test case 5: encode complex protobuf bytes for human #####################################################################################################################
135
+
136
+
137
+ context "#encodePB2-b" do
138
+ subject do
139
+ next LogStash::Codecs::Protobuf.new("class_name" => "Animal::Human", "include_path" => [pb_include_path + '/pb2/human.pb.rb'])
140
+ end
141
+
142
+ event = LogStash::Event.new("first_name" => "Jimmy", "middle_names" => ["Bob", "James"], "last_name" => "Doe" \
143
+ , "mother" => {"first_name" => "Jane", "middle_names" => ["Elizabeth"], "last_name" => "Doe" , "age" => 83, "vegetarian"=> false} \
144
+ , "father" => {"first_name" => "John", "last_name" => "Doe", "@email" => "character_replacement_test@nothing" })
145
+
146
+ it "should return protobuf encoded data from a complex event" do
147
+
148
+ subject.on_event do |event, data|
149
+ expect(data).to be_a(String)
150
+ jimmy = Animal::Human.parse(data)
151
+
152
+ expect(jimmy.first_name ).to eq(event.get("first_name") )
153
+ expect(jimmy.middle_names ).to eq(event.get("middle_names") )
154
+ expect(jimmy.last_name ).to eq(event.get("last_name") )
155
+ expect(jimmy.mother.first_name ).to eq(event.get("[mother][first_name]") )
156
+ expect(jimmy.father.first_name ).to eq(event.get("[father][first_name]") )
157
+ expect(jimmy.mother.middle_names ).to eq(event.get("[mother][middle_names]") )
158
+ expect(jimmy.mother.age ).to eq(event.get("[mother][age]") ) # recursion test for values
159
+ expect(jimmy.mother.vegetarian ).to eq(event.get("[mother][vegetarian]") ) # recursion test for values
160
+ expect(jimmy.father.last_name ).to eq(event.get("[father][last_name]") )
161
+ expect(jimmy.father.email ).to eq(event.get("[father][@email]") ) # recursion test for keys
162
+ expect(jimmy.mother.last_name ).to eq(event.get("[mother][last_name]") )
163
+
164
+ end # subject.on_event
165
+ subject.encode(event)
166
+ end # it
167
+ end # context
168
+
169
+
170
+
171
+
172
+
173
+ #### Test case 6: encode enums #########################################################################################################################
174
+
175
+
176
+
177
+ context "#encodePB2-c" do
178
+ subject do
179
+ next LogStash::Codecs::Protobuf.new("class_name" => "ColourProtoTest", "include_path" => [pb_include_path + '/pb2/ColourTestcase.pb.rb'])
180
+ end
181
+
182
+ require_relative '../helpers/pb2/ColourTestcase.pb.rb' # otherwise we cant use the colour enums in the next line
183
+ # ^ this import is run from the spec directory, $LOGSTASH_DIR/spec/codecs/
184
+
185
+ event = LogStash::Event.new("booleantest" => [false, false, true], "least_liked" => ColourProtoTest::Colour::YELLOW, "favourite_colours" => \
186
+ [ColourProtoTest::Colour::BLACK, ColourProtoTest::Colour::BLUE] )
187
+
188
+ it "should return protobuf encoded data from a complex event with enums" do
189
+
190
+ subject.on_event do |event, data|
191
+ expect(data).to be_a(String)
192
+
193
+ colpref = ColourProtoTest.parse(data)
194
+
195
+ expect(colpref.booleantest ).to eq(event.get("booleantest") )
196
+ expect(colpref.least_liked ).to eq(event.get("least_liked") )
197
+ expect(colpref.favourite_colours ).to eq(event.get("favourite_colours") )
198
+
199
+
200
+ end # subject.on_event
201
+ subject.encode(event)
202
+ end # it
203
+ end # context
204
+
205
+ #### Test case 7: decode a message automatically loading the dependencies ######################################################################################
206
+
207
+ context "#test4" do
208
+ let(:plugin) { LogStash::Codecs::Protobuf.new(
209
+ "class_name" => "Logging::Event",
210
+ "class_file" => [ 'event.pb.rb' ],
211
+ "protobuf_root_directory" => pb_include_path + '/pb2/')
212
+ }
213
+
214
+ before do
215
+ plugin.register
216
+ end
217
+
218
+ it "should return an event from protobuf encoded data loading the dependencies" do
219
+ header = Grpc::Header.new(:protocol => 'https')
220
+
221
+ data = {
222
+ :name => "Test",
223
+ :header => header,
224
+ }
225
+
226
+ pb = Logging::Event.new(data)
227
+
228
+ plugin.decode(pb.serialize_to_string) do |event|
229
+ expect(event.get("name") ).to eq(data[:name])
230
+ expect(event.get("header") ).to eq({"protocol"=>"https"})
231
+ end
232
+ end # it
233
+ end # context test4
234
+
235
+
236
+ end # describe