/* * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. 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. */ package org.wso2.carbon.transport.jms.receiver; import org.wso2.carbon.messaging.CarbonMessage; import org.wso2.carbon.messaging.CarbonMessageProcessor; import org.wso2.carbon.transport.jms.callback.AcknowledgementCallback; import org.wso2.carbon.transport.jms.callback.TransactedSessionCallback; import org.wso2.carbon.transport.jms.exception.JMSConnectorException; import org.wso2.carbon.transport.jms.utils.JMSConstants; import org.wso2.carbon.transport.jms.utils.JMSUtils; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.Session; /** * Handles a received JMS message by passing it to the relevant message processor. */ class JMSMessageHandler { private CarbonMessageProcessor carbonMessageProcessor; private String serviceId; private int acknowledgementMode; private Session session; /** * Initializes the message handler with connection details. * * @param carbonMessageProcessor The message processor which is going to process the received messages * @param serviceId Id of the service that is interested in particular destination * @param session The session that is used to create the consumer * @throws JMSConnectorException Throws if an error occurs when retrieving session acknowledgement mode */ JMSMessageHandler(CarbonMessageProcessor carbonMessageProcessor, String serviceId, Session session) throws JMSConnectorException { this.carbonMessageProcessor = carbonMessageProcessor; this.serviceId = serviceId; this.session = session; try { acknowledgementMode = session.getAcknowledgeMode(); } catch (JMSException e) { throw new JMSConnectorException("Error retrieving acknowledgement mode", e); } } /** * Processes a received JMS message and forward to the relevant {@link CarbonMessageProcessor} * <br> * <br> * Acknowledge/Commit/Rollback .etc needs to be handled within the same thread since JMS API specifies that * session objects should be handled within a single thread. * <br> * See <a href="https://docs.oracle.com/cd/E19340-01/820-6767/aeqdb/index.html">JMS Threading Restrictions</a>. * Hence, onMessage will wait for the relevant callback to complete before returning. * * @param message The received JMS Message * @throws JMSConnectorException Throws when an errors occurs when processing the received message */ void handle(Message message) throws JMSConnectorException { try { CarbonMessage jmsCarbonMessage = JMSUtils.createJMSCarbonMessage(message); jmsCarbonMessage.setProperty(org.wso2.carbon.messaging.Constants.PROTOCOL, JMSConstants.PROTOCOL_JMS); jmsCarbonMessage.setProperty(JMSConstants.JMS_SERVICE_ID, serviceId); jmsCarbonMessage.setProperty(JMSConstants.JMS_SESSION_ACKNOWLEDGEMENT_MODE, this.acknowledgementMode); switch (acknowledgementMode) { case Session.CLIENT_ACKNOWLEDGE: AcknowledgementCallback acknowledgementCallback = new AcknowledgementCallback(session, this, message); carbonMessageProcessor.receive(jmsCarbonMessage, acknowledgementCallback); synchronized (this) { while (!acknowledgementCallback.isOperationComplete()) { wait(); } } break; case Session.SESSION_TRANSACTED: TransactedSessionCallback transactedSessionCallback = new TransactedSessionCallback(session, this); carbonMessageProcessor.receive(jmsCarbonMessage, transactedSessionCallback); synchronized (this) { while (!transactedSessionCallback.isOperationComplete()) { wait(); } } break; default: //Session.AUTO_ACKNOWLEDGE and Session.DUPS_OK_ACKNOWLEDGE will be handled by this carbonMessageProcessor.receive(jmsCarbonMessage, null); } } catch (InterruptedException e) { throw new JMSConnectorException("Error waiting for the operation to complete", e); } catch (Exception e) { throw new JMSConnectorException("Error while getting the message from jms provider.", e); } } }