norikra 0.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/.gitignore +17 -0
  2. data/.ruby-version +1 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +339 -0
  5. data/README.md +104 -0
  6. data/Rakefile +10 -0
  7. data/bin/norikra +8 -0
  8. data/esper/changelog.txt +1066 -0
  9. data/esper/esper-4.9.0.jar +0 -0
  10. data/esper/esper-license.txt +95 -0
  11. data/esper/esper/lib/antlr-runtime-3.2.jar +0 -0
  12. data/esper/esper/lib/cglib-nodep-2.2.jar +0 -0
  13. data/esper/esper/lib/commons-logging-1.1.1.jar +0 -0
  14. data/esper/esper/lib/esper_3rdparties.license +299 -0
  15. data/esper/esper/lib/log4j-1.2.16.jar +0 -0
  16. data/esper/esper/lib/readme.txt +38 -0
  17. data/esper/esperio-amqp-4.9.0.jar +0 -0
  18. data/esper/esperio-amqp/lib/commons-cli-1.1.jar +0 -0
  19. data/esper/esperio-amqp/lib/commons-io-1.2.jar +0 -0
  20. data/esper/esperio-amqp/lib/esperio_3rdparties.license +1328 -0
  21. data/esper/esperio-amqp/lib/esperio_amqp_jars.txt +2 -0
  22. data/esper/esperio-amqp/lib/rabbitmq-client.jar +0 -0
  23. data/esper/esperio-csv-4.9.0.jar +0 -0
  24. data/esper/esperio-csv/lib/esperio_3rdparties.license +1328 -0
  25. data/esper/esperio-db-4.9.0.jar +0 -0
  26. data/esper/esperio-db/lib/esperio_3rdparties.license +1328 -0
  27. data/esper/esperio-http-4.9.0.jar +0 -0
  28. data/esper/esperio-http/lib/esperio_3rdparties.license +1328 -0
  29. data/esper/esperio-http/lib/httpclient-4.0.1.jar +0 -0
  30. data/esper/esperio-http/lib/httpcore-4.0.1.jar +0 -0
  31. data/esper/esperio-http/lib/httpcore-nio-4.0.1.jar +0 -0
  32. data/esper/esperio-license.txt +95 -0
  33. data/esper/esperio-socket-4.9.0.jar +0 -0
  34. data/esper/esperio-socket/lib/esperio_3rdparties.license +1328 -0
  35. data/esper/esperio-springjms-4.9.0.jar +0 -0
  36. data/esper/esperio-springjms/lib/activation-1.1.jar +0 -0
  37. data/esper/esperio-springjms/lib/activemq-core-5.7.0.jar +0 -0
  38. data/esper/esperio-springjms/lib/activemq-pool-5.7.0.jar +0 -0
  39. data/esper/esperio-springjms/lib/commons-pool-1.6.jar +0 -0
  40. data/esper/esperio-springjms/lib/esperio_3rdparties.license +1328 -0
  41. data/esper/esperio-springjms/lib/geronimo-j2ee-management_1.1_spec-1.0.1.jar +0 -0
  42. data/esper/esperio-springjms/lib/geronimo-jms_1.1_spec-1.1.1.jar +0 -0
  43. data/esper/esperio-springjms/lib/junit-4.8.2.jar +0 -0
  44. data/esper/esperio-springjms/lib/org.springframework.asm-3.1.1.RELEASE.jar +0 -0
  45. data/esper/esperio-springjms/lib/org.springframework.beans-3.1.1.RELEASE.jar +0 -0
  46. data/esper/esperio-springjms/lib/org.springframework.context-3.1.1.RELEASE.jar +0 -0
  47. data/esper/esperio-springjms/lib/org.springframework.core-3.1.1.RELEASE.jar +0 -0
  48. data/esper/esperio-springjms/lib/org.springframework.expression-3.1.1.RELEASE.jar +0 -0
  49. data/esper/esperio-springjms/lib/org.springframework.jms-3.1.1.RELEASE.jar +0 -0
  50. data/esper/esperio-springjms/lib/org.springframework.transaction-3.1.1.RELEASE.jar +0 -0
  51. data/esper/esperio-springjms/lib/slf4j-api-1.7.2.jar +0 -0
  52. data/esper/esperio-springjms/lib/slf4j-log4j12-1.7.2.jar +0 -0
  53. data/esper/esperio-stax-4.9.0.jar +0 -0
  54. data/esper/esperio-stax/lib/axiom-api-1.2.9.jar +0 -0
  55. data/esper/esperio-stax/lib/axiom-c14n-1.2.9.jar +0 -0
  56. data/esper/esperio-stax/lib/axiom-dom-1.2.9.jar +0 -0
  57. data/esper/esperio-stax/lib/axiom-impl-1.2.9.jar +0 -0
  58. data/esper/esperio-stax/lib/commons-logging-1.1.1.jar +0 -0
  59. data/esper/esperio-stax/lib/commons-logging-LICENSE.txt +203 -0
  60. data/esper/esperio-stax/lib/esperio_3rdparties.license +1328 -0
  61. data/esper/esperio-stax/lib/geronimo-activation-LICENSE.txt +203 -0
  62. data/esper/esperio-stax/lib/geronimo-activation_1.1_spec-1.0.2.jar +0 -0
  63. data/esper/esperio-stax/lib/geronimo-javamail-LICENSE.txt +203 -0
  64. data/esper/esperio-stax/lib/geronimo-javamail_1.4_spec-1.6.jar +0 -0
  65. data/esper/esperio-stax/lib/geronimo-stax-api-LICENSE.txt +203 -0
  66. data/esper/esperio-stax/lib/geronimo-stax-api_1.0_spec-1.0.1.jar +0 -0
  67. data/esper/esperio-stax/lib/jaxen-1.1.1.jar +0 -0
  68. data/esper/esperio-stax/lib/jaxen-LICENSE.txt +33 -0
  69. data/esper/esperio-stax/lib/wstx-LICENSE.txt +203 -0
  70. data/esper/esperio-stax/lib/wstx-asl-3.2.9.jar +0 -0
  71. data/junks/esper-test.rb +79 -0
  72. data/junks/glassfish.rb +17 -0
  73. data/junks/mizuno.rb +28 -0
  74. data/junks/simple_test.rb +35 -0
  75. data/junks/type_confliction.rb +46 -0
  76. data/junks/type_conversion.rb +49 -0
  77. data/junks/type_inherit.rb +67 -0
  78. data/lib/norikra.rb +13 -0
  79. data/lib/norikra/cli.rb +24 -0
  80. data/lib/norikra/engine.rb +231 -0
  81. data/lib/norikra/output_pool.rb +45 -0
  82. data/lib/norikra/query.rb +173 -0
  83. data/lib/norikra/rpc.rb +6 -0
  84. data/lib/norikra/rpc/handler.rb +57 -0
  85. data/lib/norikra/rpc/http.rb +36 -0
  86. data/lib/norikra/server.rb +41 -0
  87. data/lib/norikra/typedef.rb +307 -0
  88. data/lib/norikra/typedef_manager.rb +91 -0
  89. data/lib/norikra/version.rb +3 -0
  90. data/norikra.gemspec +33 -0
  91. data/script/spec_server_pry +45 -0
  92. data/spec/field_spec.rb +141 -0
  93. data/spec/fieldset_spec.rb +172 -0
  94. data/spec/output_pool_spec.rb +75 -0
  95. data/spec/query_spec.rb +82 -0
  96. data/spec/spec_helper.rb +55 -0
  97. data/spec/typedef_manager_spec.rb +128 -0
  98. data/spec/typedef_spec.rb +248 -0
  99. metadata +328 -0
