class StompCLI(ConnectionListener): def __init__(self, host='localhost', port=61613, user='', passcode=''): self.c = Connection([(host, port)], user, passcode) self.c.set_listener('', self) self.c.start() def __print_async(self, frame_type, headers, body): print "\r \r", print frame_type for header_key in headers.keys(): print '%s: %s' % (header_key, headers[header_key]) print print body print '> ', sys.stdout.flush() def on_connecting(self, host_and_port): self.c.connect(wait=True) def on_disconnected(self, headers, body)
from stomp import Connection import sys hostname = sys.argv[1] class MessageListener: def on_message(self, headers, message): print "Got message %s" % message c = Connection([(hostname, 61613)]) c.set_listener('', MessageListener()) c.start() c.connect() c.subscribe(destination='/topic/postprocessing.mapmerge.out', ack='auto') f = open('example.xml', 'rb').read() c.send(f, destination='/queue/postprocessing.mapmerge.erfurt.in') print 'sent' import time time.sleep(1)
class Volare(object): # Construtor simplificado, similar ao usado em Java # Note que broker deve ser uma url do tipo "stomp://host:port[/]", # que será decodificada para isolar o host e a porta usados pelo stomppy def __init__(self, user, password, broker): self.user = user self.password = password if not broker: raise ValueError(u"A url do broker é obrigatória.") if not broker.startswith("stomp://"): raise ValueError(u"A url do broker deve usar 'stomp://'.") # como broker é da forma 'stomp://hostname:porta[/]', pode remover # o prefixo, desprezar a '/' opcional no final e separar no ':' self.host, dummy, strport = broker[8:].rstrip('/').partition(':') if len(self.host) == 0 or not strport.isdigit(): raise ValueError(u"O host e a porta do broker são obrigatórios.") self.port = int(strport) def connect(self): try: self._connection = Connection([(self.host, self.port)], self.user, self.password) self._connection.start() self._connection.connect(wait=True) except ConnectFailedException, err: raise OfflineBrokerError("Failed to connect to the broker at stomp://%s:%s/" % (self.host, self.port) )
class ProtArchive(ProtProcessMovies): """ Sends a message to the dials archiving queue """ _label = 'DLS Archive' def _defineParams(self, form): form.addSection(label='Params') group = form.addGroup('Message Queue') group.addParam('queueHost', params.StringParam, label="Host", important=True, help='The host name for a queue broker (e.g. activemq)') group.addParam('queuePort', params.IntParam, label="Port", important=True, default=61613, help='The stomp port for a queue broker (e.g. activemq)') group.addParam('queueName', params.StringParam, label='Queue Name', help='The name of the queue within the broker') group.addParam('dropFileDir', params.FolderParam, label='Dropfile dir', help='The location of the dropfile dir') def processMovieStep(self, movieDict, hasAlignment): SCIPION_HOME = os.environ['SCIPION_HOME'] LOGFILE = os.path.join(SCIPION_HOME, 'pyworkflow', 'em', 'packages','dls','archive_recipe.json') with open(LOGFILE) as recipe: recipe_data = json.load(recipe) real_path = os.path.realpath(movieDict['_filename']) self._setValues(recipe_data, 'files', [real_path ]) self._setValues(recipe_data, 'dropfile-dir', dropFileDir) json_data = json.dumps(recipe_data) self._sendMessage(json_data) def _setValues(self, data, key, value): for k in data: if k == key: data[k] = value elif type(data[k]) is dict: self._setValues(data[k], key, value) def _sendMessage(self, json_data): # type: (str) -> void try: try: from stomp import Connection except ImportError as ex: print "You need stomp to run the archiver, run 'scipion run pip stomp.py' first" raise ex self.connection.send(self.queue_name, json_data) except AttributeError: self.connection = Connection([(self.queueHost, self.queuePort)]) self.connection.connect(wait=True) self._sendMessage(json_data) def createOutputStep(self): pass
def connect(self): try: self._connection = Connection([(self.host, self.port)], self.user, self.password) self._connection.start() self._connection.connect(wait=True) except ConnectFailedException, err: raise OfflineBrokerError("Failed to connect to the broker at stomp://%s:%s/" % (self.host, self.port) )
def _sendMessage(self, json_data): # type: (str) -> void try: try: from stomp import Connection except ImportError as ex: print "You need stomp to run the archiver, run 'scipion run pip stomp.py' first" raise ex self.connection.send(self.queue_name, json_data) except AttributeError: self.connection = Connection([(self.queueHost, self.queuePort)]) self.connection.connect(wait=True) self._sendMessage(json_data)
def __init__(self, host='localhost', port=61613, user='', passcode=''): self.c = Connection([(host, port)], user, passcode) self.c.set_listener('', self) self.c.start()
class StompCLI(ConnectionListener): def __init__(self, host='localhost', port=61613, user='', passcode=''): self.c = Connection([(host, port)], user, passcode) self.c.set_listener('', self) self.c.start() def __print_async(self, frame_type, headers, body): print "\r \r", print frame_type for header_key in headers.keys(): print '%s: %s' % (header_key, headers[header_key]) print print body print '> ', sys.stdout.flush() def on_connecting(self, host_and_port): self.c.connect(wait=True) def on_disconnected(self): print "lost connection" def on_message(self, headers, body): self.__print_async("MESSAGE", headers, body) def on_error(self, headers, body): self.__print_async("ERROR", headers, body) def on_receipt(self, headers, body): self.__print_async("RECEIPT", headers, body) def on_connected(self, headers, body): print 'connected' self.__print_async("CONNECTED", headers, body) def ack(self, args): ''' Usage: ack <message-id> [transaction-id] Required Parameters: message-id - the id of the message being acknowledged Optional Parameters: transaction-id - the acknowledgement should be a part of the named transaction Description: The command 'ack' is used to acknowledge consumption of a message from a subscription using client acknowledgment. When a client has issued a 'subscribe' with the ack flag set to client, any messages received from that destination will not be considered to have been consumed (by the server) until the message has been acknowledged. ''' if len(args) < 3: self.c.ack(message_id=args[1]) else: self.c.ack(message_id=args[1], transaction=args[2]) def abort(self, args): ''' Usage: abort <transaction-id> Required Parameters: transaction-id - the transaction to abort Description: Roll back a transaction in progress. ''' self.c.abort(transaction=args[1]) def begin(self, args): ''' Usage: begin Description: Start a transaction. Transactions in this case apply to sending and acknowledging - any messages sent or acknowledged during a transaction will be handled atomically based on the transaction. ''' print 'transaction id: %s' % self.c.begin() def commit(self, args): ''' Usage: commit <transaction-id> Required Parameters: transaction-id - the transaction to commit Description: Commit a transaction in progress. ''' if len(args) < 2: print 'expecting: commit <transid>' else: print 'committing %s' % args[1] self.c.commit(transaction=args[1]) def disconnect(self, args): ''' Usage: disconnect Description: Gracefully disconnect from the server. ''' try: self.c.disconnect() except NotConnectedException: pass # ignore if no longer connected def send(self, args): ''' Usage: send <destination> <message> Required Parameters: destination - where to send the message message - the content to send Description: Sends a message to a destination in the messaging system. ''' if len(args) < 3: print 'expecting: send <destination> <message>' else: self.c.send(destination=args[1], message=' '.join(args[2:])) def sendreply(self, args): ''' Usage: sendreply <destination> <correlation-id> <message> Required Parameters: destination - where to send the message correlation-id - the correlating identifier to send with the response message - the content to send Description: Sends a reply message to a destination in the messaging system. ''' if len(args) < 4: print 'expecting: sendreply <destination> <correlation-id> <message>' else: self.c.send(destination=args[1], message="%s\n" % ' '.join(args[3:]), headers={'correlation-id': args[2]}) def sendtrans(self, args): ''' Usage: sendtrans <destination> <transaction-id> <message> Required Parameters: destination - where to send the message transaction-id - the id of the transaction in which to enlist this message message - the content to send Description: Sends a message to a destination in the message system, using a specified transaction. ''' if len(args) < 3: print 'expecting: sendtrans <destination> <transaction-id> <message>' else: self.c.send(destination=args[1], message="%s\n" % ' '.join(args[3:]), transaction=args[2]) def subscribe(self, args): ''' Usage: subscribe <destination> [ack] Required Parameters: destination - the name to subscribe to Optional Parameters: ack - how to handle acknowledgements for a message; either automatically (auto) or manually (client) Description: Register to listen to a given destination. Like send, the subscribe command requires a destination header indicating which destination to subscribe to. The ack parameter is optional, and defaults to auto. ''' if len(args) < 2: print 'expecting: subscribe <destination> [ack]' elif len(args) > 2: print 'subscribing to "%s" with acknowledge set to "%s"' % (args[1], args[2]) self.c.subscribe(destination=args[1], ack=args[2]) else: print 'subscribing to "%s" with auto acknowledge' % args[1] self.c.subscribe(destination=args[1], ack='auto') def unsubscribe(self, args): ''' Usage: unsubscribe <destination> Required Parameters: destination - the name to unsubscribe from Description: Remove an existing subscription - so that the client no longer receive messages from that destination. ''' if len(args) < 2: print 'expecting: unsubscribe <destination>' else: print 'unsubscribing from "%s"' % args[1] self.c.unsubscribe(destination=args[1]) def stats(self, args): ''' Usage: stats [on|off] Description: Record statistics on messages sent, received, errors, etc. If no argument (on|off) is specified, dump the current statistics. ''' if len(args) < 2: stats = self.c.get_listener('stats') if stats: print stats else: print 'No stats available' elif args[1] == 'on': self.c.set_listener('stats', StatsListener()) elif args[1] == 'off': self.c.remove_listener('stats') else: print 'expecting: stats [on|off]' def help(self, args): ''' Usage: help [command] Description: Display info on a specified command, or a list of available commands ''' if len(args) == 1: print 'Usage: help <command>, where command is one of the following:' print ' ' for f in dir(self): if f.startswith('_') or f.startswith('on_') or f == 'c': continue else: print '%s ' % f, print '' return elif not hasattr(self, args[1]): print 'There is no command "%s"' % args[1] return func = getattr(self, args[1]) if hasattr(func, '__doc__') and getattr(func, '__doc__') is not None: print func.__doc__ else: print 'There is no help for command "%s"' % args[1]
def test_subscribe_send_Topic(self): class MyListener(): def __init__(self): #hosts = [('127.0.0.1', 61613)] #conn = Connection(host_and_ports=hosts) #self.conn = conn print("MyListener __init__") def on_error(self, message): print('received an error "%s"' % message) def on_message(self, message): print('received a message on topic "%s"' % message) TestMQ.topic_messageReceived.append(message) for x in range(2): print(x) time.sleep(1) def on_disconnected(self): print('disconnected') #connect_and_subscribe(self.conn) print("test_subscribe_send_Topic()") hosts = [('127.0.0.1', 61613)] conn1 = Connection(host_and_ports=hosts) conn2 = Connection(host_and_ports=hosts) topic_listener1 = MyListener topic_listener2 = MyListener conn1.set_listener('', topic_listener1) conn2.set_listener('', topic_listener2) conn1.connect('admin', 'admin', wait=True) conn2.connect('admin', 'admin', wait=True) conn1.subscribe(destination='/topic/restdemo_topic', id=1, ack='auto') conn2.subscribe(destination='/topic/restdemo_topic', id=1, ack='auto') conn1.send(body='This is a message sent to restdemo_topic from test case', destination='/topic/restdemo_topic') time.sleep(4) conn1.disconnect() conn2.disconnect() #for i in range( len(TestMQ.topic_messageReceived)): #print("TestMQ.messageReceived = " + TestMQ.topic_messageReceived[i]) self.assertEqual(len(TestMQ.topic_messageReceived), 2)
class ActiveMQListener: def __init__(self): self.topic_public_calc = None self.topic_public_utf_antenna = None self.topic_communication = None self.topic_satellite_manager = None self.topic_active_mq_writer = None self.connection = None def __delete__(self, instance): if self.connection is not None: print('Closing MQ in connection') self.connection.disconnect() def publish_to_public_calc(self, message): try: request = Flyover_request() request.request_id = message['request_id'] request.action = message['action'] request.satellite_ids = message['data']['satellite_ids'] request.long = message['data']['lon'] request.lat = message['data']['lat'] request.elevation = message['data']['elevation'] rospy.loginfo( str(datetime.datetime.now()) + ': ActiveMQListener publish to public calc: ' + str(request)) self.topic_public_calc.publish(request) except Exception as ex: rospy.logerr( str(datetime.datetime.now()) + ': request ID: ' + message['request_id'] + ' ' + str(ex)) self.publish_exception(message['request_id'], str(ex)) def publish_to_public_utf_antenna(self, message): try: request = UTF_antenna_command() request.request_id = message['request_id'] request.action = message['action'] if message['elevation'] is not None: request.elevation = message['elevation'] if message['azimuth'] is not None: request.azimuth = message['azimuth'] rospy.loginfo( str(datetime.datetime.now()) + ': ActiveMQListener publish to utf antenna: ' + str(request)) self.topic_public_utf_antenna.publish(request) except Exception as ex: rospy.logerr( str(datetime.datetime.now()) + ': request ID: ' + message['request_id'] + ' ' + str(ex)) self.publish_exception(message['request_id'], str(ex)) def publish_to_communication(self, message): try: request = Communication_package() request.request_id = message['request_id'] request.data = message['data'] rospy.loginfo( str(datetime.datetime.now()) + ': ActiveMQListener publish to satellite communication: ' + str(request)) self.topic_communication.publish(request) except Exception as ex: rospy.logerr( str(datetime.datetime.now()) + ': request ID: ' + message['request_id'] + ' ' + str(ex)) self.publish_exception(message['request_id'], str(ex)) def publish_to_satellite_manager(self, message): try: request = Satellite_manager_command() request.request_id = message['request_id'] request.action = message['action'] if message['satellite_ids'] is not None: request.satellite_ids = message['satellite_ids'] rospy.loginfo( str(datetime.datetime.now()) + ': ActiveMQListener publish to satellite manager: ' + str(request)) self.topic_satellite_manager.publish(request) except Exception as ex: rospy.logerr( str(datetime.datetime.now()) + ': request ID: ' + message['request_id'] + ' ' + str(ex)) self.publish_exception(message['request_id'], [str(ex)]) def publish_exception(self, request_id, message): response = Response() response.request_id = request_id response.ok = False response.data = [message] rospy.loginfo( str(datetime.datetime.now()) + ': ActiveMQListener publish exception: ' + str(response)) self.topic_active_mq_writer.publish(response) def connect_to_mq(self): rospy.loginfo( str(datetime.datetime.now()) + ': Connecting to ActiveMQ') self.connection = Connection( host_and_ports=[(AntennaConstants.ACTIVE_MQ_HOST, AntennaConstants.ACTIVE_MQ_PORT)]) self.connection.set_listener('my_listener', ActiveMQConnectionListener(self)) self.connection.start() self.connection.connect(AntennaConstants.ACTIVE_MQ_USER, AntennaConstants.ACTIVE_MQ_PASS, wait=True) self.connection.subscribe( destination=AntennaConstants.ACTIVE_MQ_TOPIC_IN, id=1, ack='auto') def start(self): print('Starting ActiveMQListener') self.topic_public_calc = rospy.Publisher( TopicConstants.TOPIC_PUBLIC_CALC, Flyover_request, queue_size=TopicConstants.QUEUE_SIZE) self.topic_public_utf_antenna = rospy.Publisher( TopicConstants.TOPIC_PUBLIC_UTF_ANTENNA, UTF_antenna_command, queue_size=TopicConstants.QUEUE_SIZE) self.topic_communication = rospy.Publisher( TopicConstants.TOPIC_COMMUNICATION, Communication_package, queue_size=TopicConstants.QUEUE_SIZE) self.topic_satellite_manager = rospy.Publisher( TopicConstants.TOPIC_SATELLITE_MANAGER, Satellite_manager_command, queue_size=TopicConstants.QUEUE_SIZE) self.topic_active_mq_writer = rospy.Publisher( TopicConstants.TOPIC_ACTIVE_MQ_WRITER, Response, queue_size=TopicConstants.QUEUE_SIZE) rospy.init_node(TopicConstants.TOPIC_ACTIVE_MQ_LISTENER, anonymous=False) self.connect_to_mq()
def verify_destination_metrics_collection(self, destination_type): from stomp import Connection self.render_config_template( modules=[self.get_activemq_module_config(destination_type)]) proc = self.start_beat(home=self.beat_path) destination_name = ''.join( random.choice(string.ascii_lowercase) for i in range(10)) conn = Connection([self.get_stomp_host_port()]) conn.start() conn.connect(wait=True) conn.send('/{}/{}'.format(destination_type, destination_name), 'first message') conn.send('/{}/{}'.format(destination_type, destination_name), 'second message') self.wait_until(lambda: self.destination_metrics_collected( destination_type, destination_name)) proc.check_kill_and_wait() self.assert_no_logged_warnings() output = self.read_output_json() passed = False for evt in output: if self.all_messages_enqueued(evt, destination_type, destination_name): assert 0 < evt['activemq'][destination_type]['messages'][ 'size']['avg'] self.assert_fields_are_documented(evt) passed = True conn.disconnect() assert passed
class ProtArchive(ProtProcessMovies): """ Sends a message to the dials archiving queue """ _label = 'DLS Archive' def _defineParams(self, form): form.addSection(label='Params') group = form.addGroup('Message Queue') group.addParam('queueHost', params.StringParam, label="Host", important=True, help='The host name for a queue broker (e.g. activemq)') group.addParam( 'queuePort', params.IntParam, label="Port", important=True, default=61613, help='The stomp port for a queue broker (e.g. activemq)') group.addParam('queueName', params.StringParam, label='Queue Name', help='The name of the queue within the broker') group.addParam('dropFileDir', params.FolderParam, label='Dropfile dir', help='The location of the dropfile dir') def processMovieStep(self, movieDict, hasAlignment): SCIPION_HOME = os.environ['SCIPION_HOME'] LOGFILE = os.path.join(SCIPION_HOME, 'pyworkflow', 'em', 'packages', 'dls', 'archive_recipe.json') with open(LOGFILE) as recipe: recipe_data = json.load(recipe) real_path = os.path.realpath(movieDict['_filename']) self._setValues(recipe_data, 'files', [real_path]) self._setValues(recipe_data, 'dropfile-dir', dropFileDir) json_data = json.dumps(recipe_data) self._sendMessage(json_data) def _setValues(self, data, key, value): for k in data: if k == key: data[k] = value elif type(data[k]) is dict: self._setValues(data[k], key, value) def _sendMessage(self, json_data): # type: (str) -> void try: try: from stomp import Connection except ImportError as ex: print "You need stomp to run the archiver, run 'scipion run pip stomp.py' first" raise ex self.connection.send(self.queue_name, json_data) except AttributeError: self.connection = Connection([(self.queueHost, self.queuePort)]) self.connection.connect(wait=True) self._sendMessage(json_data) def createOutputStep(self): pass