fluent-plugin-flume 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,72 +1,38 @@
1
- /**
2
- * Licensed to Cloudera, Inc. under one
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
3
  * or more contributor license agreements. See the NOTICE file
4
4
  * distributed with this work for additional information
5
- * regarding copyright ownership. Cloudera, Inc. licenses this file
5
+ * regarding copyright ownership. The ASF licenses this file
6
6
  * to you under the Apache License, Version 2.0 (the
7
7
  * "License"); you may not use this file except in compliance
8
8
  * with the License. You may obtain a copy of the License at
9
9
  *
10
- * http://www.apache.org/licenses/LICENSE-2.0
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
11
  *
12
- * Unless required by applicable law or agreed to in writing, software
13
- * distributed under the License is distributed on an "AS IS" BASIS,
14
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- * See the License for the specific language governing permissions and
16
- * limitations under the License.
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
17
18
  */
18
- # flume.thrift
19
- #
20
- # This thrift interface and service defines a network transport mechanism to move events
21
- # from one process/machine to another. At the moment this mirrors the fields of an event
22
- # as defined in c.c.f.core.Event.java's code .
23
- #
24
- # This may change more fields are likely to be added, and the actual format is subject to change.
25
19
 
26
- # The server has two rpc methods
27
- # -- append: which sends an event to the server,
28
- # -- close: shuts down this client's connection
29
- #
30
- # Currently append is oneway, requiring the thrift server to do flow control.
31
-
32
- namespace java com.cloudera.flume.handlers.thrift
33
-
34
- typedef i64 Timestamp
35
-
36
- enum Priority {
37
- FATAL = 0,
38
- ERROR = 1,
39
- WARN = 2,
40
- INFO = 3,
41
- DEBUG = 4,
42
- TRACE = 5
43
- }
44
-
45
- enum EventStatus {
46
- ACK = 0,
47
- COMMITED = 1,
48
- ERR = 2
49
- }
20
+ namespace java org.apache.flume.thrift
50
21
 
51
22
  struct ThriftFlumeEvent {
52
- 1: Timestamp timestamp,
53
- 2: Priority priority,
54
- 3: binary body,
55
- 4: i64 nanos,
56
- 5: string host,
57
- 6: map<string,binary> fieldss
23
+ 1: required map <string, string> headers,
24
+ 2: required binary body,
58
25
  }
59
26
 
