norikra 0.0.1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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