zookeeper-ng 1.5.2.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.
- checksums.yaml +7 -0
- data/.ctags_paths +1 -0
- data/.dotfiles/ruby-gemset +1 -0
- data/.dotfiles/ruby-version +1 -0
- data/.dotfiles/rvmrc +2 -0
- data/.github/workflows/build.yml +57 -0
- data/.gitignore +19 -0
- data/.gitmodules +3 -0
- data/CHANGELOG +408 -0
- data/Gemfile +30 -0
- data/Guardfile +8 -0
- data/LICENSE +23 -0
- data/Manifest +29 -0
- data/README.markdown +62 -0
- data/Rakefile +121 -0
- data/cause-abort.rb +117 -0
- data/ext/.gitignore +6 -0
- data/ext/Rakefile +41 -0
- data/ext/c_zookeeper.rb +398 -0
- data/ext/common.h +17 -0
- data/ext/dbg.h +53 -0
- data/ext/depend +5 -0
- data/ext/event_lib.c +740 -0
- data/ext/event_lib.h +175 -0
- data/ext/extconf.rb +103 -0
- data/ext/generate_gvl_code.rb +321 -0
- data/ext/patches/zkc-3.3.5-network.patch +24 -0
- data/ext/patches/zkc-3.4.5-buffer-overflow.patch +11 -0
- data/ext/patches/zkc-3.4.5-config.patch +5454 -0
- data/ext/patches/zkc-3.4.5-fetch-and-add.patch +16 -0
- data/ext/patches/zkc-3.4.5-logging.patch +41 -0
- data/ext/patches/zkc-3.4.5-out-of-order-ping.patch +163 -0
- data/ext/patches/zkc-3.4.5-yosemite-htonl-fix.patch +102 -0
- data/ext/zkc-3.4.5.tar.gz +0 -0
- data/ext/zkrb.c +1080 -0
- data/ext/zkrb_wrapper.c +775 -0
- data/ext/zkrb_wrapper.h +350 -0
- data/ext/zkrb_wrapper_compat.c +15 -0
- data/ext/zkrb_wrapper_compat.h +11 -0
- data/ext/zookeeper_base.rb +256 -0
- data/java/java_base.rb +501 -0
- data/lib/zookeeper/acls.rb +44 -0
- data/lib/zookeeper/callbacks.rb +108 -0
- data/lib/zookeeper/client.rb +30 -0
- data/lib/zookeeper/client_methods.rb +282 -0
- data/lib/zookeeper/common/queue_with_pipe.rb +110 -0
- data/lib/zookeeper/common.rb +122 -0
- data/lib/zookeeper/compatibility.rb +138 -0
- data/lib/zookeeper/constants.rb +97 -0
- data/lib/zookeeper/continuation.rb +223 -0
- data/lib/zookeeper/core_ext.rb +58 -0
- data/lib/zookeeper/em_client.rb +55 -0
- data/lib/zookeeper/exceptions.rb +135 -0
- data/lib/zookeeper/forked.rb +19 -0
- data/lib/zookeeper/latch.rb +34 -0
- data/lib/zookeeper/logger/forwarding_logger.rb +84 -0
- data/lib/zookeeper/logger.rb +39 -0
- data/lib/zookeeper/monitor.rb +19 -0
- data/lib/zookeeper/rake_tasks.rb +165 -0
- data/lib/zookeeper/request_registry.rb +153 -0
- data/lib/zookeeper/stat.rb +21 -0
- data/lib/zookeeper/version.rb +4 -0
- data/lib/zookeeper.rb +115 -0
- data/notes.txt +14 -0
- data/scripts/upgrade-1.0-sed-alike.rb +46 -0
- data/spec/c_zookeeper_spec.rb +51 -0
- data/spec/chrooted_connection_spec.rb +83 -0
- data/spec/compatibilty_spec.rb +8 -0
- data/spec/default_watcher_spec.rb +41 -0
- data/spec/em_spec.rb +51 -0
- data/spec/ext/zookeeper_base_spec.rb +19 -0
- data/spec/forked_connection_spec.rb +122 -0
- data/spec/latch_spec.rb +24 -0
- data/spec/log4j.properties +17 -0
- data/spec/shared/all_success_return_values.rb +10 -0
- data/spec/shared/connection_examples.rb +1081 -0
- data/spec/spec_helper.rb +61 -0
- data/spec/support/00_logging.rb +38 -0
- data/spec/support/10_spawn_zookeeper.rb +20 -0
- data/spec/support/progress_formatter.rb +15 -0
- data/spec/support/zookeeper_spec_helpers.rb +96 -0
- data/spec/zookeeper_spec.rb +24 -0
- data/zookeeper.gemspec +46 -0
- data/zoomonkey/duplicates +3 -0
- data/zoomonkey/zoomonkey.rb +194 -0
- metadata +185 -0
data/java/java_base.rb
ADDED
@@ -0,0 +1,501 @@
|
|
1
|
+
require 'java'
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
# require 'rubygems'
|
5
|
+
# gem 'slyphon-log4j', '= 1.2.15'
|
6
|
+
# gem 'zk-ruby-zookeeper_jar', "= #{Zookeeper::DRIVER_VERSION}"
|
7
|
+
|
8
|
+
require 'log4j'
|
9
|
+
require 'zookeeper_jar'
|
10
|
+
|
11
|
+
|
12
|
+
# XXX: reindent this WHOLE FILE later
|
13
|
+
module Zookeeper
|
14
|
+
|
15
|
+
# The low-level wrapper-specific methods for the Java lib,
|
16
|
+
# subclassed by the top-level Zookeeper class
|
17
|
+
class JavaBase
|
18
|
+
include Java
|
19
|
+
include Common
|
20
|
+
include Constants
|
21
|
+
include Callbacks
|
22
|
+
include Exceptions
|
23
|
+
include ACLs
|
24
|
+
include Logger
|
25
|
+
|
26
|
+
JZK = org.apache.zookeeper
|
27
|
+
JZKD = org.apache.zookeeper.data
|
28
|
+
Code = JZK::KeeperException::Code
|
29
|
+
|
30
|
+
ANY_VERSION = -1
|
31
|
+
DEFAULT_SESSION_TIMEOUT = 10_000
|
32
|
+
|
33
|
+
JZKD::Stat.class_eval do
|
34
|
+
MEMBERS = [:version, :czxid, :mzxid, :ctime, :mtime, :cversion, :aversion, :ephemeralOwner, :dataLength, :numChildren, :pzxid]
|
35
|
+
def to_hash
|
36
|
+
MEMBERS.inject({}) { |h,k| h[k] = __send__(k); h }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
JZKD::Id.class_eval do
|
41
|
+
def to_hash
|
42
|
+
{ :scheme => getScheme, :id => getId }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
JZKD::ACL.class_eval do
|
47
|
+
def self.from_ruby_acl(acl)
|
48
|
+
raise TypeError, "acl must be a Zookeeper::ACLs::ACL not #{acl.inspect}" unless acl.kind_of?(Zookeeper::ACLs::ACL)
|
49
|
+
id = org.apache.zookeeper.data.Id.new(acl.id.scheme.to_s, acl.id.id.to_s)
|
50
|
+
new(acl.perms.to_i, id)
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_hash
|
54
|
+
{ :perms => getPerms, :id => getId.to_hash }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
JZK::WatchedEvent.class_eval do
|
59
|
+
def to_hash
|
60
|
+
{ :type => getType.getIntValue, :state => getState.getIntValue, :path => getPath }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# used for internal dispatching
|
65
|
+
# @private
|
66
|
+
module JavaCB
|
67
|
+
class Callback
|
68
|
+
include Logger
|
69
|
+
|
70
|
+
attr_reader :req_id
|
71
|
+
|
72
|
+
def initialize(req_id)
|
73
|
+
@req_id = req_id
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class DataCallback < Callback
|
78
|
+
include JZK::AsyncCallback::DataCallback
|
79
|
+
|
80
|
+
def processResult(rc, path, queue, data, stat)
|
81
|
+
logger.debug { "#{self.class.name}#processResult rc: #{rc}, req_id: #{req_id}, path: #{path}, queue: #{queue.inspect}, data: #{data.inspect}, stat: #{stat.inspect}" }
|
82
|
+
|
83
|
+
hash = {
|
84
|
+
:rc => rc,
|
85
|
+
:req_id => req_id,
|
86
|
+
:path => path,
|
87
|
+
:data => (data && String.from_java_bytes(data)),
|
88
|
+
:stat => (stat && stat.to_hash),
|
89
|
+
}
|
90
|
+
|
91
|
+
# if rc == Zookeeper::ZOK
|
92
|
+
# hash.merge!({
|
93
|
+
# :data => String.from_java_bytes(data),
|
94
|
+
# :stat => stat.to_hash,
|
95
|
+
# })
|
96
|
+
# end
|
97
|
+
|
98
|
+
queue.push(hash)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class StringCallback < Callback
|
103
|
+
include JZK::AsyncCallback::StringCallback
|
104
|
+
|
105
|
+
def processResult(rc, path, queue, str)
|
106
|
+
logger.debug { "#{self.class.name}#processResult rc: #{rc}, req_id: #{req_id}, path: #{path}, queue: #{queue.inspect}, str: #{str.inspect}" }
|
107
|
+
queue.push(:rc => rc, :req_id => req_id, :path => path, :string => str)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class StatCallback < Callback
|
112
|
+
include JZK::AsyncCallback::StatCallback
|
113
|
+
|
114
|
+
def processResult(rc, path, queue, stat)
|
115
|
+
logger.debug { "#{self.class.name}#processResult rc: #{rc.inspect}, req_id: #{req_id}, path: #{path.inspect}, queue: #{queue.inspect}, stat: #{stat.inspect}" }
|
116
|
+
queue.push(:rc => rc, :req_id => req_id, :stat => (stat and stat.to_hash), :path => path)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class Children2Callback < Callback
|
121
|
+
include JZK::AsyncCallback::Children2Callback
|
122
|
+
|
123
|
+
def processResult(rc, path, queue, children, stat)
|
124
|
+
logger.debug { "#{self.class.name}#processResult rc: #{rc}, req_id: #{req_id}, path: #{path}, queue: #{queue.inspect}, children: #{children.inspect}, stat: #{stat.inspect}" }
|
125
|
+
hash = {
|
126
|
+
:rc => rc,
|
127
|
+
:req_id => req_id,
|
128
|
+
:path => path,
|
129
|
+
:strings => (children && children.to_a),
|
130
|
+
:stat => (stat and stat.to_hash),
|
131
|
+
}
|
132
|
+
|
133
|
+
queue.push(hash)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
class ACLCallback < Callback
|
138
|
+
include JZK::AsyncCallback::ACLCallback
|
139
|
+
|
140
|
+
def processResult(rc, path, queue, acl, stat)
|
141
|
+
logger.debug { "ACLCallback#processResult rc: #{rc.inspect}, req_id: #{req_id}, path: #{path.inspect}, queue: #{queue.inspect}, acl: #{acl.inspect}, stat: #{stat.inspect}" }
|
142
|
+
a = Array(acl).map { |a| a.to_hash }
|
143
|
+
queue.push(:rc => rc, :req_id => req_id, :path => path, :acl => a, :stat => (stat && stat.to_hash))
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
class VoidCallback < Callback
|
148
|
+
include JZK::AsyncCallback::VoidCallback
|
149
|
+
|
150
|
+
def processResult(rc, path, queue)
|
151
|
+
logger.debug { "#{self.class.name}#processResult rc: #{rc}, req_id: #{req_id}, queue: #{queue.inspect}" }
|
152
|
+
queue.push(:rc => rc, :req_id => req_id, :path => path)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
class WatcherCallback < Callback
|
157
|
+
include JZK::Watcher
|
158
|
+
include Zookeeper::Constants
|
159
|
+
|
160
|
+
attr_reader :client
|
161
|
+
|
162
|
+
def initialize(event_queue, opts={})
|
163
|
+
@event_queue = event_queue
|
164
|
+
@client = opts[:client]
|
165
|
+
super(ZKRB_GLOBAL_CB_REQ)
|
166
|
+
end
|
167
|
+
|
168
|
+
def process(event)
|
169
|
+
hash = event.to_hash
|
170
|
+
logger.debug { "WatcherCallback got event: #{hash.inspect}" }
|
171
|
+
|
172
|
+
if client && (hash[:type] == ZOO_SESSION_EVENT) && (hash[:state] == ZOO_CONNECTED_STATE)
|
173
|
+
logger.debug { "#{self.class}##{__method__} notifying client of connected state!" }
|
174
|
+
client.notify_connected!
|
175
|
+
end
|
176
|
+
|
177
|
+
hash = event.to_hash.merge(:req_id => req_id)
|
178
|
+
@event_queue.push(hash)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
attr_reader :event_queue
|
184
|
+
|
185
|
+
def reopen(timeout=10, watcher=nil, opts = {})
|
186
|
+
@mutex.synchronize do
|
187
|
+
@req_registry.clear_watchers!
|
188
|
+
|
189
|
+
replace_jzk!(opts)
|
190
|
+
wait_until_connected(timeout)
|
191
|
+
end
|
192
|
+
|
193
|
+
state
|
194
|
+
end
|
195
|
+
|
196
|
+
def wait_until_connected(timeout=10)
|
197
|
+
@connected_latch.await(timeout) unless connected?
|
198
|
+
connected?
|
199
|
+
end
|
200
|
+
|
201
|
+
def initialize(host, timeout=10, watcher=nil, options={})
|
202
|
+
@host = host
|
203
|
+
@event_queue = QueueWithPipe.new
|
204
|
+
|
205
|
+
watcher ||= get_default_global_watcher()
|
206
|
+
|
207
|
+
@req_registry = RequestRegistry.new(watcher)
|
208
|
+
|
209
|
+
@mutex = Monitor.new
|
210
|
+
@dispatch_shutdown_cond = @mutex.new_cond
|
211
|
+
@connected_latch = Latch.new
|
212
|
+
|
213
|
+
@_running = nil
|
214
|
+
@_closed = false
|
215
|
+
@options = {}
|
216
|
+
|
217
|
+
|
218
|
+
# allows connected-state handlers to be registered before
|
219
|
+
yield self if block_given?
|
220
|
+
|
221
|
+
reopen(timeout, nil, options)
|
222
|
+
return nil unless connected?
|
223
|
+
@_running = true
|
224
|
+
setup_dispatch_thread!
|
225
|
+
end
|
226
|
+
|
227
|
+
def close
|
228
|
+
shutdown_thread = Thread.new do
|
229
|
+
@mutex.synchronize do
|
230
|
+
unless @_closed
|
231
|
+
@_closed = true # these are probably unnecessary
|
232
|
+
@_running = false
|
233
|
+
|
234
|
+
stop_dispatch_thread!
|
235
|
+
@jzk.close if @jzk
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
shutdown_thread.join unless event_dispatch_thread?
|
241
|
+
end
|
242
|
+
|
243
|
+
def state
|
244
|
+
@mutex.synchronize { @jzk.state }
|
245
|
+
end
|
246
|
+
|
247
|
+
def connected?
|
248
|
+
state == JZK::ZooKeeper::States::CONNECTED
|
249
|
+
end
|
250
|
+
|
251
|
+
def connecting?
|
252
|
+
state == JZK::ZooKeeper::States::CONNECTING
|
253
|
+
end
|
254
|
+
|
255
|
+
def associating?
|
256
|
+
state == JZK::ZooKeeper::States::ASSOCIATING
|
257
|
+
end
|
258
|
+
|
259
|
+
def running?
|
260
|
+
@_running
|
261
|
+
end
|
262
|
+
|
263
|
+
def closed?
|
264
|
+
@_closed
|
265
|
+
end
|
266
|
+
|
267
|
+
def self.set_debug_level(*a)
|
268
|
+
# IGNORED IN JRUBY
|
269
|
+
end
|
270
|
+
|
271
|
+
def set_debug_level(*a)
|
272
|
+
# IGNORED IN JRUBY
|
273
|
+
end
|
274
|
+
|
275
|
+
def get(req_id, path, callback, watcher)
|
276
|
+
handle_keeper_exception do
|
277
|
+
watch_cb = watcher ? create_watcher(req_id, path) : false
|
278
|
+
|
279
|
+
if callback
|
280
|
+
jzk.getData(path, watch_cb, JavaCB::DataCallback.new(req_id), event_queue)
|
281
|
+
[Code::Ok, nil, nil] # the 'nil, nil' isn't strictly necessary here
|
282
|
+
else # sync
|
283
|
+
stat = JZKD::Stat.new
|
284
|
+
|
285
|
+
value = jzk.getData(path, watch_cb, stat)
|
286
|
+
data = String.from_java_bytes(value) unless value.nil?
|
287
|
+
[Code::Ok, data, stat.to_hash]
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
def set(req_id, path, data, callback, version)
|
293
|
+
handle_keeper_exception do
|
294
|
+
version ||= ANY_VERSION
|
295
|
+
|
296
|
+
if callback
|
297
|
+
jzk.setData(path, data.to_java_bytes, version, JavaCB::StatCallback.new(req_id), event_queue)
|
298
|
+
[Code::Ok, nil]
|
299
|
+
else
|
300
|
+
stat = jzk.setData(path, data.to_java_bytes, version).to_hash
|
301
|
+
[Code::Ok, stat]
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
def get_children(req_id, path, callback, watcher)
|
307
|
+
handle_keeper_exception do
|
308
|
+
watch_cb = watcher ? create_watcher(req_id, path) : false
|
309
|
+
|
310
|
+
if callback
|
311
|
+
jzk.getChildren(path, watch_cb, JavaCB::Children2Callback.new(req_id), event_queue)
|
312
|
+
[Code::Ok, nil, nil]
|
313
|
+
else
|
314
|
+
stat = JZKD::Stat.new
|
315
|
+
children = jzk.getChildren(path, watch_cb, stat)
|
316
|
+
[Code::Ok, children.to_a, stat.to_hash]
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
def add_auth(req_id, scheme, cert)
|
322
|
+
handle_keeper_exception do
|
323
|
+
jzk.addAuthInfo(scheme, cert.to_java_bytes)
|
324
|
+
Code::Ok
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def create(req_id, path, data, callback, acl, flags)
|
329
|
+
handle_keeper_exception do
|
330
|
+
acl = Array(acl).map{ |a| JZKD::ACL.from_ruby_acl(a) }
|
331
|
+
mode = JZK::CreateMode.fromFlag(flags)
|
332
|
+
|
333
|
+
data ||= ''
|
334
|
+
|
335
|
+
if callback
|
336
|
+
jzk.create(path, data.to_java_bytes, acl, mode, JavaCB::StringCallback.new(req_id), event_queue)
|
337
|
+
[Code::Ok, nil]
|
338
|
+
else
|
339
|
+
new_path = jzk.create(path, data.to_java_bytes, acl, mode)
|
340
|
+
[Code::Ok, new_path]
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
def sync(req_id, path)
|
346
|
+
handle_keeper_exception do
|
347
|
+
jzk.sync(path, JavaCB::VoidCallback.new(req_id), event_queue)
|
348
|
+
Code::Ok
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
def delete(req_id, path, version, callback)
|
353
|
+
handle_keeper_exception do
|
354
|
+
if callback
|
355
|
+
jzk.delete(path, version, JavaCB::VoidCallback.new(req_id), event_queue)
|
356
|
+
else
|
357
|
+
jzk.delete(path, version)
|
358
|
+
end
|
359
|
+
|
360
|
+
Code::Ok
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
def set_acl(req_id, path, acl, callback, version)
|
365
|
+
handle_keeper_exception do
|
366
|
+
logger.debug { "set_acl: acl #{acl.inspect}" }
|
367
|
+
acl = Array(acl).flatten.map { |a| JZKD::ACL.from_ruby_acl(a) }
|
368
|
+
logger.debug { "set_acl: converted #{acl.inspect}" }
|
369
|
+
|
370
|
+
if callback
|
371
|
+
jzk.setACL(path, acl, version, JavaCB::ACLCallback.new(req_id), event_queue)
|
372
|
+
else
|
373
|
+
jzk.setACL(path, acl, version)
|
374
|
+
end
|
375
|
+
|
376
|
+
Code::Ok
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
def exists(req_id, path, callback, watcher)
|
381
|
+
handle_keeper_exception do
|
382
|
+
watch_cb = watcher ? create_watcher(req_id, path) : false
|
383
|
+
|
384
|
+
if callback
|
385
|
+
jzk.exists(path, watch_cb, JavaCB::StatCallback.new(req_id), event_queue)
|
386
|
+
[Code::Ok, nil, nil]
|
387
|
+
else
|
388
|
+
stat = jzk.exists(path, watch_cb)
|
389
|
+
[Code::Ok, (stat and stat.to_hash)]
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
def get_acl(req_id, path, callback)
|
395
|
+
handle_keeper_exception do
|
396
|
+
stat = JZKD::Stat.new
|
397
|
+
|
398
|
+
if callback
|
399
|
+
logger.debug { "calling getACL, path: #{path.inspect}, stat: #{stat.inspect}" }
|
400
|
+
jzk.getACL(path, stat, JavaCB::ACLCallback.new(req_id), event_queue)
|
401
|
+
[Code::Ok, nil, nil]
|
402
|
+
else
|
403
|
+
acls = jzk.getACL(path, stat).map { |a| a.to_hash }
|
404
|
+
|
405
|
+
[Code::Ok, Array(acls).map{|m| m.to_hash}, stat.to_hash]
|
406
|
+
end
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
def assert_open
|
411
|
+
# XXX don't know how to check for valid session state!
|
412
|
+
raise NotConnected unless connected?
|
413
|
+
end
|
414
|
+
|
415
|
+
def session_id
|
416
|
+
jzk.session_id
|
417
|
+
end
|
418
|
+
|
419
|
+
def session_passwd
|
420
|
+
jzk.session_passwd.to_s
|
421
|
+
end
|
422
|
+
|
423
|
+
# called from watcher when we are connected
|
424
|
+
# @private
|
425
|
+
def notify_connected!
|
426
|
+
@connected_latch.release
|
427
|
+
end
|
428
|
+
|
429
|
+
def pause_before_fork_in_parent
|
430
|
+
# this is a no-op in java-land
|
431
|
+
end
|
432
|
+
|
433
|
+
def resume_after_fork_in_parent
|
434
|
+
# this is a no-op in java-land
|
435
|
+
end
|
436
|
+
|
437
|
+
private
|
438
|
+
def jzk
|
439
|
+
@mutex.synchronize { @jzk }
|
440
|
+
end
|
441
|
+
|
442
|
+
# java exceptions are not wrapped anymore in JRuby 1.7+
|
443
|
+
if JRUBY_VERSION >= '1.7.0'
|
444
|
+
def handle_keeper_exception
|
445
|
+
yield
|
446
|
+
rescue JZK::KeeperException => e
|
447
|
+
# code is an enum and always set -> we don't need any additional checks here
|
448
|
+
e.code.intValue
|
449
|
+
end
|
450
|
+
else
|
451
|
+
def handle_keeper_exception
|
452
|
+
yield
|
453
|
+
rescue JZK::KeeperException => e
|
454
|
+
if e.respond_to?(:cause) and e.cause and e.cause.respond_to?(:code) and e.cause.code and e.cause.code.respond_to?(:intValue)
|
455
|
+
e.cause.code.intValue
|
456
|
+
else
|
457
|
+
raise e # dunno what happened, just raise it
|
458
|
+
end
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
def call_type(callback, watcher)
|
463
|
+
if callback
|
464
|
+
watcher ? :async_watch : :async
|
465
|
+
else
|
466
|
+
watcher ? :sync_watch : :sync
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
def create_watcher(req_id, path)
|
471
|
+
logger.debug { "creating watcher for req_id: #{req_id} path: #{path}" }
|
472
|
+
lambda do |event|
|
473
|
+
ev_type, ev_state = event.type.int_value, event.state.int_value
|
474
|
+
|
475
|
+
logger.debug { "watcher for req_id #{req_id}, path: #{path} called back" }
|
476
|
+
|
477
|
+
h = { :req_id => req_id, :type => ev_type, :state => ev_state, :path => path }
|
478
|
+
event_queue.push(h)
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
def get_default_global_watcher
|
483
|
+
Proc.new { |args|
|
484
|
+
logger.debug { "Ruby ZK Global CB called type=#{event_by_value(args[:type])} state=#{state_by_value(args[:state])}" }
|
485
|
+
true
|
486
|
+
}
|
487
|
+
end
|
488
|
+
|
489
|
+
def replace_jzk!(opts = {})
|
490
|
+
orig_jzk = @jzk
|
491
|
+
if opts.has_key?(:session_id) && opts.has_key?(:session_passwd)
|
492
|
+
@jzk = JZK::ZooKeeper.new(@host, DEFAULT_SESSION_TIMEOUT, JavaCB::WatcherCallback.new(event_queue, :client => self), opts.fetch(:session_id), opts.fetch(:session_passwd).to_java_bytes)
|
493
|
+
else
|
494
|
+
@jzk = JZK::ZooKeeper.new(@host, DEFAULT_SESSION_TIMEOUT, JavaCB::WatcherCallback.new(event_queue, :client => self))
|
495
|
+
end
|
496
|
+
ensure
|
497
|
+
orig_jzk.close if orig_jzk
|
498
|
+
end
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
module ACLs
|
3
|
+
class Id
|
4
|
+
attr_reader :scheme, :id
|
5
|
+
def initialize(hash)
|
6
|
+
@scheme = hash[:scheme]
|
7
|
+
@id = hash[:id]
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_hash
|
11
|
+
{ :id => id, :scheme => scheme }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class ACL
|
16
|
+
attr_reader :perms, :id
|
17
|
+
def initialize(hash)
|
18
|
+
@perms = hash[:perms]
|
19
|
+
v = hash[:id]
|
20
|
+
@id = v.kind_of?(Hash) ? Id.new(v) : v
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_hash
|
24
|
+
{ :perms => perms, :id => id.to_hash }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module Constants
|
29
|
+
ZOO_PERM_READ = 1 << 0
|
30
|
+
ZOO_PERM_WRITE = 1 << 1
|
31
|
+
ZOO_PERM_CREATE = 1 << 2
|
32
|
+
ZOO_PERM_DELETE = 1 << 3
|
33
|
+
ZOO_PERM_ADMIN = 1 << 4
|
34
|
+
ZOO_PERM_ALL = ZOO_PERM_READ | ZOO_PERM_WRITE | ZOO_PERM_CREATE | ZOO_PERM_DELETE | ZOO_PERM_ADMIN
|
35
|
+
|
36
|
+
ZOO_ANYONE_ID_UNSAFE = Id.new(:scheme => "world", :id => "anyone")
|
37
|
+
ZOO_AUTH_IDS = Id.new(:scheme => "auth", :id => "")
|
38
|
+
|
39
|
+
ZOO_OPEN_ACL_UNSAFE = [ACL.new(:perms => ZOO_PERM_ALL, :id => ZOO_ANYONE_ID_UNSAFE)]
|
40
|
+
ZOO_READ_ACL_UNSAFE = [ACL.new(:perms => ZOO_PERM_READ, :id => ZOO_ANYONE_ID_UNSAFE)]
|
41
|
+
ZOO_CREATOR_ALL_ACL = [ACL.new(:perms => ZOO_PERM_ALL, :id => ZOO_AUTH_IDS)]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
module Callbacks
|
3
|
+
class Base
|
4
|
+
attr_reader :proc, :completed, :context
|
5
|
+
|
6
|
+
# allows for easier construction of a user callback block that will be
|
7
|
+
# called with the callback object itself as an argument.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# Base.create do |cb|
|
12
|
+
# puts "watcher callback called with argument: #{cb.inspect}"
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# "watcher callback called with argument: #<Zookeeper::Callbacks::Base:0x1018a3958 @state=3, @type=1, ...>"
|
16
|
+
#
|
17
|
+
#
|
18
|
+
def self.create
|
19
|
+
cb_inst = new { yield cb_inst }
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@completed = false
|
24
|
+
@proc = Proc.new do |hash|
|
25
|
+
initialize_context(hash)
|
26
|
+
yield if block_given?
|
27
|
+
@completed = true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def call(*args)
|
32
|
+
@proc.call(*args)
|
33
|
+
end
|
34
|
+
|
35
|
+
def completed?
|
36
|
+
@completed
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize_context(hash)
|
40
|
+
@context = nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class WatcherCallback < Base
|
45
|
+
## wexists, awexists, wget, awget, wget_children, awget_children
|
46
|
+
attr_reader :type, :state, :path
|
47
|
+
|
48
|
+
def initialize_context(hash)
|
49
|
+
@type, @state, @path, @context = hash[:type], hash[:state], hash[:path], hash[:context]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class DataCallback < Base
|
54
|
+
## aget, awget
|
55
|
+
attr_reader :return_code, :data, :stat
|
56
|
+
|
57
|
+
def initialize_context(hash)
|
58
|
+
@return_code, @data, @stat, @context = hash[:rc], hash[:data], hash[:stat], hash[:context]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class StringCallback < Base
|
63
|
+
## acreate, async
|
64
|
+
attr_reader :return_code, :string, :context
|
65
|
+
|
66
|
+
alias path string
|
67
|
+
|
68
|
+
def initialize_context(hash)
|
69
|
+
@return_code, @string, @context = hash[:rc], hash[:string], hash[:context]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class StringsCallback < Base
|
74
|
+
## aget_children, awget_children
|
75
|
+
attr_reader :return_code, :children, :stat
|
76
|
+
|
77
|
+
def initialize_context(hash)
|
78
|
+
@return_code, @children, @stat, @context = hash[:rc], hash[:strings], hash[:stat], hash[:context]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class StatCallback < Base
|
83
|
+
## aset, aexists, awexists
|
84
|
+
attr_reader :return_code, :stat
|
85
|
+
|
86
|
+
def initialize_context(hash)
|
87
|
+
@return_code, @stat, @context = hash[:rc], hash[:stat], hash[:context]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class VoidCallback < Base
|
92
|
+
## adelete, aset_acl, add_auth
|
93
|
+
attr_reader :return_code
|
94
|
+
|
95
|
+
def initialize_context(hash)
|
96
|
+
@return_code, @context = hash[:rc], hash[:context]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class ACLCallback < Base
|
101
|
+
## aget_acl
|
102
|
+
attr_reader :return_code, :acl, :stat
|
103
|
+
def initialize_context(hash)
|
104
|
+
@return_code, @acl, @stat, @context = hash[:rc], hash[:acl], hash[:stat], hash[:context]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# figure out what platform we're on
|
2
|
+
# this way there's no ambiguity about which file to include
|
3
|
+
# or which class we're subclassing.
|
4
|
+
|
5
|
+
if defined?(::JRUBY_VERSION)
|
6
|
+
Zookeeper.require_root('java/java_base')
|
7
|
+
else
|
8
|
+
Zookeeper.require_root('ext/zookeeper_base')
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
module Zookeeper
|
13
|
+
if defined?(::JRUBY_VERSION)
|
14
|
+
class Client < Zookeeper::JavaBase
|
15
|
+
end
|
16
|
+
else
|
17
|
+
class Client < Zookeeper::ZookeeperBase
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.new(*a, &b)
|
22
|
+
Zookeeper::Client.new(*a, &b)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
Zookeeper::Client.class_eval do
|
28
|
+
include Zookeeper::ClientMethods
|
29
|
+
end
|
30
|
+
|