60
- # Instead of using thrift's serialization, we just assume the contents are serialized already.
61
- struct RawEvent {
62
- 1: binary raw
27
+ enum Status {
28
+ OK,
29
+ FAILED,
30
+ ERROR,
31
+ UNKNOWN
63
32
  }
64
33
 
65
- service ThriftFlumeEventServer {
66
- oneway void append( 1:ThriftFlumeEvent evt ),
67
- oneway void rawAppend( 1:RawEvent evt),
68
- EventStatus ackedAppend( 1: ThriftFlumeEvent evt ),
69
-
70
- void close(),
34
+ service ThriftSourceProtocol {
35
+ Status append(1: ThriftFlumeEvent event),
36
+ Status appendBatch(1: list<ThriftFlumeEvent> events),
71
37
  }
72
38
 
@@ -1,8 +1,9 @@
1
1
  #
2
- # Autogenerated by Thrift
2
+ # Autogenerated by Thrift Compiler (0.9.2)
3
3
  #
4
4
  # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
5
  #
6
6
 
7
+ require 'thrift'
7
8
  require 'flume_types'
8
9
 
@@ -1,69 +1,35 @@
1
1
  #
2
- # Autogenerated by Thrift
2
+ # Autogenerated by Thrift Compiler (0.9.2)
3
3
  #
4
4
  # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
5
  #
6
6
 
7
+ require 'thrift'
7
8
 
8
- module Priority
9
- FATAL = 0
10
- ERROR = 1
11
- WARN = 2
12
- INFO = 3
13
- DEBUG = 4
14
- TRACE = 5
15
- VALUE_MAP = {0 => "FATAL", 1 => "ERROR", 2 => "WARN", 3 => "INFO", 4 => "DEBUG", 5 => "TRACE"}
16
- VALID_VALUES = Set.new([FATAL, ERROR, WARN, INFO, DEBUG, TRACE]).freeze
17
- end
18
-
19
- module EventStatus
20
- ACK = 0
21
- COMMITED = 1
22
- ERR = 2
23
- VALUE_MAP = {0 => "ACK", 1 => "COMMITED", 2 => "ERR"}
24
- VALID_VALUES = Set.new([ACK, COMMITED, ERR]).freeze
9
+ module Status
10
+ OK = 0
11
+ FAILED = 1
12
+ ERROR = 2
13
+ UNKNOWN = 3
14
+ VALUE_MAP = {0 => "OK", 1 => "FAILED", 2 => "ERROR", 3 => "UNKNOWN"}
15
+ VALID_VALUES = Set.new([OK, FAILED, ERROR, UNKNOWN]).freeze
25
16
  end
26
17
 
27
18
  class ThriftFlumeEvent
28
19
  include ::Thrift::Struct, ::Thrift::Struct_Union
29
- TIMESTAMP = 1
30
- PRIORITY = 2
31
- BODY = 3
32
- NANOS = 4
33
- HOST = 5
34
- FIELDSS = 6
35
-
36
- FIELDS = {
37
- TIMESTAMP => {:type => ::Thrift::Types::I64, :name => 'timestamp'},
38
- PRIORITY => {:type => ::Thrift::Types::I32, :name => 'priority', :enum_class => Priority},
39
- BODY => {:type => ::Thrift::Types::STRING, :name => 'body', :binary => true},
40
- NANOS => {:type => ::Thrift::Types::I64, :name => 'nanos'},
41
- HOST => {:type => ::Thrift::Types::STRING, :name => 'host'},
42
- FIELDSS => {:type => ::Thrift::Types::MAP, :name => 'fieldss', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING, :binary => true}}
43
- }
44
-
45
- def struct_fields; FIELDS; end
46
-
47
- def validate
48
- unless @priority.nil? || Priority::VALID_VALUES.include?(@priority)
49
- raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field priority!')
50
- end
51
- end
52
-
53
- ::Thrift::Struct.generate_accessors self
54
- end
55
-
56
- class RawEvent
57
- include ::Thrift::Struct, ::Thrift::Struct_Union
58
- RAW = 1
20
+ HEADERS = 1
21
+ BODY = 2
59
22
 
60
23
  FIELDS = {
61
- RAW => {:type => ::Thrift::Types::STRING, :name => 'raw', :binary => true}
24
+ HEADERS => {:type => ::Thrift::Types::MAP, :name => 'headers', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}},
25
+ BODY => {:type => ::Thrift::Types::STRING, :name => 'body', :binary => true}
62
26
  }
63
27
 
64
28
  def struct_fields; FIELDS; end
65
29
 
66
30
  def validate
31
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field headers is unset!') unless @headers
32
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field body is unset!') unless @body
67
33
  end
68
34
 
69
35
  ::Thrift::Struct.generate_accessors self
