/* * Copyright 2004,2005 The Apache Software Foundation. * * Licensed 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.apache.axis2.transport.jms; import org.apache.axis2.AxisFault; import org.apache.axis2.description.AxisService; import org.apache.axis2.description.Parameter; import org.apache.axis2.description.ParameterInclude; import org.apache.axis2.transport.base.BaseConstants; import org.apache.axis2.transport.base.ParamUtils; import org.apache.axis2.transport.base.ProtocolEndpoint; import org.apache.axis2.transport.base.threads.WorkerPool; import org.apache.axis2.transport.jms.ctype.ContentTypeRuleFactory; import org.apache.axis2.transport.jms.ctype.ContentTypeRuleSet; import org.apache.axis2.transport.jms.ctype.MessageTypeRule; import org.apache.axis2.transport.jms.ctype.PropertyRule; import org.apache.axis2.addressing.EndpointReference; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.Set; import java.util.HashSet; import javax.jms.BytesMessage; import javax.jms.TextMessage; import javax.naming.Context; /** * Class that links an Axis2 service to a JMS destination. Additionally, it contains * all the required information to process incoming JMS messages and to inject them * into Axis2. */ public class JMSEndpoint extends ProtocolEndpoint { private static final Log log = LogFactory.getLog(JMSEndpoint.class); private final JMSListener listener; private final WorkerPool workerPool; private JMSConnectionFactory cf; private String jndiDestinationName; private int destinationType = JMSConstants.GENERIC; private String jndiReplyDestinationName; private String replyDestinationType = JMSConstants.DESTINATION_TYPE_GENERIC; private Set<EndpointReference> endpointReferences = new HashSet<EndpointReference>(); private ContentTypeRuleSet contentTypeRuleSet; private ServiceTaskManager serviceTaskManager; public JMSEndpoint(JMSListener listener, WorkerPool workerPool) { this.listener = listener; this.workerPool = workerPool; } public String getJndiDestinationName() { return jndiDestinationName; } private void setDestinationType(String destinationType) { if (JMSConstants.DESTINATION_TYPE_TOPIC.equalsIgnoreCase(destinationType)) { this.destinationType = JMSConstants.TOPIC; } else if (JMSConstants.DESTINATION_TYPE_QUEUE.equalsIgnoreCase(destinationType)) { this.destinationType = JMSConstants.QUEUE; } else { this.destinationType = JMSConstants.GENERIC; } } private void setReplyDestinationType(String destinationType) { if (JMSConstants.DESTINATION_TYPE_TOPIC.equalsIgnoreCase(destinationType)) { this.replyDestinationType = JMSConstants.DESTINATION_TYPE_TOPIC; } else if (JMSConstants.DESTINATION_TYPE_QUEUE.equalsIgnoreCase(destinationType)) { this.replyDestinationType = JMSConstants.DESTINATION_TYPE_QUEUE; } else { this.replyDestinationType = JMSConstants.DESTINATION_TYPE_GENERIC; } } public String getJndiReplyDestinationName() { return jndiReplyDestinationName; } public String getReplyDestinationType() { return replyDestinationType; } @Override public EndpointReference[] getEndpointReferences(AxisService service, String ip) { return endpointReferences.toArray(new EndpointReference[endpointReferences.size()]); } private void computeEPRs() { List<EndpointReference> eprs = new ArrayList<EndpointReference>(); for (Object o : getService().getParameters()) { Parameter p = (Parameter) o; if (JMSConstants.PARAM_PUBLISH_EPR.equals(p.getName()) && p.getValue() instanceof String) { if ("legacy".equalsIgnoreCase((String) p.getValue())) { // if "legacy" specified, compute and replace it endpointReferences.add( new EndpointReference(getEPR())); } else { endpointReferences.add(new EndpointReference((String) p.getValue())); } } } if (eprs.isEmpty()) { // if nothing specified, compute and return legacy EPR endpointReferences.add(new EndpointReference(getEPR())); } } /** * Get the EPR for the given JMS connection factory and destination * the form of the URL is * jms:/<destination>?[<key>=<value>&]* * Credentials Context.SECURITY_PRINCIPAL, Context.SECURITY_CREDENTIALS * JMSConstants.PARAM_JMS_USERNAME and JMSConstants.PARAM_JMS_USERNAME are filtered * * @return the EPR as a String */ private String getEPR() { StringBuffer sb = new StringBuffer(); sb.append( JMSConstants.JMS_PREFIX).append(jndiDestinationName); sb.append("?"). append(JMSConstants.PARAM_DEST_TYPE).append("=").append( destinationType == JMSConstants.TOPIC ? JMSConstants.DESTINATION_TYPE_TOPIC : JMSConstants.DESTINATION_TYPE_QUEUE); if (contentTypeRuleSet != null) { String contentTypeProperty = contentTypeRuleSet.getDefaultContentTypeProperty(); if (contentTypeProperty != null) { sb.append("&"); sb.append(JMSConstants.CONTENT_TYPE_PROPERTY_PARAM); sb.append("="); sb.append(contentTypeProperty); } } for (Map.Entry<String,String> entry : cf.getParameters().entrySet()) { if (!Context.SECURITY_PRINCIPAL.equalsIgnoreCase(entry.getKey()) && !Context.SECURITY_CREDENTIALS.equalsIgnoreCase(entry.getKey()) && !JMSConstants.PARAM_JMS_USERNAME.equalsIgnoreCase(entry.getKey()) && !JMSConstants.PARAM_JMS_PASSWORD.equalsIgnoreCase(entry.getKey())) { sb.append("&").append( entry.getKey()).append("=").append(entry.getValue()); } } return sb.toString(); } public ContentTypeRuleSet getContentTypeRuleSet() { return contentTypeRuleSet; } public JMSConnectionFactory getCf() { return cf; } public ServiceTaskManager getServiceTaskManager() { return serviceTaskManager; } public void setServiceTaskManager(ServiceTaskManager serviceTaskManager) { this.serviceTaskManager = serviceTaskManager; } @Override public boolean loadConfiguration(ParameterInclude params) throws AxisFault { // We only support endpoints configured at service level if (!(params instanceof AxisService)) { return false; } AxisService service = (AxisService)params; cf = listener.getConnectionFactory(service); if (cf == null) { return false; } Parameter destParam = service.getParameter(JMSConstants.PARAM_DESTINATION); if (destParam != null) { jndiDestinationName = (String)destParam.getValue(); } else { // Assume that the JNDI destination name is the same as the service name jndiDestinationName = service.getName(); } Parameter destTypeParam = service.getParameter(JMSConstants.PARAM_DEST_TYPE); if (destTypeParam != null) { String paramValue = (String) destTypeParam.getValue(); if (JMSConstants.DESTINATION_TYPE_QUEUE.equals(paramValue) || JMSConstants.DESTINATION_TYPE_TOPIC.equals(paramValue) ) { setDestinationType(paramValue); } else { throw new AxisFault("Invalid destinaton type value " + paramValue); } } else { log.debug("JMS destination type not given. default queue"); destinationType = JMSConstants.QUEUE; } Parameter replyDestTypeParam = service.getParameter(JMSConstants.PARAM_REPLY_DEST_TYPE); if (replyDestTypeParam != null) { String paramValue = (String) replyDestTypeParam.getValue(); if (JMSConstants.DESTINATION_TYPE_QUEUE.equals(paramValue) || JMSConstants.DESTINATION_TYPE_TOPIC.equals(paramValue) ) { setReplyDestinationType(paramValue); } else { throw new AxisFault("Invalid destinaton type value " + paramValue); } } else { log.debug("JMS reply destination type not given. default queue"); replyDestinationType = JMSConstants.DESTINATION_TYPE_QUEUE; } jndiReplyDestinationName = ParamUtils.getOptionalParam(service, JMSConstants.PARAM_REPLY_DESTINATION); Parameter contentTypeParam = service.getParameter(JMSConstants.CONTENT_TYPE_PARAM); if (contentTypeParam == null) { contentTypeRuleSet = new ContentTypeRuleSet(); contentTypeRuleSet.addRule(new PropertyRule(BaseConstants.CONTENT_TYPE)); contentTypeRuleSet.addRule(new MessageTypeRule(BytesMessage.class, "application/octet-stream")); contentTypeRuleSet.addRule(new MessageTypeRule(TextMessage.class, "text/plain")); } else { contentTypeRuleSet = ContentTypeRuleFactory.parse(contentTypeParam); } computeEPRs(); // compute service EPR and keep for later use serviceTaskManager = ServiceTaskManagerFactory.createTaskManagerForService(cf, service, workerPool); serviceTaskManager.setJmsMessageReceiver(new JMSMessageReceiver(listener, cf, this)); return true; } }