PageRenderTime 205ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/jca/src/main/java/org/switchyard/component/jca/endpoint/JMSEndpoint.java

https://github.com/objectiser/switchyard-components
Java | 376 lines | 273 code | 30 blank | 73 comment | 58 complexity | 241aac206fe39f3b87c29121c9f5c48c MD5 | raw file
  1. /*
  2. * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. * Unless required by applicable law or agreed to in writing, software
  9. * distributed under the License is distributed on an "AS IS" BASIS,
  10. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. * See the License for the specific language governing permissions and
  12. * limitations under the License.
  13. */
  14. package org.switchyard.component.jca.endpoint;
  15. import java.io.InputStream;
  16. import java.util.Properties;
  17. import javax.jms.Connection;
  18. import javax.jms.ConnectionFactory;
  19. import javax.jms.Destination;
  20. import javax.jms.Message;
  21. import javax.jms.MessageListener;
  22. import javax.jms.MessageProducer;
  23. import javax.jms.Session;
  24. import javax.naming.InitialContext;
  25. import org.switchyard.Context;
  26. import org.switchyard.Exchange;
  27. import org.switchyard.ExchangePattern;
  28. import org.switchyard.ExchangeState;
  29. import org.switchyard.common.type.Classes;
  30. import org.switchyard.component.common.SynchronousInOutHandler;
  31. import org.switchyard.component.common.composer.MessageComposer;
  32. import org.switchyard.component.jca.JCALogger;
  33. import org.switchyard.component.jca.JCAMessages;
  34. import org.switchyard.component.jca.composer.JMSBindingData;
  35. import org.switchyard.SwitchYardException;
  36. import org.switchyard.selector.OperationSelector;
  37. /**
  38. * Concrete message endpoint class for JCA message inflow using JMS MessageListener interface.
  39. *
  40. * @author <a href="mailto:tm.igarashi@gmail.com">Tomohisa Igarashi</a>
  41. *
  42. */
  43. public class JMSEndpoint extends AbstractInflowEndpoint implements MessageListener {
  44. /** prefix for the context property. */
  45. public static final String CONTEXT_PROPERTY_PREFIX = "org.switchyard.component.jca.endpoint.";
  46. /** key for JNDI properties file. */
  47. public static final String KEY_JNDI_PROPERTIES_FILE = "jndiPropertiesFileName";
  48. /** key for JNDI properties file to look up the JMS destination. */
  49. public static final String KEY_DESTINATION_JNDI_PROPERTIES_FILE = "destinationJndiPropertiesFileName";
  50. /** key for ConnectionFactory JNDI name. */
  51. public static final String KEY_CONNECTION_FACTORY_JNDI_NAME = "connectionFactoryJndiName";
  52. /** key for replyTo destination name. */
  53. public static final String KEY_REPLY_TO = "replyTo";
  54. /** key for faultTo destination name. */
  55. public static final String KEY_FAULT_TO = "faultTo";
  56. /** key for output message type. */
  57. public static final String KEY_MESSAGE_TYPE = "messageType";
  58. /** key for user name. */
  59. public static final String KEY_USERNAME = "userName";
  60. /** key for password. */
  61. public static final String KEY_PASSWORD = "password";
  62. private MessageComposer<JMSBindingData> _composer;
  63. private OperationSelector<JMSBindingData> _selector;
  64. private String _jndiPropertiesFileName;
  65. private String _destinationJndiPropertiesFileName;
  66. private String _connectionFactoryJNDIName;
  67. private String _defaultFaultTo;
  68. private String _defaultReplyTo;
  69. private String _userName;
  70. private String _password;
  71. private Properties _jndiProperties;
  72. private Properties _destinationJndiProperties;
  73. private ConnectionFactory _connectionFactory;
  74. private Destination _faultToJMSDestination;
  75. private Destination _replyToJMSDestination;
  76. private MessageType _defaultOutMessageType = MessageType.Object;
  77. private enum MessageType {
  78. Stream, Map, Text, Object, Bytes, Plain
  79. }
  80. @Override
  81. public void initialize() {
  82. super.initialize();
  83. _composer = getMessageComposer(JMSBindingData.class);
  84. _selector = getOperationSelector(JMSBindingData.class);
  85. try {
  86. InitialContext cfic = null;
  87. if (getJndiProperties() != null) {
  88. cfic = new InitialContext(getJndiProperties());
  89. } else {
  90. cfic = new InitialContext();
  91. }
  92. if (_connectionFactoryJNDIName != null) {
  93. _connectionFactory = (ConnectionFactory) cfic.lookup(_connectionFactoryJNDIName);
  94. }
  95. InitialContext destic = null;
  96. if (getDestinationJndiProperties() != null) {
  97. cfic.close();
  98. destic = new InitialContext(getDestinationJndiProperties());
  99. } else {
  100. destic = cfic;
  101. }
  102. if (_defaultFaultTo != null) {
  103. try {
  104. _faultToJMSDestination = (Destination) destic.lookup(_defaultFaultTo);
  105. } catch (Exception e) {
  106. JCALogger.ROOT_LOGGER.destinationNotFound(_defaultFaultTo, "faultTo");
  107. }
  108. }
  109. if (_defaultReplyTo != null) {
  110. try {
  111. _replyToJMSDestination = (Destination) destic.lookup(_defaultReplyTo);
  112. } catch (Exception e) {
  113. JCALogger.ROOT_LOGGER.destinationNotFound(_defaultReplyTo, "replyTo");
  114. }
  115. }
  116. destic.close();
  117. } catch (Exception e) {
  118. throw JCAMessages.MESSAGES.failedToInitialize(this.getClass().getName(), e);
  119. }
  120. }
  121. @Override
  122. public void onMessage(Message message) {
  123. try {
  124. JMSBindingData bindingData = new JMSBindingData(message);
  125. final String operation = _selector != null ? _selector.selectOperation(bindingData).getLocalPart() : null;
  126. SynchronousInOutHandler replyHandler = new SynchronousInOutHandler();
  127. Exchange exchange = createExchange(operation, replyHandler);
  128. exchange.send(_composer.compose(bindingData, exchange));
  129. Context context = exchange.getContext();
  130. Destination faultTo = getFaultToDestination(context);
  131. Destination replyTo = getReplyToDestination(context);
  132. if (faultTo != null && ExchangeState.FAULT.equals(exchange.getState())) {
  133. if (exchange.getMessage() != null) {
  134. sendJMSMessage(faultTo, exchange, getOutputMessageType(context));
  135. }
  136. } else if (replyTo != null && ExchangePattern.IN_OUT.equals(exchange.getPattern())) {
  137. exchange = replyHandler.waitForOut();
  138. if (exchange.getMessage() != null) {
  139. sendJMSMessage(replyTo, exchange, getOutputMessageType(context));
  140. }
  141. }
  142. } catch (Exception e) {
  143. throw new SwitchYardException(e);
  144. }
  145. }
  146. protected void sendJMSMessage(Destination destination, Exchange exchange, MessageType type) {
  147. Connection connection = null;
  148. try {
  149. if (_userName != null) {
  150. connection = _connectionFactory.createConnection(_userName, _password);
  151. } else {
  152. connection = _connectionFactory.createConnection();
  153. }
  154. Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  155. MessageProducer producer = session.createProducer(destination);
  156. Message msg;
  157. switch (type) {
  158. case Stream:
  159. msg = session.createStreamMessage();
  160. break;
  161. case Map:
  162. msg = session.createMapMessage();
  163. break;
  164. case Text:
  165. msg = session.createTextMessage();
  166. break;
  167. case Bytes:
  168. msg = session.createBytesMessage();
  169. break;
  170. case Plain:
  171. msg = session.createMessage();
  172. break;
  173. default:
  174. msg = session.createObjectMessage();
  175. }
  176. producer.send(_composer.decompose(exchange, new JMSBindingData(msg)).getMessage());
  177. } catch (Exception e) {
  178. JCALogger.ROOT_LOGGER.failedToSendMessage(destination.toString(), e.getMessage());
  179. } finally {
  180. if (connection != null) {
  181. try {
  182. connection.close();
  183. } catch (Exception e) {
  184. JCALogger.ROOT_LOGGER.failedToCloseJMSSessionconnection(e.getMessage());
  185. }
  186. }
  187. }
  188. }
  189. protected Destination getReplyToDestination(Context ctx) {
  190. String key = CONTEXT_PROPERTY_PREFIX + KEY_REPLY_TO;
  191. if (ctx.getProperty(key) != null) {
  192. String destName = ctx.getPropertyValue(key);
  193. try {
  194. return getDestinationFromContext(destName);
  195. } catch (Exception e) {
  196. if (_defaultReplyTo != null) {
  197. JCALogger.ROOT_LOGGER.contextDestinationNotFound(destName, _defaultReplyTo);
  198. } else {
  199. JCALogger.ROOT_LOGGER.destinationNotFound(destName, "replyTo");
  200. }
  201. }
  202. }
  203. return _replyToJMSDestination;
  204. }
  205. protected Destination getFaultToDestination(Context ctx) {
  206. String key = CONTEXT_PROPERTY_PREFIX + KEY_FAULT_TO;
  207. if (ctx.getProperty(key) != null) {
  208. String destName = ctx.getPropertyValue(key);
  209. try {
  210. return getDestinationFromContext(destName);
  211. } catch (Exception e) {
  212. if (_defaultFaultTo != null) {
  213. JCALogger.ROOT_LOGGER.contextDestinationNotFound(destName, _defaultFaultTo);
  214. } else {
  215. JCALogger.ROOT_LOGGER.destinationNotFound(destName, "faultTo");
  216. }
  217. }
  218. }
  219. return _faultToJMSDestination;
  220. }
  221. protected Destination getDestinationFromContext(String destName) throws Exception {
  222. InitialContext ic = null;
  223. try {
  224. if (getDestinationJndiProperties() != null) {
  225. ic = new InitialContext(getDestinationJndiProperties());
  226. } else if (getJndiProperties() != null) {
  227. ic = new InitialContext(getJndiProperties());
  228. } else {
  229. ic = new InitialContext();
  230. }
  231. return (Destination) ic.lookup(destName);
  232. } finally {
  233. if (ic != null) {
  234. try {
  235. ic.close();
  236. } catch (Exception e) {
  237. e.getMessage();
  238. }
  239. }
  240. }
  241. }
  242. protected MessageType getOutputMessageType(Context ctx) {
  243. String key = CONTEXT_PROPERTY_PREFIX + KEY_MESSAGE_TYPE;
  244. if (ctx.getProperty(key) != null) {
  245. return MessageType.valueOf(ctx.getPropertyValue(key).toString());
  246. }
  247. return _defaultOutMessageType;
  248. }
  249. /**
  250. * set ConnectionFactory JNDI name.
  251. *
  252. * @param name ConnectionFactory JNDI name
  253. */
  254. public void setConnectionFactoryJNDIName(String name) {
  255. _connectionFactoryJNDIName = name;
  256. }
  257. /**
  258. * set replyTo destination name.
  259. *
  260. * @param name replyTo destination name
  261. */
  262. public void setReplyTo(String name) {
  263. _defaultReplyTo = name;
  264. }
  265. /**
  266. * set faultTo destination name.
  267. *
  268. * @param name faultTo destination name
  269. */
  270. public void setFaultTo(String name) {
  271. _defaultFaultTo = name;
  272. }
  273. /**
  274. * set user name.
  275. *
  276. * @param user user name
  277. */
  278. public void setUsername(String user) {
  279. _userName = user;
  280. }
  281. /**
  282. * set password.
  283. *
  284. * @param passwd password
  285. */
  286. public void setPassword(String passwd) {
  287. _password = passwd;
  288. }
  289. /**
  290. * set message type.
  291. * @param type message type
  292. */
  293. public void setMessageType(String type) {
  294. _defaultOutMessageType = MessageType.valueOf(type);
  295. }
  296. /**
  297. * set JNDI properties file name.
  298. * @param name file name
  299. */
  300. public void setJndiPropertiesFileName(String name) {
  301. _jndiPropertiesFileName = name;
  302. }
  303. /**
  304. * get JNDI properties.
  305. * @return JNDI properties
  306. */
  307. public Properties getJndiProperties() {
  308. if (_jndiPropertiesFileName != null && _jndiProperties == null) {
  309. try {
  310. InputStream is = Classes.getResourceAsStream(_jndiPropertiesFileName);
  311. Properties props = new Properties();
  312. props.load(is);
  313. is.close();
  314. _jndiProperties = props;
  315. } catch (Exception e) {
  316. JCALogger.ROOT_LOGGER.failedToLoadJndiPropertiesFile(_jndiPropertiesFileName, e);
  317. }
  318. }
  319. return _jndiProperties;
  320. }
  321. /**
  322. * set JNDI properties file name for destination lookup.
  323. * @param name filename
  324. */
  325. public void setDestinationJndiPropertiesFileName(String name) {
  326. _destinationJndiPropertiesFileName = name;
  327. }
  328. /**
  329. * get JNDI properties for destination lookup.
  330. * @return InitialContext properties for destination lookup
  331. */
  332. public Properties getDestinationJndiProperties() {
  333. if (_destinationJndiPropertiesFileName != null && _destinationJndiProperties == null) {
  334. try {
  335. InputStream is = Classes.getResourceAsStream(_destinationJndiPropertiesFileName);
  336. Properties props = new Properties();
  337. props.load(is);
  338. is.close();
  339. _destinationJndiProperties = props;
  340. } catch (Exception e) {
  341. JCALogger.ROOT_LOGGER.failedToLoadJndiPropertiesFile(_destinationJndiPropertiesFileName, e);
  342. }
  343. }
  344. return _destinationJndiProperties;
  345. }
  346. }