logstash-codec-protobuf 1.3.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +56 -0
- data/CONTRIBUTORS +12 -0
- data/DEVELOPER.md +2 -0
- data/Gemfile +11 -0
- data/LICENSE +202 -0
- data/NOTICE.TXT +4 -0
- data/README.md +184 -0
- data/docs/index.asciidoc +241 -0
- data/google-protobuf-lib-update.md +57 -0
- data/lib/logstash/codecs/protobuf.rb +804 -0
- data/logstash-codec-protobuf.gemspec +33 -0
- data/spec/codecs/pb2_spec.rb +236 -0
- data/spec/codecs/pb3_decode_spec.rb +665 -0
- data/spec/codecs/pb3_encode_spec.rb +243 -0
- data/spec/helpers/pb2/ColourTestcase.pb.rb +35 -0
- data/spec/helpers/pb2/ColourTestcase.proto +24 -0
- data/spec/helpers/pb2/event.pb.rb +19 -0
- data/spec/helpers/pb2/event.proto +12 -0
- data/spec/helpers/pb2/header/header.pb.rb +16 -0
- data/spec/helpers/pb2/header/header.proto +8 -0
- data/spec/helpers/pb2/human.pb.rb +26 -0
- data/spec/helpers/pb2/unicorn.pb.rb +19 -0
- data/spec/helpers/pb2/unicorn_event.pb.rb +24 -0
- data/spec/helpers/pb3/FantasyHorse_pb.rb +48 -0
- data/spec/helpers/pb3/PhoneDirectory_pb.rb +37 -0
- data/spec/helpers/pb3/ProbeResult_pb.rb +26 -0
- data/spec/helpers/pb3/ResultListComposerRequest_pb.rb +25 -0
- data/spec/helpers/pb3/dnsmessage_pb.rb +82 -0
- data/spec/helpers/pb3/events_pb.rb +17 -0
- data/spec/helpers/pb3/header/header.proto3 +7 -0
- data/spec/helpers/pb3/header/header_pb.rb +12 -0
- data/spec/helpers/pb3/integertest_pb.rb +18 -0
- data/spec/helpers/pb3/messageA_pb.rb +16 -0
- data/spec/helpers/pb3/messageB_pb.rb +15 -0
- data/spec/helpers/pb3/rum2_pb.rb +87 -0
- data/spec/helpers/pb3/rum3_pb.rb +87 -0
- data/spec/helpers/pb3/rum_pb.rb +87 -0
- data/spec/helpers/pb3/struct_test_pb.rb +21 -0
- data/spec/helpers/pb3/unicorn_pb.rb +31 -0
- 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
|