001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)JMSConnectionManager.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.binding.proxy.jms;
030:
031: import com.sun.jbi.binding.proxy.LocalStringKeys;
032:
033: import com.sun.jbi.binding.proxy.util.Translator;
034:
035: import com.sun.jbi.binding.proxy.connection.ConnectionHelper;
036: import com.sun.jbi.binding.proxy.connection.ConnectionManager;
037: import com.sun.jbi.binding.proxy.connection.ClientConnection;
038: import com.sun.jbi.binding.proxy.connection.EventConnection;
039: import com.sun.jbi.binding.proxy.connection.EventInfo;
040: import com.sun.jbi.binding.proxy.connection.ServerConnection;
041:
042: import java.util.logging.Logger;
043: import java.util.HashMap;
044:
045: import javax.jms.ConnectionFactory;
046: import javax.jms.Connection;
047: import javax.jms.BytesMessage;
048: import javax.jms.Message;
049: import javax.jms.MessageProducer;
050: import javax.jms.Queue;
051: import javax.jms.Session;
052: import javax.jms.Topic;
053:
054: import javax.naming.InitialContext;
055:
056: /**
057: * Implements a JMS instance of the ConnectionManager contract.
058: * @author Sun Microsystems, Inc
059: */
060: public class JMSConnectionManager implements ConnectionManager {
061: private Logger mLog = Logger
062: .getLogger("com.sun.jbi.binding.proxy.jms");
063:
064: private ConnectionFactory mConnFac;
065: private Connection mTopicConn;
066: private Connection mServerQueueConn;
067: private Connection mClientQueueConn;
068: private ConnectionHelper mHelper;
069: private Topic mTopic;
070: private MessageProducer mProducer;
071: private Session mSharedQueueSession;
072: private HashMap mClientConnections;
073: private JMSServerConnection mSC;
074: private JMSEventConnection mEC;
075: private String mId;
076: private String mExternalId;
077:
078: /** JMS topic name which coordinates registration activity. */
079: private static final String TOPIC_NAME = "SunJbiProxyBindingTopic";
080:
081: /**
082: * Creates a new connection manager.
083: * Four connections to the JMS resource are used:
084: * The SendEvent connection is used to send events (Many synchronized).
085: * The ReceiveEvent connection is used to receive events(EventProcessor)
086: * The Server connection is used to receive messages (RemoteProcessor).
087: * The Client connection is used to send messages (NMRProcessor).
088: * Each connection is used by a single thread (see-above).
089: * Three connections are used due to a restriction on connection when using the JMS RA.
090: *
091: * @param id with unique instance id
092: * @param host of our JMS resource
093: * @param port on the host of our JMS resource
094: * @throws com.sun.jbi.binding.proxy.connection.ConnectionException for any JMS problems.
095: */
096: public JMSConnectionManager(String id, ConnectionHelper helper)
097: throws com.sun.jbi.binding.proxy.connection.ConnectionException {
098: mExternalId = id;
099: mId = sanitizeName(id);
100: mHelper = helper;
101: mLog.fine("Initializing JMS connection manager: ExternalId("
102: + id + ") InternalId(" + mId + ")");
103:
104: try {
105: mClientConnections = new HashMap();
106: mConnFac = helper.getConnectionFactory();
107:
108: mLog.fine("Creating topic and queue connections");
109:
110: mServerQueueConn = mConnFac.createConnection();
111: mClientQueueConn = mConnFac.createConnection();
112: mTopicConn = mConnFac.createConnection();
113:
114: mServerQueueConn.start();
115: mClientQueueConn.start();
116: mTopicConn.start();
117:
118: //
119: // Create the JMSServerConnection and session used to handle inbound messages.
120: //
121: mSC = new JMSServerConnection(this , mServerQueueConn
122: .createSession(false, Session.AUTO_ACKNOWLEDGE),
123: mHelper.getQueue(mId));
124:
125: //
126: // Create the session used to handle all outbound messages.
127: //
128: mSharedQueueSession = mClientQueueConn.createSession(false,
129: Session.AUTO_ACKNOWLEDGE);
130:
131: //
132: // Get the topic used for event send/receive.
133: //
134: mTopic = mHelper.getTopic(TOPIC_NAME);
135:
136: //
137: // Create a local producer for out-of-band (read: different thread) event sending.
138: //
139: mProducer = mSharedQueueSession.createProducer(mTopic);
140:
141: //
142: // Create the event connection for all synchronous event traffic.
143: //
144: mEC = new JMSEventConnection(mTopicConn, mTopic);
145:
146: } catch (Exception ex) {
147: ex.printStackTrace();
148: }
149: }
150:
151: public void prepare()
152: throws com.sun.jbi.binding.proxy.connection.ConnectionException {
153: mHelper.prepare();
154: }
155:
156: /**
157: * Create a JMS ServerConnection.
158: * @return ServerConnection
159: * @throws com.sun.jbi.binding.proxy.connection.ConnectionException for any JMS problems.
160: */
161: public synchronized ServerConnection getServerConnection()
162: throws com.sun.jbi.binding.proxy.connection.ConnectionException {
163: return (mSC);
164: }
165:
166: /**
167: * Get a ClientConnection. This may be a recycled connection or a new connection.
168: * @param id for this connection
169: * @return ClientConnection
170: * @throws com.sun.jbi.binding.proxy.connection.ConnectionException for any JMS problems.
171: */
172: public ClientConnection getClientConnection(String id)
173: throws com.sun.jbi.binding.proxy.connection.ConnectionException {
174: ClientConnection cc;
175: Queue q;
176:
177: cc = (ClientConnection) mClientConnections.get(id);
178: if (cc == null) {
179: cc = new JMSClientConnection(mSC, mSharedQueueSession,
180: mHelper.getQueue(id));
181: mClientConnections.put(id, cc);
182: }
183: return (cc);
184: }
185:
186: /**
187: * Get a ClientConnection based on JMS BytesMessage. Used to capture the JMSReplyTo as the
188: * instanceId.
189: * @param message used to capture instance id.
190: * @return ClientConnection
191: * @throws com.sun.jbi.binding.proxy.connection.ConnectionException for any JMS problems.
192: */
193: ClientConnection getClientConnection(BytesMessage message)
194: throws com.sun.jbi.binding.proxy.connection.ConnectionException {
195: JMSClientConnection cc;
196: String id = null;
197:
198: try {
199: id = ((Queue) message.getJMSReplyTo()).getQueueName();
200:
201: cc = (JMSClientConnection) mClientConnections.get(id);
202: if (cc == null) {
203: cc = new JMSClientConnection(mSC, mSharedQueueSession,
204: mHelper.getQueue(id));
205: mClientConnections.put(id, cc);
206: }
207: cc.setMessage(message);
208: return (cc);
209: } catch (javax.jms.JMSException jEx) {
210: throw new com.sun.jbi.binding.proxy.connection.ConnectionException(
211: Translator
212: .translate(
213: LocalStringKeys.CANT_CREATE_JMS_QUEUESESSION,
214: id), jEx);
215: }
216: }
217:
218: /**
219: * Create and send an Event. This is used when the event is being generated in a context
220: * different from the normall event processing loop.
221: */
222: public void queueEvent(EventInfo info)
223: throws com.sun.jbi.binding.proxy.connection.EventException {
224: JMSEvent e;
225: Message m;
226: try {
227: e = new JMSEvent(mSharedQueueSession.createStreamMessage(),
228: info.getEventName());
229: info.encodeEvent(e);
230: m = e.getMessage();
231: m.setJMSType(mId);
232: mProducer.send(e.getMessage());
233: } catch (javax.jms.JMSException jmsEx) {
234: throw new com.sun.jbi.binding.proxy.connection.EventException(
235: jmsEx);
236: }
237: }
238:
239: /**
240: * Get an EventConnection.
241: * @return EventConnection
242: * @throws com.sun.jbi.binding.proxy.connection.ConnectionException for any JMS problems.
243: */
244: public synchronized EventConnection getEventConnection()
245: throws com.sun.jbi.binding.proxy.connection.ConnectionException {
246: return (mEC);
247: }
248:
249: /**
250: * Close the EventConnection.
251: * @throws javax.jbi.JBIException if there is a problem.
252: */
253: public void closeServerConnection() {
254: try {
255: mServerQueueConn.close();
256: } catch (javax.jms.JMSException jEx) {
257: mLog.info(Translator.translate(
258: LocalStringKeys.CLOSE_SERVERCONN, jEx));
259: }
260: }
261:
262: /**
263: * Close the EventConnection.
264: */
265: public void closeClientConnection() {
266: try {
267: mClientQueueConn.close();
268: } catch (javax.jms.JMSException jEx) {
269: mLog.info(Translator.translate(
270: LocalStringKeys.CLOSE_CLIENTCONN, jEx));
271: }
272:
273: }
274:
275: /**
276: * Close the EventConnection.
277: */
278: public void closeEventConnection() {
279: try {
280: mTopicConn.close();
281: } catch (javax.jms.JMSException jEx) {
282: mLog.info(Translator.translate(
283: LocalStringKeys.CLOSE_EVENTCONN, jEx));
284: }
285:
286: }
287:
288: /**
289: * Gets the instance id of this connection.,
290: * @return String containing instance id.
291: */
292: public String getInstanceId() {
293: return (mId);
294: }
295:
296: /**
297: * Gets the instance id of this connection.,
298: * @return String containing instance id.
299: */
300: public String getExternalInstanceId() {
301: return (mExternalId);
302: }
303:
304: /**
305: * Takes an external name and converts it into a viable JMS Queue name.
306: * @param is to be sanitized
307: * @return String containing the sanitized id.
308: */
309: String sanitizeName(String id) {
310: StringBuffer sb = new StringBuffer();
311:
312: for (int i = 0; i < id.length(); i++) {
313: char ch = id.charAt(i);
314:
315: if (ch == '@') {
316: sb.append("_at_");
317: } else if (ch == '_') {
318: sb.append("__");
319: } else if (ch == '.') {
320: sb.append("_dot_");
321: } else if (ch == ':') {
322: sb.append("_colon_");
323: } else if (ch == '-') {
324: sb.append("_minus_");
325: } else {
326: sb.append(ch);
327: }
328: }
329:
330: return (sb.toString());
331: }
332: }
|