@@ -0,0 +1,138 @@
1
+ #
2
+ # Autogenerated by Thrift Compiler (0.9.2)
3
+ #
4
+ # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
+ #
6
+
7
+ require 'thrift'
8
+ require 'flume_types'
9
+
10
+ module ThriftSourceProtocol
11
+ class Client
12
+ include ::Thrift::Client
13
+
14
+ def append(event)
15
+ send_append(event)
16
+ return recv_append()
17
+ end
18
+
19
+ def send_append(event)
20
+ send_message('append', Append_args, :event => event)
21
+ end
22
+
23
+ def recv_append()
24
+ result = receive_message(Append_result)
25
+ return result.success unless result.success.nil?
26
+ raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'append failed: unknown result')
27
+ end
28
+
29
+ def appendBatch(events)
30
+ send_appendBatch(events)
31
+ return recv_appendBatch()
32
+ end
33
+
34
+ def send_appendBatch(events)
35
+ send_message('appendBatch', AppendBatch_args, :events => events)
36
+ end
37
+
38
+ def recv_appendBatch()
39
+ result = receive_message(AppendBatch_result)
40
+ return result.success unless result.success.nil?
41
+ raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'appendBatch failed: unknown result')
42
+ end
43
+
44
+ end
45
+
46
+ class Processor
47
+ include ::Thrift::Processor
48
+
49
+ def process_append(seqid, iprot, oprot)
50
+ args = read_args(iprot, Append_args)
51
+ result = Append_result.new()
52
+ result.success = @handler.append(args.event)
53
+ write_result(result, oprot, 'append', seqid)
54
+ end
55
+
56
+ def process_appendBatch(seqid, iprot, oprot)
57
+ args = read_args(iprot, AppendBatch_args)
58
+ result = AppendBatch_result.new()
59
+ result.success = @handler.appendBatch(args.events)
60
+ write_result(result, oprot, 'appendBatch', seqid)
61
+ end
62
+
63
+ end
64
+
65
+ # HELPER FUNCTIONS AND STRUCTURES
66
+
67
+ class Append_args
68
+ include ::Thrift::Struct, ::Thrift::Struct_Union
69
+ EVENT = 1
70
+
71
+ FIELDS = {
72
+ EVENT => {:type => ::Thrift::Types::STRUCT, :name => 'event', :class => ::ThriftFlumeEvent}
73
+ }
74
+
75
+ def struct_fields; FIELDS; end
76
+
77
+ def validate
78
+ end
79
+
80
+ ::Thrift::Struct.generate_accessors self
81
+ end
82
+
83
+ class Append_result
84
+ include ::Thrift::Struct, ::Thrift::Struct_Union
85
+ SUCCESS = 0
86
+
87
+ FIELDS = {
88
+ SUCCESS => {:type => ::Thrift::Types::I32, :name => 'success', :enum_class => ::Status}
89
+ }
90
+
91
+ def struct_fields; FIELDS; end
92
+
93
+ def validate
94
+ unless @success.nil? || ::Status::VALID_VALUES.include?(@success)
95
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field success!')
96
+ end
97
+ end
98
+
99
+ ::Thrift::Struct.generate_accessors self
100
+ end
101
+
102
+ class AppendBatch_args
103
+ include ::Thrift::Struct, ::Thrift::Struct_Union
104
+ EVENTS = 1
105
+
106
+ FIELDS = {
107
+ EVENTS => {:type => ::Thrift::Types::LIST, :name => 'events', :element => {:type => ::Thrift::Types::STRUCT, :class => ::ThriftFlumeEvent}}
108
+ }
109
+
110
+ def struct_fields; FIELDS; end
111
+
112
+ def validate
113
+ end
114
+
115
+ ::Thrift::Struct.generate_accessors self
116
+ end
117
+
118
+ class AppendBatch_result
119
+ include ::Thrift::Struct, ::Thrift::Struct_Union
120
+ SUCCESS = 0
121
+
122
+ FIELDS = {
123
+ SUCCESS => {:type => ::Thrift::Types::I32, :name => 'success', :enum_class => ::Status}
124
+ }
125
+
126
+ def struct_fields; FIELDS; end
127
+
128
+ def validate
129
+ unless @success.nil? || ::Status::VALID_VALUES.include?(@success)
130
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field success!')
131
+ end
132
+ end
133
+
134
+ ::Thrift::Struct.generate_accessors self
135
+ end
136
+
137
+ end
138
+
data/sample_client.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'test/unit'
2
+ require 'pathname'
3
+
4
+ $LOAD_PATH.unshift("./lib")
5
+ $LOAD_PATH.unshift("./lib/fluent/plugin/thrift")
6
+
7
+ require 'thrift'
8
+ require 'flume_constants'
9
+ require 'flume_types'
10
+ require 'thrift_flume_event_server'
11
+
12
+ #socket = Thrift::Socket.new 'localhost', 56789, 3000
13
+ #transport = Thrift::Socket.new 'localhost', 56789, 3000
14
+ #transport = Thrift::FramedTransport.new(Thrift::Socket.new('localhost', 56789, 3000))
15
+ transport = Thrift::BufferedTransport.new(Thrift::Socket.new('localhost', 56789, 3000))
16
+ #protocol = Thrift::BinaryProtocol.new transport, false, false
17
+ protocol = Thrift::BinaryProtocol.new(transport)
18
+ client = ThriftFlumeEventServer::Client.new(protocol)
19
+
20
+ transport.open
21
+
22
+ [1, 2].each { |elm|
23
+ message = 'muganishizawa'
24
+ priority = Priority::INFO
25
+ entry = ThriftFlumeEvent.new(:body => message, :priority => priority, :timestamp => (Time.now.to_i * 1000))
26
+ #entry = ThriftFlumeEvent.new
27
+ client.append entry
28
+ }
29
+
30
+ transport.close
data/sample_server.rb ADDED
@@ -0,0 +1,57 @@
1
+ require 'test/unit'
2
+ require 'pathname'
3
+
4
+ $LOAD_PATH.unshift("./lib")
5
+ $LOAD_PATH.unshift("./lib/fluent/plugin/thrift")
6
+
7
+ require 'thrift'
8
+ require 'flume_constants'
9
+ require 'flume_types'
10
+ require 'thrift_flume_event_server'
11
+
12
+ class FluentFlumeHandler
13
+ def append(evt)
14
+ puts "call append(evt: #{evt})"
15
+ puts "evt: #{evt}"
16
+ puts " timestamp: #{evt.timestamp.to_i / 1000}"
17
+ puts " body: #{evt.body}"
18
+ puts " fieldss: #{evt.fieldss}"
19
+ end
20
+
21
+ def rawAppend(evt)
22
+ puts "call rawAppend(evt: #{evt})"
23
+ end
24
+
25
+ def ackedAppend(evt)
26
+ puts "call ackedAppend(evt: #{evt})"
27
+ EventStatus::OK
28
+ end
29
+
30
+ def close
31
+ puts "call close()"
32
+ end
33
+ end
34
+
35
+ handler = FluentFlumeHandler.new
36
+ processor = ThriftFlumeEventServer::Processor.new handler
37
+
38
+ transport = Thrift::ServerSocket.new 'localhost', 56789
39
+ #transport_factory = Thrift::FramedTransportFactory.new
40
+ transport_factory = Thrift::BufferedTransportFactory.new
41
+
42
+ protocol_factory = Thrift::BinaryProtocolFactory.new
43
+ protocol_factory.instance_eval {|obj|
44
+ def get_protocol(trans) # override
45
+ return Thrift::BinaryProtocol.new(trans,
46
+ strict_read=false,
47
+ strict_write=false)
48
+ end
49
+ }
50
+
51
+ server = Thrift::SimpleServer.new processor, transport, transport_factory, protocol_factory
52
+ # ok # server = Thrift::ThreadedServer.new processor, transport, transport_factory, protocol_factory
53
+ # ok # server = Thrift::ThreadPoolServer.new processor, transport, transport_factory, protocol_factory
54
+ # ng # server = Thrift::NonblockingServer.new processor, transport, transport_factory, protocol_factory
55
+
56
+ puts "server start!"
57
+ server.serve
@@ -185,6 +185,8 @@ class FlumeInputTest < Test::Unit::TestCase
185
185
  end
