logstash-codec-protobuf 1.0.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-codec-protobuf'
4
- s.version = '1.0.5'
4
+ s.version = '1.1.0'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "Reads protobuf messages and converts to Logstash Events"
7
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"
@@ -20,7 +20,8 @@ Gem::Specification.new do |s|
20
20
 
21
21
  # Gem dependencies
22
22
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
23
- s.add_runtime_dependency 'google-protobuf', '3.1'
23
+ # s.add_runtime_dependency 'google-protobuf', '3.1'
24
+ s.add_runtime_dependency 'google-protobuf', '3.5.0.pre'
24
25
  s.add_runtime_dependency 'ruby-protocol-buffers' # for protobuf 2
25
26
  s.add_development_dependency 'logstash-devutils'
26
27
  end
@@ -10,12 +10,13 @@ require 'google/protobuf' # for protobuf3
10
10
 
11
11
  describe LogStash::Codecs::Protobuf do
12
12
 
13
+ pb_include_path = "../../../spec/helpers/"
13
14
 
14
- context "#decodePB3" do
15
+ context "#test1_pb3" do
15
16
 
16
17
 
17
18
  #### Test case 1: Decode simple protobuf ####################################################################################################################
18
- let(:plugin_unicorn) { LogStash::Codecs::Protobuf.new("class_name" => "Unicorn", "include_path" => ['spec/helpers/pb3/unicorn_pb.rb'], "protobuf_version_3" => true) }
19
+ let(:plugin_unicorn) { LogStash::Codecs::Protobuf.new("class_name" => "Unicorn", "include_path" => [pb_include_path + '/pb3/unicorn_pb.rb'], "protobuf_version" => 3) }
19
20
  before do
20
21
  plugin_unicorn.register
21
22
  end
@@ -38,13 +39,15 @@ describe LogStash::Codecs::Protobuf do
38
39
  expect(event.get("is_pegasus") ).to eq(data[:is_pegasus] )
39
40
  end
40
41
  end # it
42
+ end # context
41
43
 
44
+ context "#test2_pb3" do
42
45
 
43
46
 
44
47
 
45
48
 
46
49
  #### Test case 2: decode nested protobuf ####################################################################################################################
47
- let(:plugin_unicorn) { LogStash::Codecs::Protobuf.new("class_name" => "Unicorn", "include_path" => ['spec/helpers/pb3/unicorn_pb.rb'], "protobuf_version_3" => true) }
50
+ let(:plugin_unicorn) { LogStash::Codecs::Protobuf.new("class_name" => "Unicorn", "include_path" => [pb_include_path + '/pb3/unicorn_pb.rb'], "protobuf_version" => 3) }
48
51
  before do
49
52
  plugin_unicorn.register
50
53
  end
@@ -69,19 +72,150 @@ describe LogStash::Codecs::Protobuf do
69
72
  end
70
73
  end # it
71
74
 
75
+ end # context
72
76
 
