class SimpleRPCAction(object): def __init__(self, agent, action, config=None, stomp_client=None, autoconnect=True, **kwargs): self.agent = agent self.action = action self.config = config or Config() self.params = kwargs if self.config.connector == 'stomp': suffix = 'command' else: suffix = 'agent' self.stomp_target = "{0}.{1}".format(self.target, suffix) self.stomp_target_reply = '%s.reply' % self.target self.stomp_client = stomp_client self.signer = PROVIDERS.get(self.config.securityprovider) if self.signer: self.signer = self.signer(config) if autoconnect and not stomp_client: self.connect_stomp() @property def target(self): '''MColletive target, based on topic and collective''' collective = self.params.get('collective', self.config.main_collective) return "{topicprefix}{collective}.{agent}".format( topicprefix=self.config.topicprefix, collective=collective, agent=self.agent) def connect_stomp(self): '''Connect to stomp server''' if self.config.connector == 'stomp': key = 'stomp' elif self.config.connector == 'activemq': # FIXME(rafaduran): take advantage of multiple stomp servers key = 'activemq.pool.1' self.stomp_client = Client( self.config.pluginconf['{key}.host'.format(key=key)], int(self.config.pluginconf['{key}.port'.format(key=key)]), ) self.stomp_client.connect( self.config.pluginconf['{key}.user'.format(key=key)], self.config.pluginconf['{key}.password'.format(key=key)], ) def send(self, filter_=None, process_results=True, **kwargs): if (self.agent == 'discovery') and (self.action == 'ping'): body = 'ping' else: body = dict() body[':action'] = self.action body[':agent'] = self.agent body[':data'] = dict([(':%s' % k, v) for k, v in kwargs.items()]) body[':data'][':process_results'] = process_results collective = self.params.get('collective', self.config.main_collective) if self.signer: # body[':caller'] = self.signer.caller_id m = Message(body, self.stomp_target, filter_=filter_, agent=self.agent, identity=self.config.identity, collective=collective) self.signer.sign(m) else: m = Message(body, self.stomp_target, filter_=filter_, agent=self.agent, identity=self.config.identity, collective=collective) self.request = m.request data = safe_dump(m.request, explicit_start=True, explicit_end=False) body = "\n".join([' %s' % line for line in m.body.split("\n")]) data = data + ":body: " + body self.data = data if process_results: self.stomp_client.subscribe(self.stomp_target_reply) if self.config.connector == 'activemq': conf = {'reply-to': self.stomp_target_reply} else: conf = None self.stomp_client.put(data, self.stomp_target, conf=conf) sleep(2) self.stomp_client.unsubscribe(self.stomp_target_reply) return self.collect_results(m.rid) self.stomp_client.put(data, self.stomp_target) def collect_results(self, request_id): '''Collect the results from a previous :func:`Message.send` call. :rtype: list of STOMP messages which match this object's `:requestid` ''' results = [] while True: message = None try: message = self.stomp_client.get_nowait() except Exception, e: break decoded_message = load(message.body.replace('!ruby/sym ', ':')) if decoded_message[':requestid'] == request_id: results.append(decoded_message) return results
class SimpleRPCAction(object): def __init__(self, agent, action, config=None, stomp_client=None, autoconnect=True, **kwargs): self.agent = agent self.action = action self.config = config or Config() self.params = kwargs self.stomp_target = '%s.%s.command' % (self.config.topicprefix, agent) self.stomp_target_reply = '%s.%s.reply' % (self.config.topicprefix, agent) self.stomp_client = stomp_client self.signer = PROVIDERS.get(self.config.securityprovider) if self.signer: caller = basename(self.config.pluginconf['ssl_client_public']).split('.')[0] self.signer = self.signer( self.config.pluginconf['ssl_client_private'], caller, ) if autoconnect and not stomp_client: self.connect_stomp() def connect_stomp(self): self.stomp_client = Client( self.config.pluginconf['stomp.host'], int(self.config.pluginconf['stomp.port']), ) self.stomp_client.connect( self.config.pluginconf['stomp.user'], self.config.pluginconf['stomp.password'], ) def send(self, filter_=None, process_results=True, **kwargs): body = dict() body[':action'] = self.action body[':agent'] = self.agent body[':data'] = dict([(':%s' % k, v) for k, v in kwargs.items()]) body[':data'][':process_results'] = process_results m = Message(body, self.stomp_target, filter_=filter_) if self.signer: self.signer.sign(m) data = safe_dump(m.request, explicit_start=True, explicit_end=False) body = "\n".join([' %s' % line for line in m.body.split("\n")]) data = data + ":body: |\n" + body self.data = data if process_results: self.stomp_client.subscribe(self.stomp_target_reply) self.stomp_client.put(data, self.stomp_target) sleep(2) self.stomp_client.unsubscribe(self.stomp_target_reply) return self.collect_results(m.rid) self.stomp_client.put(data, self.stomp_target) def collect_results(self, request_id): '''Collect the results from a previous :func:`Message.send` call. :rtype: list of STOMP messages which match this object's `:requestid`''' results = [] while True: message = None try: message = self.stomp_client.get_nowait() except Exception, e: break decoded_message = load(message.body.replace('!ruby/sym ', ':')) if decoded_message[':requestid'] == request_id: results.append(decoded_message) return results
class WhenUsingSimpleClient(DingusTestCase(Client, exclude=['TransactionError', 'Empty'])): def setup(self): super(WhenUsingSimpleClient, self).setup() self.client = Client() def should_connect(self): self.client.connect() assert self.client.stomp.calls('connect') def should_disconnect(self): self.client.disconnect() assert self.client.stomp.calls('disconnect') def should_subscribe(self): self.client.subscribe('/queue/nose_test') print self.client.stomp.calls assert self.client.stomp.calls('subscribe', {'ack': 'auto', 'destination': '/queue/nose_test'}) def should_unsubscribe(self): self.client.unsubscribe('/queue/nose_test') assert self.client.stomp.calls('unsubscribe', {'destination': '/queue/nose_test'}) def should_begin_transaction(self): self.client.begin('bah') assert self.client.stomp.calls('begin', {"transaction": self.client._current_transaction}) def should_fail_to_begin_already_in_transaction(self): self.client._current_transaction = "meh" nose_tools.assert_raises(TransactionError, self.client.begin, 'bah') def should_commit_transaction(self): self.client._current_transaction = 'meh' self.client.commit('bah') assert self.client.stomp.calls('commit', {'transaction': 'meh'}) def should_fail_to_commit_transaction(self): nose_tools.assert_raises(TransactionError, self.client.commit, 'bah') def should_abort_transaction(self): self.client._current_transaction = 'meh' self.client.abort() assert self.client.stomp.calls('abort', {'transaction': 'meh'}) def should_fail_to_abort_transaction(self): nose_tools.assert_raises(TransactionError, self.client.abort) def should_ack_message(self): self.client.ack("fake_frame") assert self.client.stomp.calls('ack', "fake_frame") def should_make_conf(self): conf = self.client._make_conf(None, destination='/queue/nose_test', ack='auto') assert isinstance(conf, type({})) def should_make_conf_with_transaction(self): self.client._current_transaction = 'meh' conf = self.client._make_conf({}, destination='/queue/nose_test', ack='auto') assert isinstance(conf, type({})) def should_put_item_into_queue(self): self.client.put('bah', '/queue/nose_test') conf = self.client._make_conf(None, body='bah', destination='/queue/nose_test', persistent='true') assert self.client.stomp.calls('send', conf) def should_get_message(self): self.client.get() assert self.client.stomp.calls('receive_frame', nonblocking=False, callback=None) def should_get_message_without_blocking(self): self.client.get_nowait() assert self.client.stomp.calls('receive_frame', nonblocking=True, callback=None) def should_not_get_message(self): self.client.stomp.receive_frame.return_value = None nose_tools.assert_raises(self.client.Empty, self.client.get, block=False)
'fact': [], 'agent': [], 'cf_class': [], } r[":requestid"] = rid r[":callerid"] = 'cert=%s' % CERTNAME r[":senderid"] = 'pythontest' r[":msgtarget"] = target r[':body'] = yaml.dump('ping') h = rr.sign(sha1(r[':body']).digest(), 'sha1') r[':hash'] = h.encode('base64').replace("\n", "").strip() data = yaml.dump(r) s.put(data, target) time.sleep(2) results = [] while True: x = None try: x = s.get_nowait() print x except: break if not x: break y = yaml.load(x.body) print y if y[':requestid'] == rid: results.append(y) print [q[':senderid'] for q in results]