/** * Cancel a previous subscription. * * @param destinationType The destination type (TOPIC or QUEUE). * @param destinationName The destination name (e.g., /topic/.*). * @param acceptRequest An AcceptRequest object used handling Accept messages. */ public void unsubscribe( NetAction.DestinationType destinationType, String destinationName, AcceptRequest acceptRequest) throws Throwable { if ((StringUtils.isNotBlank(destinationName)) && (destinationType != null)) { NetUnsubscribe unsubs = new NetUnsubscribe(destinationName, destinationType); if (acceptRequest != null) { unsubs.setActionId(acceptRequest.getActionId()); PendingAcceptRequestsManager.addAcceptRequest(acceptRequest); } NetAction action = new NetAction(ActionType.UNSUBSCRIBE); action.setUnsbuscribeMessage(unsubs); NetMessage message = buildMessage(action); getNetHandler().sendMessage(message); Map<String, BrokerAsyncConsumer> subscriptions = _consumerList.get( destinationType.equals(DestinationType.TOPIC) ? DestinationType.TOPIC : DestinationType.QUEUE); subscriptions.remove(destinationName); } else { throw new IllegalArgumentException("Mal-formed Unsubscribe request"); } }
/** * Publishes a message to a queue. * * @param brokerMessage The Broker message containing the payload. * @param destinationName The destination name (e.g. /queue/foo). * @param acceptRequest An AcceptRequest object used handling Accept messages. */ public void enqueueMessage( NetBrokerMessage brokerMessage, String destinationName, AcceptRequest acceptRequest) { if ((brokerMessage != null) && (StringUtils.isNotBlank(destinationName))) { NetPublish publish = new NetPublish( destinationName, pt.com.broker.types.NetAction.DestinationType.QUEUE, brokerMessage); if (acceptRequest != null) { publish.setActionId(acceptRequest.getActionId()); PendingAcceptRequestsManager.addAcceptRequest(acceptRequest); } NetAction action = new NetAction(ActionType.PUBLISH); action.setPublishMessage(publish); NetMessage msg = buildMessage(action, brokerMessage.getHeaders()); try { getNetHandler().sendMessage(msg); } catch (Throwable t) { log.error("Failed to deliver message.", t); } } else { throw new IllegalArgumentException("Mal-formed Enqueue request"); } }
/** * Publish a message to a topic. * * @param brokerMessage The Broker message containing the payload. * @param destination The destination name (e.g. /topic/foo). * @param acceptRequest An AcceptRequest object used handling Accept messages. */ public void publishMessage( NetBrokerMessage brokerMessage, String destination, AcceptRequest acceptRequest) { if ((brokerMessage != null) && (StringUtils.isNotBlank(destination))) { NetPublish publish = new NetPublish( destination, pt.com.broker.types.NetAction.DestinationType.TOPIC, brokerMessage); if (acceptRequest != null) { publish.setActionId(acceptRequest.getActionId()); PendingAcceptRequestsManager.addAcceptRequest(acceptRequest); } NetAction action = new NetAction(ActionType.PUBLISH); action.setPublishMessage(publish); NetMessage msg = buildMessage(action, brokerMessage.getHeaders()); try { getNetHandler().sendMessage(msg); } catch (Throwable e) { log.error("Could not publish message, messageId:"); log.error(e.getMessage(), e); } } else { throw new IllegalArgumentException("Mal-formed Publish request"); } }
/** * Checks agent's liveness by sending a Ping message. Waits synchronously by the response. * * @return A <code>Pong</code> message or <code>null</code> if the agent doesn't answer in 2 * seconds; */ public NetPong checkStatus() throws Throwable { String actionId = UUID.randomUUID().toString(); NetPing ping = new NetPing(actionId); NetAction action = new NetAction(ActionType.PING); action.setPingMessage(ping); NetMessage message = buildMessage(action); getNetHandler().sendMessage(message); long timeout = System.currentTimeMillis() + (2 * 1000); NetPong pong = null; do { synchronized (_bstatus) { Sleep.time(500); if (System.currentTimeMillis() > timeout) return null; pong = _bstatus.peek(); if (pong == null) continue; if (!pong.getActionId().equals(NetPong.getUniversalActionId()) && !pong.getActionId().equals(actionId)) { pong = null; } _bstatus.remove(); } } while (pong == null); return pong; }
/** * Acknowledges a received message. * * @param notification The received notification message * @param acceptRequest An AcceptRequest object used handling Accept messages. */ public void acknowledge(NetNotification notification, AcceptRequest acceptRequest) throws Throwable { if ((notification != null) && (notification.getMessage() != null) && (StringUtils.isNotBlank(notification.getMessage().getMessageId()))) { NetBrokerMessage brkMsg = notification.getMessage(); if (notification.getDestinationType() == DestinationType.TOPIC) { return; } String ackDestination = notification.getSubscription(); NetAcknowledge ackMsg = new NetAcknowledge(ackDestination, brkMsg.getMessageId()); if (acceptRequest != null) { ackMsg.setActionId(acceptRequest.getActionId()); PendingAcceptRequestsManager.addAcceptRequest(acceptRequest); } NetAction action = new NetAction(ActionType.ACKNOWLEDGE); action.setAcknowledgeMessage(ackMsg); NetMessage msg = buildMessage(action); getNetHandler().sendMessage(msg); } else { throw new IllegalArgumentException("Can't acknowledge invalid message."); } }
/** * Obtain a queue message synchronously. * * @param queueName Name of the queue from where to retrieve a message * @param timeout Timeout, in milliseconds. When timeout is reached a TimeoutException is thrown. * Zero means that the client wants to wait forever. A negative value means that the client * doesn't want to wait if there are no messages is local agent's queue. * @param reserveTime Message reserve time, in milliseconds. Polled messages are reserved, by * default, for 15 minutes. If clients prefer a different reserve time , bigger or small, they * can specify it. * @param acceptRequest An AcceptRequest object used handling Accept messages. * @return A notification containing the queue message. Or null if timeout was a negative value * and there was no message in local agent's queue. */ public NetNotification poll( String queueName, long timeout, long reserveTime, AcceptRequest acceptRequest) throws Throwable { if (StringUtils.isBlank(queueName)) throw new IllegalArgumentException("Mal-formed Poll request. queueName is blank."); NetPoll poll = new NetPoll(queueName, timeout); NetAction action = new NetAction(ActionType.POLL); action.setPollMessage(poll); NetMessage message = buildMessage(action); SynchronousQueue<NetMessage> synQueue = new SynchronousQueue<NetMessage>(); synchronized (_syncSubscriptions) { if (_syncSubscriptions.containsKey(queueName)) throw new IllegalArgumentException("Queue " + queueName + " has already a poll runnig."); _syncSubscriptions.put(queueName, message); pendingPolls.put(queueName, synQueue); } if (reserveTime > 0) { message.getHeaders().put(Headers.RESERVE_TIME, reserveTime + ""); } if (acceptRequest != null) { poll.setActionId(acceptRequest.getActionId()); PendingAcceptRequestsManager.addAcceptRequest(acceptRequest); } getNetHandler().sendMessage(message); NetMessage receivedMsg = synQueue.take(); synchronized (_syncSubscriptions) { _syncSubscriptions.remove(queueName); pendingPolls.remove(queueName); } if (receivedMsg == BrokerProtocolHandler.TimeoutUnblockNotification) throw new TimeoutException(); if (receivedMsg == BrokerProtocolHandler.NoMessageUnblockNotification) return null; NetNotification m = null; if (receivedMsg.getAction().getActionType().equals(ActionType.NOTIFICATION)) { m = receivedMsg.getAction().getNotificationMessage(); } else { log.error( "Poll unbloqued by a message that wasn't of any of the expeceted error nor a notification."); return null; } return m; }
protected void sendSubscriptions() throws Throwable { for (DestinationType desType : _consumerList.keySet()) { Map<String, BrokerAsyncConsumer> subscriptions = _consumerList.get(desType); for (BrokerAsyncConsumer aconsumer : subscriptions.values()) { NetSubscribe subscription = aconsumer.getSubscription(); NetAction netAction = new NetAction(ActionType.SUBSCRIBE); netAction.setSubscribeMessage(subscription); NetMessage msg = buildMessage(netAction, subscription.getHeaders()); getNetHandler().sendMessage(msg); log.info("Reconnected async consumer for '{}'", subscription.getDestination()); } } synchronized (_syncSubscriptions) { for (String queueName : _syncSubscriptions.keySet()) { getNetHandler().sendMessage(_syncSubscriptions.get(queueName)); } } }
/** * Create a new asynchronous subscription. * * @param subscribe A subscription message. * @param listener A BrokerListener instance. * @param acceptRequest An AcceptRequest object used handling Accept messages. */ public void addAsyncConsumer( NetSubscribe subscribe, BrokerListener listener, AcceptRequest acceptRequest) throws Throwable { if ((subscribe != null) && (StringUtils.isNotBlank(subscribe.getDestination()))) { Map<String, BrokerAsyncConsumer> subscriptions = _consumerList.get( subscribe.getDestinationType().equals(DestinationType.TOPIC) ? DestinationType.TOPIC : DestinationType.QUEUE); BrokerAsyncConsumer previous = subscriptions.put( subscribe.getDestination(), new BrokerAsyncConsumer(subscribe, listener)); if (previous != null) { // A subscription for the given destination already existed. Set it again and subscriptions.put(subscribe.getDestination(), previous); throw new IllegalStateException("A listener for that Destination already exists"); } if (acceptRequest != null) { subscribe.setActionId(acceptRequest.getActionId()); PendingAcceptRequestsManager.addAcceptRequest(acceptRequest); } NetAction netAction = new NetAction(ActionType.SUBSCRIBE); netAction.setSubscribeMessage(subscribe); NetMessage msg = buildMessage(netAction, subscribe.getHeaders()); getNetHandler().sendMessage(msg); log.info("Created new async consumer for '{}'", subscribe.getDestination()); } else { throw new IllegalArgumentException("Mal-formed Notification request"); } }