73
- end # context #decodePB3
77
+ context "#test3_pb3" do
78
+
79
+ #### Test case 3: decode ProbeResult ####################################################################################################################
80
+ let(:plugin_3) { LogStash::Codecs::Protobuf.new("class_name" => "ProbeResult", "include_path" => [pb_include_path + '/pb3/ProbeResult_pb.rb'], "protobuf_version" => 3) }
81
+ before do
82
+ plugin_3.register
83
+ end
84
+
85
+ it "should return an event from protobuf encoded data with nested classes" do
86
+
87
+
88
+ probe_result_class = Google::Protobuf::DescriptorPool.generated_pool.lookup("ProbeResult").msgclass
89
+ ping_result_class = Google::Protobuf::DescriptorPool.generated_pool.lookup("PingIPv4Result").msgclass
90
+
91
+ ping_result_data = {:status=> PingIPv4Result::Status::ERROR,
92
+ :latency => 50, :ip => "8.8.8.8", :probe_ip => "127.0.0.1", :geolocation => "New York City" }
93
+ ping_result_object = ping_result_class.new(ping_result_data)
94
+
95
+ probe_result_data = {:UUID => '12345678901233456789', :TaskPingIPv4Result => ping_result_object}
96
+ probe_result_object = probe_result_class.new(probe_result_data)
97
+ bin = probe_result_class.encode(probe_result_object)
98
+ plugin_3.decode(bin) do |event|
99
+ expect(event.get("UUID") ).to eq(probe_result_data[:UUID] )
100
+ expect(event.get("TaskPingIPv4Result")["status"] ).to eq("ERROR")
101
+ expect(event.get("TaskPingIPv4Result")["latency"] ).to eq(ping_result_data[:latency] )
102
+ expect(event.get("TaskPingIPv4Result")["ip"] ).to eq(ping_result_data[:ip] )
103
+ expect(event.get("TaskPingIPv4Result")["probe_ip"] ).to eq(ping_result_data[:probe_ip] )
104
+ expect(event.get("TaskPingIPv4Result")["geolocation"] ).to eq(ping_result_data[:geolocation] )
105
+ end
106
+ end # it
107
+ end # context
108
+
109
+ context "#test4_pb3" do
110
+
111
+ #### Test case 4: decode PBDNSMessage ####################################################################################################################
112
+ let(:plugin_4) { LogStash::Codecs::Protobuf.new("class_name" => "PBDNSMessage", "include_path" => [pb_include_path + '/pb3/dnsmessage_pb.rb'], "protobuf_version" => 3) }
113
+ before do
114
+ plugin_4.register
115
+ end
116
+
117
+ it "should return an event from protobuf encoded data with nested classes" do
118
+
119
+
120
+ pbdns_message_class = Google::Protobuf::DescriptorPool.generated_pool.lookup("PBDNSMessage").msgclass
121
+ dns_question_class = Google::Protobuf::DescriptorPool.generated_pool.lookup("PBDNSMessage.DNSQuestion").msgclass
122
+ dns_response_class = Google::Protobuf::DescriptorPool.generated_pool.lookup("PBDNSMessage.DNSResponse").msgclass
123
+ dns_rr_class = Google::Protobuf::DescriptorPool.generated_pool.lookup("PBDNSMessage.DNSResponse.DNSRR").msgclass
124
+
125
+ dns_question_data = {:qName => "Foo", :qType => 12345, :qClass => 67890 }
126
+ dns_question_object = dns_question_class.new(dns_question_data)
127
+
128
+ dns_response_data = {:rcode => 12345, :appliedPolicy => "baz", :tags => ["a","b","c"],
129
+ :queryTimeSec => 123, :queryTimeUsec => 456,
130
+ :appliedPolicyType => PBDNSMessage::PolicyType::NSIP}
131
+
132
+ dns_rr_data = [
133
+ {:name => "abc", :type => 9000, :class => 8000, :ttl => 20, :rdata => "300"},
134
+ {:name => "def", :type => 19000, :class => 18000, :ttl => 120, :rdata => "1300"}
135
+ ]
136
+
137
+ dns_response_data[:rrs] = dns_rr_data.map { | d | d = dns_rr_class.new(d) }
138
+ dns_response_object = dns_response_class.new(dns_response_data)
139
+
140
+ pbdns_message_data = {
141
+ # :UUID => '12345678901233456789', :TaskPingIPv4Result => ping_result_object
142
+ :type => PBDNSMessage::Type::DNSIncomingResponseType,
143
+ :messageId => "15",
144
+ :serverIdentity => "16",
145
+ :socketFamily => PBDNSMessage::SocketFamily::INET6,
146
+ :socketProtocol => PBDNSMessage::SocketProtocol::TCP,
147
+ :from => "17",
148
+ :to => "18",
149
+ :inBytes => 70000,
150
+ :timeSec => 80000,
151
+ :timeUsec => 90000,
152
+ :id => 20000,
153
+ :question => dns_question_object,
154
+ :response => dns_response_object,
155
+ :originalRequestorSubnet => "19",
156
+ :requestorId => "Bar",
157
+ :initialRequestId => "20",
158
+ :deviceId => "21",
159
+ }
160
+ pbdns_message_object = pbdns_message_class.new(pbdns_message_data)
161
+ bin = pbdns_message_class.encode(pbdns_message_object)
162
+ plugin_4.decode(bin) do |event|
163
+
164
+ ['messageId', 'serverIdentity','from','to','inBytes','timeUsec','timeSec','id', 'originalRequestorSubnet', 'requestorId' ,'initialRequestId','deviceIdf'].each { |n|
165
+ expect(event.get(n)).to eq(pbdns_message_data[n.to_sym] ) }
166
+
167
+ # enum test:
168
+ expect(event.get("type") ).to eq("DNSIncomingResponseType" )
169
+ expect(event.get("socketFamily") ).to eq("INET6" )
170
+ expect(event.get("socketProtocol") ).to eq("TCP" )
171
+
172
+ expect(event.get("question")["qName"] ).to eq(dns_question_data[:qName] )
173
+ expect(event.get("question")["qType"] ).to eq(dns_question_data[:qType] )
174
+ expect(event.get("question")["qClass"] ).to eq(dns_question_data[:qClass] )
175
+
176
+ ['rcode', 'appliedPolicy','tags','queryTimeSec','queryTimeUsec'].each { |n| expect(event.get('response')[n]).to eq(dns_response_data[n.to_sym] ) }
177
+ expect(event.get("response")['appliedPolicyType'] ).to eq("NSIP" )
178
+
179
+ dns_rr_data.each_with_index { | data, index |
180
+ found = event.get("response")['rrs'][index]
181
+ ['name', 'type','class','ttl','rdata'].each { |n| expect(found[n]).to eq(data[n.to_sym]) }
182
+ }
183
+
184
+ end
185
+ end # it
186
+
187
+ end # context
188
+
189
+ context "#test5_pb3" do
190
+
191
+ #### Test case 5: decode test case for github issue 17 ####################################################################################################################
192
+ let(:plugin_5) { LogStash::Codecs::Protobuf.new("class_name" => "com.foo.bar.IntegerTestMessage", "include_path" => [pb_include_path + '/pb3/integertest_pb.rb'], "protobuf_version" => 3) }
193
+ before do
194
+ plugin_5.register
195
+ end
196
+
197
+ it "should return an event from protobuf encoded data with nested classes" do
198
+ integertest_class = Google::Protobuf::DescriptorPool.generated_pool.lookup("com.foo.bar.IntegerTestMessage").msgclass
199
+ integertest_object = integertest_class.new({:response_time => 500})
200
+ bin = integertest_class.encode(integertest_object)
201
+ plugin_5.decode(bin) do |event|
202
+ expect(event.get("response_time") ).to eq(500)
203
+ end
204
+ end # it
205
+
206
+
207
+ end # context
74
208
 
