001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.camel;
018
019 import java.net.URISyntaxException;
020 import java.util.Map;
021 import java.util.Set;
022 import java.util.concurrent.ConcurrentHashMap;
023
024 import javax.jbi.management.DeploymentException;
025 import javax.jbi.messaging.ExchangeStatus;
026 import javax.jbi.messaging.MessageExchange;
027 import javax.jbi.messaging.MessagingException;
028 import javax.jbi.messaging.NormalizedMessage;
029 import javax.xml.namespace.QName;
030
031 import org.apache.camel.AsyncCallback;
032 import org.apache.camel.AsyncProcessor;
033 import org.apache.camel.Exchange;
034 import org.apache.camel.Message;
035 import org.apache.servicemix.common.endpoints.ConsumerEndpoint;
036 import org.apache.servicemix.id.IdGenerator;
037 import org.apache.servicemix.jbi.FaultException;
038 import org.apache.servicemix.jbi.resolver.URIResolver;
039
040 /**
041 * A consumer endpoint that will be used to send JBI exchanges
042 * originating from camel.
043 */
044 public class CamelConsumerEndpoint extends ConsumerEndpoint implements AsyncProcessor {
045
046 public static final QName SERVICE_NAME = new QName("http://activemq.apache.org/camel/schema/jbi", "consumer");
047
048 private JbiBinding binding;
049
050 private JbiEndpoint jbiEndpoint;
051
052 private Map<String, AsyncCallback> callbacks = new ConcurrentHashMap<String, AsyncCallback>();
053 private Map<String, Exchange> exchanges = new ConcurrentHashMap<String, Exchange>();
054
055 public CamelConsumerEndpoint(JbiBinding binding, JbiEndpoint jbiEndpoint) {
056 setService(SERVICE_NAME);
057 setEndpoint(new IdGenerator().generateId());
058 this.binding = binding;
059 this.jbiEndpoint = jbiEndpoint;
060 }
061
062 public void process(MessageExchange messageExchange) throws Exception {
063 Exchange exchange = exchanges.remove(messageExchange.getExchangeId());
064 if (exchange == null) {
065 String message = String.format("Unable to find Camel Exchange for JBI MessageExchange %s", messageExchange.getExchangeId());
066 logger.warn(message);
067 if (messageExchange.getStatus() == ExchangeStatus.ACTIVE) {
068 fail(messageExchange, new JbiException(message));
069 }
070 } else {
071 processReponse(messageExchange, exchange);
072 }
073
074 AsyncCallback asyncCallback = callbacks.remove(messageExchange.getExchangeId());
075 if (asyncCallback == null) {
076 logger.warn(String.format("Unable to find Camel AsyncCallback for JBI MessageExchange %s", messageExchange.getExchangeId()));
077 } else {
078 asyncCallback.done(false);
079 }
080 }
081
082 public boolean process(Exchange exchange, AsyncCallback asyncCallback) {
083 try {
084 MessageExchange messageExchange = binding.makeJbiMessageExchange(exchange, getExchangeFactory(), jbiEndpoint.getMep());
085
086 if (jbiEndpoint.getOperation() != null) {
087 messageExchange.setOperation(QName.valueOf(jbiEndpoint.getOperation()));
088 }
089
090 URIResolver.configureExchange(messageExchange, getContext(), jbiEndpoint.getDestinationUri());
091 exchanges.put(messageExchange.getExchangeId(), exchange);
092 callbacks.put(messageExchange.getExchangeId(), asyncCallback);
093
094 send(messageExchange);
095 return false;
096 } catch (Exception e) {
097 exchange.setException(e);
098 asyncCallback.done(true);
099 return true;
100 }
101 }
102
103 public void process(Exchange exchange) throws Exception {
104 try {
105 MessageExchange messageExchange = binding.makeJbiMessageExchange(exchange, getExchangeFactory(), jbiEndpoint.getMep());
106
107 if (jbiEndpoint.getOperation() != null) {
108 messageExchange.setOperation(QName.valueOf(jbiEndpoint.getOperation()));
109 }
110
111 URIResolver.configureExchange(messageExchange, getContext(), jbiEndpoint.getDestinationUri());
112
113 sendSync(messageExchange);
114
115 processReponse(messageExchange, exchange);
116
117 } catch (MessagingException e) {
118 exchange.setException(e);
119 throw new JbiException(e);
120 } catch (URISyntaxException e) {
121 exchange.setException(e);
122 throw new JbiException(e);
123 }
124 }
125
126 public String getLocationURI() {
127 return null;
128 }
129
130 private void processReponse(MessageExchange messageExchange, Exchange exchange) throws MessagingException {
131 if (messageExchange.getStatus() == ExchangeStatus.ERROR) {
132 exchange.setException(messageExchange.getError());
133 } else if (messageExchange.getStatus() == ExchangeStatus.ACTIVE) {
134 addHeaders(messageExchange, exchange);
135 if (messageExchange.getFault() != null) {
136 exchange.getFault().setBody(new FaultException("Fault occured for " + exchange.getPattern() + " exchange",
137 messageExchange, messageExchange.getFault()));
138 addHeaders(messageExchange.getFault(), exchange.getFault());
139 addAttachments(messageExchange.getFault(), exchange.getFault());
140 } else if (messageExchange.getMessage("out") != null) {
141 exchange.getOut().setBody(messageExchange.getMessage("out").getContent());
142 addHeaders(messageExchange.getMessage("out"), exchange.getOut());
143 addAttachments(messageExchange.getMessage("out"), exchange.getOut());
144 }
145 done(messageExchange);
146 }
147 }
148
149 @Override
150 public void validate() throws DeploymentException {
151 // No validation required
152 }
153
154 @SuppressWarnings("unchecked")
155 private void addHeaders(MessageExchange messageExchange, Exchange camelExchange) {
156 Set entries = messageExchange.getPropertyNames();
157 for (Object o : entries) {
158 String key = o.toString();
159 camelExchange.setProperty(key, messageExchange.getProperty(key));
160 }
161 }
162
163 @SuppressWarnings("unchecked")
164 private void addHeaders(NormalizedMessage normalizedMessage, Message camelMessage) {
165 Set entries = normalizedMessage.getPropertyNames();
166 for (Object o : entries) {
167 String key = o.toString();
168 camelMessage.setHeader(key, normalizedMessage.getProperty(key));
169 }
170 }
171
172 @SuppressWarnings("unchecked")
173 private void addAttachments(NormalizedMessage normalizedMessage, Message camelMessage) {
174 Set entries = normalizedMessage.getAttachmentNames();
175 for (Object o : entries) {
176 String id = o.toString();
177 camelMessage.addAttachment(id, normalizedMessage.getAttachment(id));
178 }
179 }
180
181 }