def test_onhandlerException_ackMessage_filterReservedHdrs_send2ErrorQ_and_no_disconnect(self):
        config = StompConfig(HOST, PORT)
        creator = StompCreator(config)

        # Connect
        stomp = yield creator.getConnection()

        # Enqueue two messages
        stomp.send(self.queue, self.msg1, self.msg1Hdrs)
        stomp.send(self.queue, self.msg2)

        # Barf on first msg, disconnect on second msg
        stomp.subscribe(
            self.queue,
            self._barfOneEatOneAndDisonnect,
            {"ack": "client-individual", "activemq.prefetchSize": 1},
            errorDestination=self.errorQueue,
        )

        # Client disconnects without error
        yield stomp.getDisconnectedDeferred()

        # Reconnect and subscribe to error queue
        stomp = yield creator.getConnection()
        stomp.subscribe(
            self.errorQueue, self._saveErrMsgAndDisconnect, {"ack": "client-individual", "activemq.prefetchSize": 1}
        )

        # Wait for disconnect
        yield stomp.getDisconnectedDeferred()

        # Verify that one message was in error queue (can't guarantee order)
        self.assertNotEquals(None, self.errQMsg)
        self.assertTrue(self.errQMsg["body"] in (self.msg1, self.msg2))
    def test_onDisconnect_waitForOutstandingMessagesToFinish(self):
        self.config = StompConfig(HOST, PORT)
        self.creator = StompCreator(self.config)

        config = StompConfig(HOST, PORT)
        creator = StompCreator(config)

        # Connect
        stomp = yield creator.getConnection()

        for i in range(self.numMsgs):
            stomp.send(self.queue, self.msg)
        stomp.subscribe(
            self.queue, self._msgHandler, {"ack": "client-individual", "activemq.prefetchSize": self.numMsgs}
        )

        # Wait for disconnect
        yield stomp.getDisconnectedDeferred()

        # Reconnect and subscribe again to make sure that all messages in the queue were ack'ed
        stomp = yield creator.getConnection()
        self.timeExpired = False
        self.timeoutDelayedCall = reactor.callLater(1, self._timesUp, stomp)
        stomp.subscribe(
            self.queue,
            self._eatOneMsgAndDisconnect,
            {"ack": "client-individual", "activemq.prefetchSize": self.numMsgs},
        )

        # Wait for disconnect
        yield stomp.getDisconnectedDeferred()

        # Time should have expired if there were no messages left in the queue
        self.assertTrue(self.timeExpired)