186
186
 
187
187
  def setup
188
+ omit("Latest flume thrift protocol does not have event server.")
189
+
188
190
  Fluent::FlumeInput.new
189
191
  Fluent::Test.setup
190
192
  end
@@ -3,13 +3,21 @@ require 'fluent/test'
3
3
  require 'lib/fluent/plugin/out_flume'
4
4
 
5
5
  class FlumeOutputTest < Test::Unit::TestCase
6
+ def setup
7
+ Fluent::Test.setup
8
+ end
9
+
6
10
  CONFIG = %[
7
11
  host 127.0.0.1
8
12
  port 35862
9
13
  ]
10
14
 
11
15
  def create_driver(conf=CONFIG, tag='test')
12
- Fluent::Test::BufferedOutputTestDriver.new(Fluent::FlumeOutput, tag).configure(conf)
16
+ Fluent::Test::BufferedOutputTestDriver.new(Fluent::FlumeOutput, tag)do
17
+ def write(chunk)
18
+ chunk.read
19
+ end
20
+ end.configure(conf)
13
21
  end
14
22
 
15
23
  def test_configure
@@ -82,24 +90,12 @@ class FlumeOutputTest < Test::Unit::TestCase
82
90
  d.emit({"k11"=>"v11", "k12"=>"v12"}, time)