75
209
 
76
210
  context "#encodePB3-a" do
77
211
 
78
212
  #### Test case 3: encode simple protobuf ####################################################################################################################
79
213
 
80
- definitions_file = 'spec/helpers/pb3/unicorn_pb.rb'
81
- require definitions_file
214
+
215
+ require_relative '../helpers/pb3/unicorn_pb.rb'
82
216
 
83
217
  subject do
84
- next LogStash::Codecs::Protobuf.new("class_name" => "Unicorn", "include_path" => [definitions_file], "protobuf_version_3" => true)
218
+ next LogStash::Codecs::Protobuf.new("class_name" => "Unicorn", "include_path" => [pb_include_path + '/pb3/unicorn_pb.rb'], "protobuf_version" => 3)
85
219
  end
86
220
 
87
221
  event3 = LogStash::Event.new("name" => "Pinkie", "age" => 18, "is_pegasus" => false, "favourite_numbers" => [1,2,3], "fur_colour" => Colour::PINK, "favourite_colours" => [1,5] )
@@ -109,11 +243,10 @@ describe LogStash::Codecs::Protobuf do
109
243
 
110
244
  #### Test case 4: encode nested protobuf ####################################################################################################################
111
245
 
112
- definitions_file = 'spec/helpers/pb3/unicorn_pb.rb'
113
- require definitions_file
246
+ require_relative '../helpers/pb3/unicorn_pb.rb'
114
247
 