class GracefulDisconnectTestCase(unittest.TestCase):
    numMsgs = 5
    msgCount = 0
    msg = 'test'
    queue = '/queue/aysncStompestGracefulDisconnectUnitTest'
    disconnected = defer.Deferred()
    disconnectedAgain = defer.Deferred()
    ackMode = getClientAckMode()
    
    def test_onDisconnect_waitForOutstandingMessagesToFinish(self):
        self.config = StompConfig('localhost', 61613)
        self.creator = StompCreator(self.config)
        deferConnected = self.creator.getConnection().addCallback(self._onConnected)
        self.disconnected.addCallback(self._reconnect)
        self.disconnectedAgain.addCallback(self._verifyAllMsgsAcked)
        return defer.DeferredList([
                self.disconnected,
                self.disconnectedAgain,
            ]
        )
        
    def _onConnected(self, stomp):
        stomp.getDisconnectedDeferred().addCallback(self.disconnected.callback).addErrback(self.disconnected.errback)
        for i in range(self.numMsgs):
            stomp.send(self.queue, self.msg)
        stomp.subscribe(self.queue, self._msgHandler, {'ack': self.ackMode, 'activemq.prefetchSize': self.numMsgs})
        
    def _msgHandler(self, stomp, msg):
        self.msgCount += 1
        if self.msgCount < self.numMsgs:
            d = defer.Deferred() 
            reactor.callLater(1, d.callback, None)
            return d
        else:
            stomp.disconnect()
            
    def _reconnect(self, result):
        self.creator.getConnection().addCallback(self._onReconnect)
        
    def _onReconnect(self, stomp):
        stomp.getDisconnectedDeferred().addCallback(self.disconnectedAgain.callback).addErrback(self.disconnectedAgain.errback)
        self.timeExpired = False
        self.timeoutDelayedCall = reactor.callLater(1, self._timesUp, stomp)
        stomp.subscribe(self.queue, self._eatOneMsgAndDisconnect, {'ack': self.ackMode, 'activemq.prefetchSize': self.numMsgs})

    def _timesUp(self, stomp):
        print "Times up!!!"
        self.timeExpired = True
        stomp.disconnect()

    def _eatOneMsgAndDisconnect(self, stomp, msg):
        self.timeoutDelayedCall.cancel()
        stomp.disconnect()
        
    def _verifyAllMsgsAcked(self, result):
        print "VERIFY!"
        self.assertTrue(self.timeExpired)
        return result
    def test_onhandlerException_ackMessage_filterReservedHdrs_send2ErrorQ_and_disconnect(self):
        config = StompConfig(HOST, PORT)
        creator = StompCreator(config, alwaysDisconnectOnUnhandledMsg=True)

        # Connect
        stomp = yield creator.getConnection()

        # Enqueue two messages
        stomp.send(self.queue, self.msg1, self.msg1Hdrs)
        stomp.send(self.queue, self.msg2)

        # Barf on first message so it will get put in error queue
        # Use selector to guarantee message order.  AMQ doesn't not guarantee order by default
        stomp.subscribe(
            self.queue,
            self._saveMsgAndBarf,
            {"ack": "client-individual", "activemq.prefetchSize": 1, "selector": "food = 'barf'"},
            errorDestination=self.errorQueue,
        )

        # Client disconnected and returned error
        try:
            yield stomp.getDisconnectedDeferred()
        except StompestTestError:
            pass
        else:
            self.assertTrue(False)

        # Reconnect and subscribe again - consuming second message then disconnecting
        stomp = yield creator.getConnection()
        stomp.subscribe(
            self.queue,
            self._eatOneMsgAndDisconnect,
            {"ack": "client-individual", "activemq.prefetchSize": 1},
            errorDestination=self.errorQueue,
        )

        # Client disconnects without error
        yield stomp.getDisconnectedDeferred()

        # Reconnect and subscribe to error queue
        stomp = yield creator.getConnection()
        stomp.subscribe(
            self.errorQueue, self._saveErrMsgAndDisconnect, {"ack": "client-individual", "activemq.prefetchSize": 1}
        )

        # Wait for disconnect
        yield stomp.getDisconnectedDeferred()

        # Verify that first message was in error queue
        self.assertEquals(self.msg1, self.errQMsg["body"])
        self.assertEquals(self.msg1Hdrs["food"], self.errQMsg["headers"]["food"])
        self.assertNotEquals(self.unhandledMsg["headers"]["message-id"], self.errQMsg["headers"]["message-id"])

        # Verify that second message was consumed
        self.assertEquals(self.msg2, self.consumedMsg["body"])
    def test_onhandlerException_disconnect(self):
        config = StompConfig(HOST, PORT)
        creator = StompCreator(config)

        # Connect
        stomp = yield creator.getConnection()

        # Enqueue a message
        stomp.send(self.queue, self.msg1, self.msg1Hdrs)

        # Barf on first msg (implicit disconnect)
        stomp.subscribe(self.queue, self._saveMsgAndBarf, {"ack": "client-individual", "activemq.prefetchSize": 1})

        # Client disconnected and returned error
        try:
            yield stomp.getDisconnectedDeferred()
        except StompestTestError, e:
            pass
 def test_onDisconnect_waitForOutstandingMessagesToFinish(self):
     self.config = StompConfig('localhost', 61613)
     self.creator = StompCreator(self.config)
     deferConnected = self.creator.getConnection().addCallback(self._onConnected)
     self.disconnected.addCallback(self._reconnect)
     self.disconnectedAgain.addCallback(self._verifyAllMsgsAcked)
     return defer.DeferredList([
             self.disconnected,
             self.disconnectedAgain,
         ]
     )
 def test_onhandlerException_ackMessage_filterReservedHdrs_send2ErrorQ_and_errback(self):
     self.cleanQueues()
     self.config = StompConfig('localhost', 61613)
     self.creator = StompCreator(self.config)
     deferConnected = self.creator.getConnection().addCallback(self._onConnected)
     deferredTestErr = self.assertFailure(self.disconnected, StompestTestError).addCallback(self._reconnectAfterErr)
     self.disconnectedAgain.addCallback(self._reconnectForErrQ)
     self.disconnectedFromErrQ.addCallback(self._verifyErrMsg) #asserts err message content is correct
     return defer.DeferredList([
         deferredTestErr, #asserts that handler exception triggered disconnect and was propagated to disconnect deferred
         self.disconnectedAgain, #asserts that message causing the exception was ack'ed to broker (otherwise, this message would not get delivered)
         self.disconnectedFromErrQ, #asserts that we were able to read a message from the error queue
         ]
     )
예제 #8
0
 def test_bad_port_tcp_error(self):
     config = StompConfig('localhost', 65535)
     creator = StompCreator(config)
     return self.assertFailure(creator.getConnection(), error.ConnectionRefusedError)
예제 #9
0
 def test_bad_host_tcp_error(self):
     config = StompConfig('nosuchhost', 61613)
     creator = StompCreator(config)
     return self.assertFailure(creator.getConnection(), error.DNSLookupError)
예제 #10
0
 def test_stomp_error_after_connected(self):
     config = StompConfig('localhost', self.testPort)
     creator = StompCreator(config)
     creator.getConnection().addCallback(self.onConnected)
     return self.assertFailure(self.disconnected, StompProtocolError)