@@ -0,0 +1,6 @@
1
+ module Norikra::RPC
2
+ # namespace only
3
+ end
4
+
5
+ require 'norikra/rpc/handler'
6
+ require 'norikra/rpc/http'
@@ -0,0 +1,57 @@
1
+ class Norikra::RPC::Handler
2
+ def initialize(engine)
3
+ @engine = engine
4
+ end
5
+
6
+ def targets
7
+ @engine.targets
8
+ end
9
+
10
+ def open(target, fields)
11
+ r = @engine.open(target, fields)
12
+ !!r
13
+ end
14
+
15
+ def close(target)
16
+ r = @engine.close(target)
17
+ !!r
18
+ end
19
+
20
+ def queries
21
+ @engine.queries.map(&:to_hash)
22
+ end
23
+
24
+ def register(query_name, expression)
25
+ r = @engine.register(Norikra::Query.new(:name => query_name, :expression => expression))
26
+ !!r
27
+ end
28
+
29
+ def deregister(query_name)
30
+ #TODO: write!
31
+ raise NotImplementedError
32
+ end
33
+
34
+ def fields(target)
35
+ @engine.typedef_manager.field_list(target)
36
+ end
37
+
38
+ def reserve(target, fieldname, type)
39
+ r = @engine.reserve(target, fieldname, type)
40
+ !!r
41
+ end
42
+
43
+ def send(target, events)
44
+ r = @engine.send(target, events)
45
+ !!r
46
+ end
47
+
48
+ def event(query_name)
49
+ @engine.output_pool.pop(query_name)
50
+ end
51
+
52
+ def sweep
53
+ @engine.output_pool.sweep
54
+ end
55
+
56
+ # post('/listen') # get all events as stream, during connection keepaliving
57
+ end
@@ -0,0 +1,36 @@
1
+ require 'mizuno/server'
2
+ require 'rack/builder'
3
+ require 'msgpack-rpc-over-http-jruby'
4
+
5
+ require_relative 'handler'
6
+
7
+ module Norikra::RPC
8
+ class HTTP
9
+ #TODO Xmx of mizuno/jetty
10
+ attr_accessor :host, :port, :threads
11
+ attr_accessor :engine, :mizuno, :thread
12
+
13
+ def initialize(opts={})
14
+ @engine = opts[:engine]
15
+ @host = opts[:host]
16
+ @port = opts[:port]
17
+ handler = Norikra::RPC::Handler.new(@engine)
18
+ @app = Rack::Builder.new {
19
+ run MessagePack::RPCOverHTTP::Server.app(handler)
20
+ }
21
+ end
22
+
23
+ def start
24
+ @thread = Thread.new do
25
+ @mizuno = Mizuno::Server.new
26
+ @mizuno.run(@app, :embedded => true, :threads => 5, :port => @port, :host => @host)
27
+ end
28
+ end
29
+
30
+ def stop
31
+ @mizuno.stop
32
+ @thread.kill
33
+ @thread.join
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,41 @@
1
+ require 'norikra/engine'
2
+
3
+ require 'norikra/typedef_manager'
4
+ require 'norikra/output_pool'
5
+ require 'norikra/typedef'
6
+ require 'norikra/query'
7
+
8
+ require 'norikra/rpc'
9
+
10
+ module Norikra
11
+ class Server
12
+ RPC_DEFAULT_HOST = '0.0.0.0'
13
+ RPC_DEFAULT_PORT = 26571
14
+ # 26571 = 3026 + 3014 + 2968 + 2950 + 2891 + 2896 + 2975 + 2979 + 2872
15
+
16
+ def initialize(host=RPC_DEFAULT_HOST, port=RPC_DEFAULT_PORT, configuration={})
17
+ #TODO: initial configuration
18
+ @typedef_manager = Norikra::TypedefManager.new
19
+
20
+ @output_pool = Norikra::OutputPool.new
21
+
22
+ @engine = Norikra::Engine.new(@output_pool, @typedef_manager)
23
+ @rpcserver = Norikra::RPC::HTTP.new(:engine => @engine, :port => port)
24
+ end
25
+
26
+ def run
27
+ @engine.start
28
+ @rpcserver.start
29
+ p "Norikra server started."
30
+ #TODO: main loop and signal traps
31
+ #TODO: loggings
32
+ sleep 50
33
+ end
34
+
35
+ def shutdown
36
+ #TODO: stop order
37
+ @rpcserver.stop
38
+ @engine.stop
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,307 @@
1
+ require 'digest'
2
+ require 'json'
3
+
4
+ # Norikra::Field, Norikra::FieldSet, Norikra::Typedef
5
+
6
+ module Norikra
7
+ class Field
8
+ attr_accessor :name, :type, :optional
9
+
10
+ def initialize(name, type, optional=nil)
11
+ @name = name.to_s
12
+ @type = self.class.valid_type?(type)
13
+ @optional = optional
14
+ end
15
+
16
+ def to_hash
17
+ {'name' => @name, 'type' => @type, 'optional' => @optional}
18
+ end
19
+
20
+ def dup(optional=nil)
21
+ self.class.new(@name, @type, optional.nil? ? @optional : optional)
22
+ end
23
+
24
+ def ==(other)
25
+ self.name == other.name && self.type == other.type && self.optional == other.optional
26
+ end
27
+
28
+ def optional? # used outside of FieldSet
29
+ @optional
30
+ end
31
+
32
+ ### esper types
33
+ ### http://esper.codehaus.org/esper-4.9.0/doc/reference/en-US/html/epl_clauses.html#epl-syntax-datatype
34
+ # string A single character to an unlimited number of characters.
35
+ # boolean A boolean value.
36
+ # integer An integer value (4 byte).
37
+ # long A long value (8 byte). Use the "L" or "l" (lowercase L) suffix. # select 1L as field1, 1l as field2
38
+ # double A double-precision 64-bit IEEE 754 floating point. # select 1.67 as field1, 167e-2 as field2, 1.67d as field3
39
+ # float A single-precision 32-bit IEEE 754 floating point. Use the "f" suffix. # select 1.2f as field1, 1.2F as field2
40
+ # byte A 8-bit signed two's complement integer. # select 0x10 as field1
41
+ #
42
+ #### 'integer' in epser document IS WRONG.
43
+ #### If 'integer' specified, esper raises this exception:
44
+ ### Exception: Nestable type configuration encountered an unexpected property type name 'integer' for property 'status',
45
+ ### expected java.lang.Class or java.util.Map or the name of a previously-declared Map or ObjectArray type
46
+ #### Correct type name is 'int'. see and run 'junks/esper-test.rb'
47
+ def self.valid_type?(type)
48
+ case type.to_s.downcase
49
+ when 'string' then 'string'
50
+ when 'boolean' then 'boolean'
51
+ when 'int' then 'int'
52
+ when 'long' then 'long'
53
+ when 'float' then 'float'
54
+ when 'double' then 'double'
55
+ else
56
+ raise ArgumentError, "invalid field type #{type}"
57
+ end
58
+ end
59
+
60
+ def format(value)
61
+ case @type
62
+ when 'string' then value.to_s
63
+ when 'boolean' then value =~ /^(true|false)$/i ? ($1.downcase == 'true') : (!!value)
64
+ when 'long','int' then value.to_i
65
+ when 'double','float' then value.to_f
66
+ else
67
+ raise RuntimeError, "unknown field type (in format), maybe BUG. name:#{@name},type:#{@type}"
68
+ end
69
+ end
70
+ end
71
+
72
+ class FieldSet
73
+ attr_accessor :summary, :fields
74
+ attr_accessor :target, :level
75
+
76
+ def initialize(fields, default_optional=nil)
77
+ @fields = {}
78
+ fields.keys.each do |key|
79
+ data = fields[key]
80
+ type,optional = if data.is_a?(Hash)
81
+ [data[:type], (data.has_key?(:optional) ? data[:optional] : default_optional)]
82
+ elsif data.is_a?(String)
83
+ [data, default_optional]
84
+ else
85
+ raise ArgumentError, "FieldSet.new argument class unknown: #{fields.class}"
86
+ end
87
+ @fields[key.to_s] = Field.new(key, type, optional)
88
+ end
89
+ self.update_summary
90
+
91
+ @target = nil
92
+ @level = nil
93
+ @event_type_name = nil
94
+ end
95
+
96
+ def dup
97
+ fields = Hash[@fields.map{|key,field| [key, {:type => field.type, :optional => field.optional}]}]
98
+ self.class.new(fields)
99
+ end
100
+
101
+ def field_names_key
102
+ @fields.keys.sort.join(',')
103
+ end
104
+
105
+ def update_summary
106
+ @summary = @fields.keys.sort.map{|k| @fields[k].name + ':' + @fields[k].type}.join(',')
107
+ self
108
+ end
109
+
110
+ def update(fields, optional_flag)
111
+ fields.each do |field|
112
+ @fields[field.name] = field.dup(optional_flag)
113
+ end
114
+ self.update_summary
115
+ end
116
+
117
+ #TODO: have a bug?
118
+ def ==(other)
119
+ return false unless self.class != other.class
120
+ self.summary == other.summary
121
+ end
122
+
123
+ def definition
124
+ d = {}
125
+ @fields.each do |key, field|
126
+ d[field.name] = field.type
127
+ end
128
+ d
129
+ end
130
+
131
+ def subset?(other) # self is subset of other (or not)
132
+ (self.fields.keys - other.fields.keys).size == 0
133
+ end
134
+
135
+ def event_type_name
136
+ @event_type_name.dup
137
+ end
138
+
139
+ def bind(target, level)
140
+ @target = target
141
+ @level = level
142
+ prefix = case level
143
+ when :base then 'b_'
144
+ when :query then 'q_'
145
+ else 'e_'
146
+ end
147
+ @event_type_name = prefix + Digest::MD5.hexdigest(target + "\t" + level.to_s + "\t" + @summary)
148
+ self
149
+ end
150
+
151
+ def self.simple_guess(data, optional=true)
152
+ mapping = Hash[
153
+ data.map{|key,value|
154
+ type = case value
155
+ when TrueClass,FalseClass then 'boolean'
156
+ when Integer then 'long'
157
+ when Float then 'double'
158
+ else
159
+ 'string'
160
+ end
161
+ [key,type]
162
+ }
163
+ ]
164
+ self.new(mapping, optional)
165
+ end
166
+
167
+ # def self.guess(data, optional=true)
168
+ # mapping = Hash[
169
+ # data.map{|key,value|
170
+ # sval = value.to_s
171
+ # type = case
172
+ # when val.is_a?(TrueClass) || val.is_a?(FalseClass) || sval =~ /^(?:true|false)$/i
173
+ # 'boolean'
174
+ # when val.is_a?(Integer) || sval =~ /^-?\d+[lL]?$/
175
+ # 'long'
176
+ # when val.is_a?(Float) || sval =~ /^-?\d+\.\d+(?:[eE]-?\d+|[dDfF])?$/
177
+ # 'double'
178
+ # else
179
+ # 'string'
180
+ # end
181
+ # [key,type]
182
+ # }
183
+ # ]
184
+ # self.new(mapping, optional)
185
+ # end
186
+ end
187
+
188
+ # Typedef is
189
+ # * known field list of target (and these are optional or not)
190
+ # * known field-set list of a target
191
+ # * base set of a target
192
+ class Typedef
193
+ attr_accessor :fields, :baseset, :queryfieldsets, :datafieldsets
194
+
195
+ def initialize(fields=nil)
196
+ if fields
197
+ @baseset = FieldSet.new(fields, false) # all fields are required
198
+ @fields = @baseset.fields.dup
199
+ else
200
+ @baseset = nil
201
+ @fields = {}
202
+ end
203
+
204
+ @queryfieldsets = []
205
+ @datafieldsets = []
206
+
207
+ @set_map = {} # fieldname.sort.join(',') => data_fieldset
208
+
209
+ @mutex = Mutex.new
210
+ end
211
+
212
+ def field_defined?(list)
213
+ list.reduce(true){|r,f| r && @fields[f]}
214
+ end
215
+
216
+ def lazy?
217
+ @baseset.nil?
218
+ end
219
+
220
+ def activate(fieldset)
221
+ @mutex.synchronize do
222
+ set = fieldset.dup
223
+ fieldset.fields.dup.each do |fieldname, field|
224
+ set.fields[fieldname] = field.dup(false)
225
+ end
226
+ @baseset = set
227
+ @fields = @baseset.fields.merge(@fields)
228
+ end
229
+ end
230
+
231
+ def reserve(fieldname, type, optional=true)
232
+ fieldname = fieldname.to_s
233
+ @mutex.synchronize do
234
+ return false if @fields[fieldname]
235
+ @fields[fieldname] = Field.new(fieldname, type, optional)
236
+ end
237
+ true
238
+ end
239
+
240
+ def consistent?(fieldset)
241
+ fields = fieldset.fields
242
+ @baseset.subset?(fieldset) &&
243
+ @fields.values.select{|f| !f.optional? }.reduce(true){|r,f| r && fields[f.name] && fields[f.name].type == f.type} &&
244
+ fields.values.reduce(true){|r,f| r && (@fields[f.name].nil? || @fields[f.name].type == f.type)}
245
+ end
246
+
247
+ def push(level, fieldset)
248
+ unless self.consistent?(fieldset)
249
+ raise ArgumentError, "inconsistent field set for this typedef"
250
+ end
251
+
252
+ @mutex.synchronize do
253
+ case level
254
+ when :base
255
+ unless @baseset.object_id == fieldset.object_id
256
+ raise RuntimeError, "baseset mismatch"
257
+ end
258
+ when :query
259
+ unless @queryfieldsets.include?(fieldset)
260
+ @queryfieldsets.push(fieldset)
261
+
262
+ fieldset.fields.each do |fieldname,field|
263
+ @fields[fieldname] = field.dup(true) unless @fields[fieldname]
264
+ end
265
+ end
266
+ when :data
267
+ unless @datafieldsets.include?(fieldset)
268
+ @datafieldsets.push(fieldset)
269
+ @set_map[fieldset.field_names_key] = fieldset
270
+
271
+ fieldset.fields.each do |fieldname,field|
272
+ @fields[fieldname] = field.dup(true) unless @fields[fieldname]
273
+ end
274
+ end
275
+ else
276
+ raise ArgumentError, "unknown level #{level}"
277
+ end
278
+ end
279
+ true
280
+ end
281
+
282
+ def refer(data)
283
+ field_names_key = data.keys.sort.join(',')
284
+ return @set_map[field_names_key] if @set_map.has_key?(field_names_key)
285
+
286
+ guessed = FieldSet.simple_guess(data)
287
+ guessed_fields = guessed.fields
288
+ @fields.each do |key,field|
289
+ if guessed_fields.has_key?(key)
290
+ guessed_fields[key].type = field.type if guessed_fields[key].type != field.type
291
+ else
292
+ guessed_fields[key] = field unless field.optional?
293
+ end
294
+ end
295
+ guessed
296
+ end
297
+
298
+ def format(data)
299
+ # all keys of data should be already known at #format (before #format, do #refer)
300
+ ret = {}
301
+ data.each do |key, value|
302
+ ret[key] = @fields[key].format(value)
303
+ end
304
+ ret
305
+ end
306
+ end
307
+ end