diff options
Diffstat (limited to 'cpp/bindings/qmf')
| -rw-r--r-- | cpp/bindings/qmf/qmfengine.i | 4 | ||||
| -rw-r--r-- | cpp/bindings/qmf/ruby/qmf.rb | 298 | ||||
| -rwxr-xr-x | cpp/bindings/qmf/tests/agent_ruby.rb | 10 | ||||
| -rwxr-xr-x | cpp/bindings/qmf/tests/python_console.py | 12 | ||||
| -rwxr-xr-x | cpp/bindings/qmf/tests/ruby_console.rb | 43 | ||||
| -rwxr-xr-x | cpp/bindings/qmf/tests/run_interop_tests | 13 |
6 files changed, 338 insertions, 42 deletions
diff --git a/cpp/bindings/qmf/qmfengine.i b/cpp/bindings/qmf/qmfengine.i index 8ae28730e5..d3500c9b8f 100644 --- a/cpp/bindings/qmf/qmfengine.i +++ b/cpp/bindings/qmf/qmfengine.i @@ -20,7 +20,8 @@ %{ #include "qmf/AgentEngine.h" -#include <qmf/ResilientConnection.h> +#include "qmf/ConsoleEngine.h" +#include "qmf/ResilientConnection.h" %} @@ -28,6 +29,7 @@ %include <qmf/Query.h> %include <qmf/Message.h> %include <qmf/AgentEngine.h> +%include <qmf/ConsoleEngine.h> %include <qmf/ConnectionSettings.h> %include <qmf/ResilientConnection.h> %include <qmf/Typecode.h> diff --git a/cpp/bindings/qmf/ruby/qmf.rb b/cpp/bindings/qmf/ruby/qmf.rb index badd53942d..38c42b5aa7 100644 --- a/cpp/bindings/qmf/ruby/qmf.rb +++ b/cpp/bindings/qmf/ruby/qmf.rb @@ -20,6 +20,7 @@ require 'qmfengine' require 'thread' require 'socket' +require 'monitor' module Qmf @@ -70,39 +71,18 @@ module Qmf def sess_event_recv(context, message); end end - class Query - attr_reader :impl - def initialize(i) - @impl = i - end - - def package_name - @impl.getPackage - end - - def class_name - @impl.getClass - end - - def object_id - objid = @impl.getObjectId - if objid.class == NilClass - return nil - end - return ObjectId.new(objid) - end - end - class Connection + include MonitorMixin + attr_reader :impl def initialize(settings) + super() @impl = Qmfengine::ResilientConnection.new(settings.impl) @sockEngine, @sock = Socket::socketpair(Socket::PF_UNIX, Socket::SOCK_STREAM, 0) @impl.setNotifyFd(@sockEngine.fileno) @new_conn_handlers = Array.new @conn_handlers = Array.new - @sess_handlers = Array.new @thread = Thread.new do run @@ -110,47 +90,56 @@ module Qmf end def add_conn_handler(handler) - @new_conn_handlers.push(handler) + synchronize do + @new_conn_handlers.push(handler) + end @sockEngine.write("x") end - def add_sess_handler(handler) - @sess_handlers.push(handler) - end - def run() - event = Qmfengine::ResilientConnectionEvent.new + eventImpl = Qmfengine::ResilientConnectionEvent.new connected = nil + new_handlers = nil + bt_count = 0 + while :true @sock.read(1) - @new_conn_handlers.each do |nh| + synchronize do + new_handlers = @new_conn_handlers + @new_conn_handlers = Array.new + end + + new_handlers.each do |nh| @conn_handlers.push(nh) nh.conn_event_connected() if connected end - @new_conn_handlers = Array.new + new_handlers = nil - valid = @impl.getEvent(event) + valid = @impl.getEvent(eventImpl) while valid begin - case event.kind + case eventImpl.kind when Qmfengine::ResilientConnectionEvent::CONNECTED connected = :true @conn_handlers.each { |h| h.conn_event_connected() } when Qmfengine::ResilientConnectionEvent::DISCONNECTED connected = nil - @conn_handlers.each { |h| h.conn_event_disconnected(event.errorText) } + @conn_handlers.each { |h| h.conn_event_disconnected(eventImpl.errorText) } when Qmfengine::ResilientConnectionEvent::SESSION_CLOSED - event.sessionContext.handler.sess_event_session_closed(event.sessionContext, event.errorText) + eventImpl.sessionContext.handler.sess_event_session_closed(eventImpl.sessionContext, eventImpl.errorText) when Qmfengine::ResilientConnectionEvent::RECV - event.sessionContext.handler.sess_event_recv(event.sessionContext, event.message) + eventImpl.sessionContext.handler.sess_event_recv(eventImpl.sessionContext, eventImpl.message) end rescue Exception => ex puts "Event Exception: #{ex}" - puts ex.backtrace + if bt_count < 2 + puts ex.backtrace + bt_count += 1 + end end @impl.popEvent - valid = @impl.getEvent(event) + valid = @impl.getEvent(eventImpl) end end end @@ -164,9 +153,12 @@ module Qmf @label = label @handler = handler @handle = Qmfengine::SessionHandle.new - @conn.add_sess_handler(@handler) result = @conn.impl.createSession(label, self, @handle) end + + def destroy() + @conn.impl.destroySession(@handle) + end end ##============================================================================== @@ -262,6 +254,30 @@ module Qmf end end + class ConsoleObject < QmfObject + attr_reader :current_time, :create_time, :delete_time + + def initialize(cls) + super(cls) + end + + def update() + end + + def mergeUpdate(newObject) + end + + def deleted?() + @delete_time > 0 + end + + def index() + end + + def method_missing(name, *args) + end + end + class ObjectId attr_reader :impl def initialize(impl=nil) @@ -357,6 +373,29 @@ module Qmf end end + class Query + attr_reader :impl + def initialize(i) + @impl = i + end + + def package_name + @impl.getPackage + end + + def class_name + @impl.getClass + end + + def object_id + objid = @impl.getObjectId + if objid.class == NilClass + return nil + end + return ObjectId.new(objid) + end + end + ##============================================================================== ## SCHEMA ##============================================================================== @@ -410,6 +449,21 @@ module Qmf end end + class SchemaClassKey + attr_reader :impl + def initialize(i) + @impl = i + end + + def get_package() + @impl.getPackageName() + end + + def get_class() + @impl.getClassName() + end + end + class SchemaObjectClass attr_reader :impl def initialize(package, name, kwargs={}) @@ -467,6 +521,170 @@ module Qmf ## CONSOLE ##============================================================================== + class ConsoleHandler + def agent_added(agent); end + def agent_deleted(agent); end + def new_package(package); end + def new_class(class_key); end + def object_update(object, hasProps, hasStats); end + def event_received(event); end + def agent_heartbeat(agent, timestamp); end + def method_response(resp); end + def broker_info(broker); end + end + + class Console + attr_reader :impl + + def initialize(handler, kwargs={}) + @handler = handler + @impl = Qmfengine::ConsoleEngine.new + @event = Qmfengine::ConsoleEvent.new + @broker_list = Array.new + end + + def add_connection(conn) + broker = Broker.new(self, conn) + @broker_list.push(broker) + return broker + end + + def del_connection(broker) + end + + def get_packages() + end + + def get_classes(package) + end + + def get_schema(class_key) + end + + def bind_package(package) + end + + def bind_class(kwargs = {}) + end + + def get_agents(broker = nil) + end + + def get_objects(query, kwargs = {}) + end + + def start_sync(query) + end + + def touch_sync(sync) + end + + def end_sync(sync) + end + + def do_console_events() + count = 0 + valid = @impl.getEvent(@event) + while valid + count += 1 + case @event.kind + when Qmfengine::ConsoleEvent::AGENT_ADDED + when Qmfengine::ConsoleEvent::AGENT_DELETED + when Qmfengine::ConsoleEvent::NEW_PACKAGE + when Qmfengine::ConsoleEvent::NEW_CLASS + when Qmfengine::ConsoleEvent::OBJECT_UPDATE + when Qmfengine::ConsoleEvent::EVENT_RECEIVED + when Qmfengine::ConsoleEvent::AGENT_HEARTBEAT + when Qmfengine::ConsoleEvent::METHOD_RESPONSE + end + @impl.popEvent + valid = @impl.getEvent(@event) + end + return count + end + end + + class Broker < ConnectionHandler + attr_reader :impl + + def initialize(console, conn) + @console = console + @conn = conn + @session = nil + @event = Qmfengine::BrokerEvent.new + @xmtMessage = Qmfengine::Message.new + @impl = Qmfengine::BrokerProxy.new(@console.impl) + @console.impl.addConnection(@impl, self) + @conn.add_conn_handler(self) + end + + def do_broker_events() + count = 0 + valid = @impl.getEvent(@event) + while valid + count += 1 + puts "Broker Event: #{@event.kind}" + case @event.kind + when Qmfengine::BrokerEvent::BROKER_INFO + when Qmfengine::BrokerEvent::DECLARE_QUEUE + @conn.impl.declareQueue(@session.handle, @event.name) + when Qmfengine::BrokerEvent::DELETE_QUEUE + @conn.impl.deleteQueue(@session.handle, @event.name) + when Qmfengine::BrokerEvent::BIND + @conn.impl.bind(@session.handle, @event.exchange, @event.name, @event.bindingKey) + when Qmfengine::BrokerEvent::UNBIND + @conn.impl.unbind(@session.handle, @event.exchange, @event.name, @event.bindingKey) + when Qmfengine::BrokerEvent::SETUP_COMPLETE + @impl.startProtocol + end + @impl.popEvent + valid = @impl.getEvent(@event) + end + return count + end + + def do_broker_messages() + count = 0 + valid = @impl.getXmtMessage(@xmtMessage) + while valid + count += 1 + @conn.impl.sendMessage(@session.handle, @xmtMessage) + @impl.popXmt + valid = @impl.getXmtMessage(@xmtMessage) + end + return count + end + + def do_events() + begin + ccnt = @console.do_console_events + bcnt = do_broker_events + mcnt = do_broker_messages + end until ccnt == 0 and bcnt == 0 and mcnt == 0 + end + + def conn_event_connected() + puts "Console Connection Established..." + @session = Session.new(@conn, "qmfc-%s.%d" % [Socket.gethostname, Process::pid], self) + @impl.sessionOpened(@session.handle) + do_events + end + + def conn_event_disconnected(error) + puts "Console Connection Lost" + end + + def sess_event_session_closed(context, error) + puts "Console Session Lost" + @impl.sessionClosed() + end + + def sess_event_recv(context, message) + @impl.handleRcvMessage(message) + do_events + end + end + ##============================================================================== ## AGENT ##============================================================================== diff --git a/cpp/bindings/qmf/tests/agent_ruby.rb b/cpp/bindings/qmf/tests/agent_ruby.rb index 0f85c90f37..75de2b5fa1 100755 --- a/cpp/bindings/qmf/tests/agent_ruby.rb +++ b/cpp/bindings/qmf/tests/agent_ruby.rb @@ -53,7 +53,10 @@ class Model method = Qmf::SchemaMethod.new("create_child", :desc => "Create a new child object") method.add_argument(Qmf::SchemaArgument.new("child_name", Qmf::TYPE_LSTR, :dir => Qmf::DIR_IN)) method.add_argument(Qmf::SchemaArgument.new("child_ref", Qmf::TYPE_REF, :dir => Qmf::DIR_OUT)) + @parent_class.add_method(method) + method = Qmf::SchemaMethod.new("probe_userid", :desc => "Return the user-id for this method call") + method.add_argument(Qmf::SchemaArgument.new("userid", Qmf::TYPE_SSTR, :dir => Qmf::DIR_OUT)) @parent_class.add_method(method) @child_class = Qmf::SchemaObjectClass.new("org.apache.qpid.qmf", "child") @@ -136,6 +139,13 @@ class App < Qmf::AgentHandler @child.set_attr("name", args.by_key("child_name")) @child.set_object_id(oid) @agent.method_response(context, 0, "OK", args) + + elsif name == "probe_userid" + args['userid'] = userId + @agent.method_response(context, 0, "OK", args) + + else + @agent.method_response(context, 1, "Unimplemented Method: #{name}", args) end end diff --git a/cpp/bindings/qmf/tests/python_console.py b/cpp/bindings/qmf/tests/python_console.py index 365f2ac33a..bcd3063fe3 100755 --- a/cpp/bindings/qmf/tests/python_console.py +++ b/cpp/bindings/qmf/tests/python_console.py @@ -128,6 +128,18 @@ class QmfInteropTests(TestBase010): self.assertEqual(parent.int16val, -1000) self.assertEqual(parent.int8val, -100) + def test_D_userid_for_method(self): + self.startQmf(); + qmf = self.qmf + + parents = qmf.getObjects(_class="parent") + self.assertEqual(len(parents), 1) + parent = parents[0] + + result = parent.probe_userid() + self.assertEqual(result.status, 0) + self.assertEqual(result.userid, "guest") + def getProperty(self, msg, name): for h in msg.headers: if hasattr(h, name): return getattr(h, name) diff --git a/cpp/bindings/qmf/tests/ruby_console.rb b/cpp/bindings/qmf/tests/ruby_console.rb new file mode 100755 index 0000000000..c7ee9c3686 --- /dev/null +++ b/cpp/bindings/qmf/tests/ruby_console.rb @@ -0,0 +1,43 @@ +#!/usr/bin/ruby + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +require 'qmf' +require 'socket' + +class App < Qmf::ConsoleHandler + + def main + @settings = Qmf::ConnectionSettings.new + @settings.set_attr("host", ARGV[0]) if ARGV.size > 0 + @settings.set_attr("port", ARGV[1].to_i) if ARGV.size > 1 + @connection = Qmf::Connection.new(@settings) + @qmf = Qmf::Console.new(self) + + @qmf.add_connection(@connection) + + sleep + end +end + +app = App.new +app.main + + diff --git a/cpp/bindings/qmf/tests/run_interop_tests b/cpp/bindings/qmf/tests/run_interop_tests index e6fc872dbb..f3f78185c7 100755 --- a/cpp/bindings/qmf/tests/run_interop_tests +++ b/cpp/bindings/qmf/tests/run_interop_tests @@ -54,12 +54,23 @@ if test -d ${PYTHON_DIR} ; then echo "Running qmf interop tests using broker on port $BROKER_PORT" PYTHONPATH=${PYTHON_DIR}:${MY_DIR} export PYTHONPATH - echo " Ruby Agent vs. Pure-Python Console" + echo " Ruby Agent (external storage) vs. Pure-Python Console" start_ruby_agent echo " Ruby agent started at pid $AGENT_PID" ${PYTHON_DIR}/qpid-python-test -m python_console -b localhost:$BROKER_PORT $@ RETCODE=$? stop_ruby_agent + + # Also against the Pure-Python console: + # Ruby agent (internal storage) + # Python agent (external and internal) + # C++ agent (external and internal) + # + # Other consoles against the same set of agents: + # Wrapped Python console + # Ruby console + # C++ console + stop_broker if test x$RETCODE != x0; then echo "FAIL qmf interop tests"; exit 1; |