예제 #11
0
 def test_stomp_error_before_connected(self):
     config = StompConfig('localhost', self.testPort)
     creator = StompCreator(config)
     return self.assertFailure(creator.getConnection(), StompProtocolError)
예제 #12
0
 def test_connection_timeout(self):
     config = StompConfig('localhost', self.testPort)
     creator = StompCreator(config, connectTimeout=1)
     return self.assertFailure(creator.getConnection(), StompConnectTimeout)
class HandlerExceptionWithErrorQueueIntegrationTestCase(unittest.TestCase):
    msg1 = 'choke on this'
    msg1Hdrs = {'food': 'barf', 'persistent': 'true'}
    msg2 = 'follow up message'
    queue = '/queue/asyncStompestHandlerExceptionWithErrorQueueUnitTest'
    errorQueue = '/queue/zzz.error.asyncStompestHandlerExceptionWithErrorQueueUnitTest'
    disconnected = defer.Deferred()
    disconnectedAgain = defer.Deferred()
    disconnectedFromErrQ = defer.Deferred()
    ackMode = getClientAckMode()
        
    def cleanQueues(self):
        self.cleanQueue(self.queue)
        self.cleanQueue(self.errorQueue)
    
    def cleanQueue(self, queue):
        stomp = Stomp('localhost', 61613)
        stomp.connect()
        stomp.subscribe(queue, {'ack': 'client'})
        while stomp.canRead(1):
            frame = stomp.receiveFrame()
            stomp.ack(frame)
            print "Dequeued old message: %s" % frame
        stomp.disconnect()        
    
    def test_onhandlerException_ackMessage_filterReservedHdrs_send2ErrorQ_and_errback(self):
        self.cleanQueues()
        self.config = StompConfig('localhost', 61613)
        self.creator = StompCreator(self.config)
        deferConnected = self.creator.getConnection().addCallback(self._onConnected)
        deferredTestErr = self.assertFailure(self.disconnected, StompestTestError).addCallback(self._reconnectAfterErr)
        self.disconnectedAgain.addCallback(self._reconnectForErrQ)
        self.disconnectedFromErrQ.addCallback(self._verifyErrMsg) #asserts err message content is correct
        return defer.DeferredList([
            deferredTestErr, #asserts that handler exception triggered disconnect and was propagated to disconnect deferred
            self.disconnectedAgain, #asserts that message causing the exception was ack'ed to broker (otherwise, this message would not get delivered)
            self.disconnectedFromErrQ, #asserts that we were able to read a message from the error queue
            ]
        )
        
    def _onConnected(self, stomp):
        stomp.getDisconnectedDeferred().addCallback(self.disconnected.callback).addErrback(self.disconnected.errback)
        stomp.send(self.queue, self.msg1, self.msg1Hdrs)
        stomp.send(self.queue, self.msg2)
        #Use selector to guarantee message order.  AMQ doesn't not guarantee order by default
        stomp.subscribe(self.queue, self._saveMsgAndBarf, {'ack': self.ackMode, 'activemq.prefetchSize': 1, 'selector': "food = 'barf'"}, errorDestination=self.errorQueue)
        
    def _saveMsgAndBarf(self, stomp, msg):
        print 'Save message and barf'
        self.assertEquals(self.msg1, msg['body'])
        self.unhandledMsg = msg
        raise StompestTestError('this is a test')
        
    def _reconnectAfterErr(self, result):
        self.creator.getConnection().addCallback(self._onConnectedAgain)
        
    def _onConnectedAgain(self, stomp):
        stomp.getDisconnectedDeferred().addCallback(self.disconnectedAgain.callback).addErrback(self.disconnectedAgain.errback)
        stomp.subscribe(self.queue, self._eatOneMsgAndDisconnect, {'ack': self.ackMode, 'activemq.prefetchSize': 1}, errorDestination=self.errorQueue)
        
    def _eatOneMsgAndDisconnect(self, stomp, msg):
        print 'Eat message and disconnect'
        self.assertEquals(self.msg2, msg['body'])
        stomp.disconnect()
        
    def _reconnectForErrQ(self, result):
        self.creator.getConnection().addCallback(self._onConnectedForErrQ)
        
    def _onConnectedForErrQ(self, stomp):
        stomp.getDisconnectedDeferred().addCallback(self.disconnectedFromErrQ.callback).addErrback(self.disconnectedFromErrQ.errback)
        stomp.subscribe(self.errorQueue, self._saveErrMsgAndDisconnect, {'ack': self.ackMode, 'activemq.prefetchSize': 1})
        
    def _saveErrMsgAndDisconnect(self, stomp, msg):
        print 'Save error message and disconnect'
        self.errQMsg = msg
        stomp.disconnect()
        
    def _verifyErrMsg(self, result):
        self.assertEquals(self.msg1, self.errQMsg['body'])
        self.assertEquals(self.msg1Hdrs['food'], self.errQMsg['headers']['food'])
        self.assertNotEquals(self.unhandledMsg['headers']['message-id'], self.errQMsg['headers']['message-id'])