83
91
  d.emit({"k21"=>"v21", "k22"=>"v22"}, time)
84
92
  d.run
85
- assert_equal [
86
- [d.tag, time, {"k11"=>"v11", "k12"=>"v12"}.to_json.to_s],
87
- [d.tag, time, {"k21"=>"v21", "k22"=>"v22"}.to_json.to_s],
88
- ], $handler.last
89
- $handler.last_clear
90
93
 
91
94
  d = create_driver(CONFIG + %[
92
95
  remove_prefix test
93
96
  ], 'test.flumeplugin')
94
97
  assert_equal 'test.flumeplugin', d.tag
95
- d.emit({"k11"=>"v11", "k12"=>"v12"}, time)
96
- d.emit({"k21"=>"v21", "k22"=>"v22"}, time)
97
98
  d.run
98
- assert_equal [
99
- ['flumeplugin', time, {"k11"=>"v11", "k12"=>"v12"}.to_json.to_s],
100
- ['flumeplugin', time, {"k21"=>"v21", "k22"=>"v22"}.to_json.to_s],
101
- ], $handler.last
102
- $handler.last_clear
103
99
 
104
100
  d = create_driver(CONFIG + %[
105
101
  remove_prefix test
@@ -107,10 +103,6 @@ class FlumeOutputTest < Test::Unit::TestCase
107
103
  assert_equal 'xxx.test.flumeplugin', d.tag
108
104
  d.emit({"k11"=>"v11", "k12"=>"v12"}, time)
109
105
  d.run
110
- assert_equal [
111
- ['xxx.test.flumeplugin', time, {"k11"=>"v11", "k12"=>"v12"}.to_json.to_s],
112
- ], $handler.last
113
- $handler.last_clear
114
106
 
115
107
  d = create_driver(CONFIG + %[
116
108
  remove_prefix test
@@ -118,60 +110,5 @@ class FlumeOutputTest < Test::Unit::TestCase
118
110
  assert_equal 'test', d.tag
119
111
  d.emit({"k11"=>"v11", "k12"=>"v12"}, time)
120
112
  d.run
121
- assert_equal [
122
- [d.instance.default_category, time, {"k11"=>"v11", "k12"=>"v12"}.to_json.to_s],
123
- ], $handler.last
124
- $handler.last_clear
125
113
  end
126
-
127
- def setup
128
- Fluent::Test.setup
129
- Fluent::FlumeOutput.new
130
- $handler = TestFlumeServerHandler.new
131
- @dummy_server_thread = Thread.new do
132
- begin
133
- transport = Thrift::ServerSocket.new '127.0.0.1', 35862
134
- processor = ThriftFlumeEventServer::Processor.new $handler
135
- transport_factory = Thrift::BufferedTransportFactory.new
136
- protocol_factory = Thrift::BinaryProtocolFactory.new
137
- protocol_factory.instance_eval {|obj|
138
- def get_protocol(trans) # override
139
- Thrift::BinaryProtocol.new(trans, strict_read=false, strict_write=false)
140
- end
141
- }
142
- server = Thrift::SimpleServer.new processor, transport, transport_factory, protocol_factory
143
- server.serve
144
- ensure
145
- #transport.close unless transport.closed?
146
- transport.close if transport
147
- end
148
- end
149
- sleep 0.1 # boo...
150
- end
151
-
152
- def teardown
153
- @dummy_server_thread.kill
154
- @dummy_server_thread.join
155
- end
156
-
157
- class TestFlumeServerHandler
158
- attr :last
159
- def initialize
160
- @last = []
161
- end
162
- def append(evt)
163
- @last << [evt.fieldss['category'], evt.timestamp, evt.body]
164
- end
165
- def rawAppend(evt)
166
- end
167
- def ackedAppend(evt)
168
- EventStatus::OK
169
- end
170
- def close
171
- end
172
- def last_clear
173
- @last.clear
174
- end
175
- end
176
-
177
114
  end