115
248
  subject do
116
- next LogStash::Codecs::Protobuf.new("class_name" => "Unicorn", "include_path" => [definitions_file], "protobuf_version_3" => true)
249
+ next LogStash::Codecs::Protobuf.new("class_name" => "Unicorn", "include_path" => [pb_include_path + '/pb3/unicorn_pb.rb'], "protobuf_version" => 3)
117
250
  end
118
251
 
119
252
  event4 = LogStash::Event.new("name" => "Horst", "age" => 23, "is_pegasus" => true, "mother" => \
@@ -10,13 +10,15 @@ require 'protocol_buffers' # https://github.com/codekitchen/ruby-protocol-buffer
10
10
 
11
11
  describe LogStash::Codecs::Protobuf do
12
12
 
13
+ pb_include_path = "../../../spec/helpers/"
13
14
 
14
15
 
15
- context "#decodePB2" do
16
+ context "#test1" do
16
17
 
18
+
17
19
 
18
20
  #### Test case 1: Decode simple protobuf bytes for unicorn ####################################################################################################################
19
- let(:plugin_unicorn) { LogStash::Codecs::Protobuf.new("class_name" => "Animal::Unicorn", "include_path" => ['spec/helpers/pb2/unicorn.pb.rb']) }
21
+ let(:plugin_unicorn) { LogStash::Codecs::Protobuf.new("class_name" => "Animal::Unicorn", "include_path" => [pb_include_path + '/pb2/unicorn.pb.rb']) }
20
22
  before do
21
23
  plugin_unicorn.register
22
24
  end
@@ -34,14 +36,14 @@ describe LogStash::Codecs::Protobuf do
34
36
  end
35
37
  end # it
36
38
 
37
-
39
+ end
38
40
 
39
41
  #### Test case 2: Decode complex protobuf bytes for human #####################################################################################################################
40
42
 
41
-
43
+ context "#test2" do
42
44
 
43
45
 
44
- let(:plugin_human) { LogStash::Codecs::Protobuf.new("class_name" => "Animal::Human", "include_path" => ['spec/helpers/pb2/human.pb.rb']) }
46
+ let(:plugin_human) { LogStash::Codecs::Protobuf.new("class_name" => "Animal::Human", "include_path" => [pb_include_path + '/pb2/human.pb.rb']) }
45
47
  before do
46
48
  plugin_human.register
47
49
  end
@@ -72,18 +74,15 @@ describe LogStash::Codecs::Protobuf do
72
74
  expect(event.get("[father][middle_names]") ).to eq(data_f[:middle_names] )
73
75
  end
74
76
  end # it
75
-
76
-
77
-
78
-
77
+ end # context
79
78
 
80
79
 
81
80
  #### Test case 3: Decoder test for enums #####################################################################################################################
82
81
 
83
-
82
+ context "#test3" do
84
83
 
85
84
 
86
- let(:plugin_col) { LogStash::Codecs::Protobuf.new("class_name" => "ColourProtoTest", "include_path" => ['spec/helpers/pb2/ColourTestcase.pb.rb']) }
85
+ let(:plugin_col) { LogStash::Codecs::Protobuf.new("class_name" => "ColourProtoTest", "include_path" => [pb_include_path + '/pb2/ColourTestcase.pb.rb']) }
87
86
  before do
88
87
  plugin_col.register
89
88
  end
@@ -102,7 +101,7 @@ describe LogStash::Codecs::Protobuf do
102
101
  end # it
103
102
 
104
103
 
105
- end # context decodePB2
104
+ end # context test3
106
105
 
107
106
 
108
107
 
@@ -112,7 +111,7 @@ describe LogStash::Codecs::Protobuf do
112
111
 
113
112
  context "#encodePB2-a" do
114
113
  subject do
115
- next LogStash::Codecs::Protobuf.new("class_name" => "Animal::UnicornEvent", "include_path" => ['spec/helpers/pb2/unicorn_event.pb.rb'])
114
+ next LogStash::Codecs::Protobuf.new("class_name" => "Animal::UnicornEvent", "include_path" => [pb_include_path + '/pb2/unicorn_event.pb.rb'])
116
115
  end
117
116
 
118
117
  event = LogStash::Event.new("colour" => "pink", "horn_length" => 12, "last_seen" => 1410081999, "has_wings" => true)
@@ -140,7 +139,7 @@ describe LogStash::Codecs::Protobuf do
140
139
 
141
140
  context "#encodePB2-b" do
142
141
  subject do
143
- next LogStash::Codecs::Protobuf.new("class_name" => "Animal::Human", "include_path" => ['spec/helpers/pb2/human.pb.rb'])
142
+ next LogStash::Codecs::Protobuf.new("class_name" => "Animal::Human", "include_path" => [pb_include_path + '/pb2/human.pb.rb'])
144
143
  end
145
144
 
146
145
  event = LogStash::Event.new("first_name" => "Jimmy", "middle_names" => ["Bob", "James"], "last_name" => "Doe" \
@@ -180,10 +179,12 @@ describe LogStash::Codecs::Protobuf do
180
179
 
181
180
  context "#encodePB2-c" do
182
181
  subject do
183
- next LogStash::Codecs::Protobuf.new("class_name" => "ColourProtoTest", "include_path" => ['spec/helpers/pb2/ColourTestcase.pb.rb'])
182
+ next LogStash::Codecs::Protobuf.new("class_name" => "ColourProtoTest", "include_path" => [pb_include_path + '/pb2/ColourTestcase.pb.rb'])
184
183
  end
185
184
 
186
- require 'spec/helpers/pb2/ColourTestcase.pb.rb' # otherwise we cant use the colour enums in the next line
185
+ require_relative '../helpers/pb2/ColourTestcase.pb.rb' # otherwise we cant use the colour enums in the next line
186
+ # ^ this import is run from the spec directory, $LOGSTASH_DIR/spec/codecs/
187
+
187
188
  event = LogStash::Event.new("booleantest" => [false, false, true], "least_liked" => ColourProtoTest::Colour::YELLOW, "favourite_colours" => \
188
189
  [ColourProtoTest::Colour::BLACK, ColourProtoTest::Colour::BLUE] )
189
190
 
@@ -0,0 +1,26 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: results.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_message "ProbeResult" do
8
+ optional :UUID, :string, 1
9
+ optional :TaskPingIPv4Result, :message, 2, "PingIPv4Result"
10
+ end
11
+ add_message "PingIPv4Result" do
12
+ optional :status, :enum, 2, "PingIPv4Result.Status"
13
+ optional :latency, :double, 3
14
+ optional :ip, :string, 4
15
+ optional :probe_ip, :string, 5
16
+ optional :geolocation, :string, 6
17
+ end
18
+ add_enum "PingIPv4Result.Status" do
19
+ value :OK, 0
20
+ value :ERROR, 1
21
+ end
22
+ end
23
+
24
+ ProbeResult = Google::Protobuf::DescriptorPool.generated_pool.lookup("ProbeResult").msgclass
25
+ PingIPv4Result = Google::Protobuf::DescriptorPool.generated_pool.lookup("PingIPv4Result").msgclass
26
+ PingIPv4Result::Status = Google::Protobuf::DescriptorPool.generated_pool.lookup("PingIPv4Result.Status").enummodule
@@ -0,0 +1,82 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: dnsmessage.proto3
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_message "PBDNSMessage" do
8
+ optional :type, :enum, 1, "PBDNSMessage.Type"
9
+ optional :messageId, :bytes, 2
10
+ optional :serverIdentity, :bytes, 3
11
+ optional :socketFamily, :enum, 4, "PBDNSMessage.SocketFamily"
12
+ optional :socketProtocol, :enum, 5, "PBDNSMessage.SocketProtocol"
13
+ optional :from, :bytes, 6
14
+ optional :to, :bytes, 7
15
+ optional :inBytes, :uint64, 8
16
+ optional :timeSec, :uint32, 9
17
+ optional :timeUsec, :uint32, 10
18
+ optional :id, :uint32, 11
19
+ optional :question, :message, 12, "PBDNSMessage.DNSQuestion"
20
+ optional :response, :message, 13, "PBDNSMessage.DNSResponse"
21
+ optional :originalRequestorSubnet, :bytes, 14
22
+ optional :requestorId, :string, 15
23
+ optional :initialRequestId, :bytes, 16
24
+ optional :deviceId, :bytes, 17
25
+ end
26
+ add_message "PBDNSMessage.DNSQuestion" do
27
+ optional :qName, :string, 1
28
+ optional :qType, :uint32, 2
29
+ optional :qClass, :uint32, 3
30
+ end
31
+ add_message "PBDNSMessage.DNSResponse" do
32
+ optional :rcode, :uint32, 1
33
+ repeated :rrs, :message, 2, "PBDNSMessage.DNSResponse.DNSRR"
34
+ optional :appliedPolicy, :string, 3
35
+ repeated :tags, :string, 4
36
+ optional :queryTimeSec, :uint32, 5
37
+ optional :queryTimeUsec, :uint32, 6
38
+ optional :appliedPolicyType, :enum, 7, "PBDNSMessage.PolicyType"
39
+ end
40
+ add_message "PBDNSMessage.DNSResponse.DNSRR" do
41
+ optional :name, :string, 1
42
+ optional :type, :uint32, 2
43
+ optional :class, :uint32, 3
44
+ optional :ttl, :uint32, 4
45
+ optional :rdata, :bytes, 5
46
+ end
47
+ add_enum "PBDNSMessage.Type" do
48
+ value :Dummy0, 0
49
+ value :DNSQueryType, 1
50
+ value :DNSResponseType, 2
51
+ value :DNSOutgoingQueryType, 3
52
+ value :DNSIncomingResponseType, 4
53
+ end
54
+ add_enum "PBDNSMessage.SocketFamily" do
55
+ value :Dummy1, 0
56
+ value :INET, 1
57
+ value :INET6, 2
58
+ end
59
+ add_enum "PBDNSMessage.SocketProtocol" do
60
+ value :Dummy2, 0
61
+ value :UDP, 1
62
+ value :TCP, 2
63
+ end
64
+ add_enum "PBDNSMessage.PolicyType" do
65
+ value :Dummy3, 0
66
+ value :UNKNOWN, 1
67
+ value :QNAME, 2
68
+ value :CLIENTIP, 3
69
+ value :RESPONSEIP, 4
70
+ value :NSDNAME, 5
71
+ value :NSIP, 6
72
+ end
73
+ end
74
+
75
+ PBDNSMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("PBDNSMessage").msgclass
76
+ PBDNSMessage::DNSQuestion = Google::Protobuf::DescriptorPool.generated_pool.lookup("PBDNSMessage.DNSQuestion").msgclass
77
+ PBDNSMessage::DNSResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("PBDNSMessage.DNSResponse").msgclass
78
+ PBDNSMessage::DNSResponse::DNSRR = Google::Protobuf::DescriptorPool.generated_pool.lookup("PBDNSMessage.DNSResponse.DNSRR").msgclass
79
+ PBDNSMessage::Type = Google::Protobuf::DescriptorPool.generated_pool.lookup("PBDNSMessage.Type").enummodule
80
+ PBDNSMessage::SocketFamily = Google::Protobuf::DescriptorPool.generated_pool.lookup("PBDNSMessage.SocketFamily").enummodule
81
+ PBDNSMessage::SocketProtocol = Google::Protobuf::DescriptorPool.generated_pool.lookup("PBDNSMessage.SocketProtocol").enummodule
82
+ PBDNSMessage::PolicyType = Google::Protobuf::DescriptorPool.generated_pool.lookup("PBDNSMessage.PolicyType").enummodule
@@ -0,0 +1,20 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: TestMessage.proto3
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_message "com.foo.bar.IntegerTestMessage" do
8
+ optional :response_time, :int64, 1
9
+ end
10
+ end
11
+
12
+ module Com
13
+ module Bla
14
+ module Bla
15
+ module Bla
16
+ TestMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("com.foo.bar.IntegerTestMessage").msgclass
17
+ end
18
+ end
19
+ end
20
+ end