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: * @(#)EngineImpl.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package engine1;
030:
031: import java.util.Vector;
032: import java.util.logging.Logger;
033:
034: import javax.jbi.component.ComponentContext;
035:
036: import javax.jbi.messaging.DeliveryChannel;
037: import javax.jbi.messaging.ExchangeStatus;
038: import javax.jbi.messaging.InOnly;
039: import javax.jbi.messaging.NormalizedMessage;
040: import javax.jbi.messaging.MessageExchange;
041: import javax.jbi.messaging.MessageExchangeFactory;
042:
043: import javax.jbi.servicedesc.ServiceEndpoint;
044:
045: import javax.xml.namespace.QName;
046: import javax.xml.parsers.DocumentBuilder;
047: import javax.xml.parsers.DocumentBuilderFactory;
048: import javax.xml.transform.dom.DOMSource;
049:
050: import org.w3c.dom.Document;
051: import org.w3c.dom.Element;
052:
053: /**
054: * This test exercises one way MEPs in both directions (InOnly, OutOnly). The
055: * binding begins by initiating an InOnly exchnage with the engine. Once that
056: * completes the binding initiates 100 exchanges with the engine in a serial
057: * fashion. This process reverses from the engine perspective (with OutOnly)
058: * after the InOnly portion completes.
059: *
060: * @author Sun Microsystems, Inc.
061: */
062:
063: public class EngineImpl extends Thread {
064: /**
065: * Local copy of the component name
066: */
067: private String mComponentName;
068:
069: /**
070: * Local copy of the component context
071: */
072: private ComponentContext mContext;
073:
074: /**
075: * Service name for the Engine service.
076: */
077: private static final QName ENGINE_SERVICE = new QName(
078: "engine_service");
079:
080: /**
081: * Endpoint name for the Engine service.
082: */
083: private static final String ENGINE_ENDPOINT = "engine_endpoint";
084:
085: /**
086: * Service name for the Binding service.
087: */
088: private static final QName BINDING_SERVICE = new QName(
089: "binding_service");
090:
091: /**
092: * Delivery Channel.
093: */
094: private DeliveryChannel mChannel;
095:
096: /**
097: * Factory for creating message exchanges.
098: */
099: private MessageExchangeFactory mFactory;
100:
101: /**
102: * XML Document builder.
103: */
104: private DocumentBuilder mDomBuilder;
105:
106: /**
107: * ServiceEndpoint for binding-provided service.
108: */
109: private ServiceEndpoint mBindingEndpoint;
110:
111: /**
112: * ServiceEndpoint for engine-provided service.
113: */
114: private ServiceEndpoint mEngineEndpoint;
115:
116: /**
117: * OutOnly exchanges.
118: */
119: private Vector mExchanges;
120:
121: /**
122: * Logger instance.
123: */
124: private Logger mLog;
125:
126: /**
127: * Constructor for the Engine Implementation.
128: * @param context - the component context for this engine.
129: * @param channel - the DeliveryChannel from the NMR.
130: * @param logger - the logger instance for this engine.
131: */
132: public EngineImpl(ComponentContext context,
133: DeliveryChannel channel, Logger logger) {
134: mContext = context;
135: mComponentName = context.getComponentName();
136: mChannel = channel;
137: mFactory = mChannel.createExchangeFactory();
138: mLog = logger;
139: mExchanges = new Vector();
140: }
141:
142: /**
143: * Activate endpoints at init() time.
144: * @throws Exception on any error.
145: */
146: public void init() throws Exception {
147: mLog.info("EngineImpl activating engine endpoint");
148: mEngineEndpoint = mContext.activateEndpoint(ENGINE_SERVICE,
149: ENGINE_ENDPOINT);
150:
151: DocumentBuilderFactory dbf = DocumentBuilderFactory
152: .newInstance();
153: dbf.setNamespaceAware(true);
154: mDomBuilder = dbf.newDocumentBuilder();
155: }
156:
157: /**
158: * The thread run method which starts the message exchange.
159: */
160: public void run() {
161: try {
162: /**
163: * NOTE : This example provides a serial test of exchanging messages
164: * between an engine and a binding. A single InOnly and OutOnly
165: * object is reused over and over again to keep code bloat down.
166: * Also, the order of the exchanges is lock-step; any change to the
167: * order of sending and receiving may cause this test to fail.
168: */
169:
170: /*############################################
171: *## PING Binding -> Engine ##
172: *###########################################*/
173:
174: // Accept 'ping' exchange from binding
175: mLog.info("Accepting ping exchange from binding");
176: InOnly ping1 = (InOnly) mChannel.accept();
177: mLog.info("Exchange received, sending done status");
178: ping1.setStatus(ExchangeStatus.DONE);
179: mChannel.send(ping1);
180:
181: /*############################################
182: *## PING Engine -> Binding ##
183: *###########################################*/
184:
185: // Initiate 'ping' exchange with binding
186: InOnly ping2 = mFactory.createInOnlyExchange();
187: ping2.setEndpoint(mContext
188: .getEndpointsForService(BINDING_SERVICE)[0]);
189: ping2.setOperation(new QName("BindingPing"));
190: ping2.setInMessage(createMessage(ping2,
191: "Ping message to binding"));
192:
193: mLog.info("Sending ping exchange to binding "
194: + BINDING_SERVICE);
195: mChannel.send(ping2);
196:
197: ping2 = (InOnly) mChannel.accept();
198: if (ping2.getStatus() != ExchangeStatus.DONE) {
199: throw new javax.jbi.messaging.MessagingException(
200: "Binding ping failed");
201: }
202:
203: mLog.info("Binding ping exchange successful");
204:
205: /*############################################
206: *## 100 Exchanges Binding -> Engine ##
207: *###########################################*/
208:
209: // Accept 100 message test from binding
210: mLog.info("EngineImpl -- Accepting 100 InOnly Exchanges");
211: for (int j = 0; j < 100; ++j) {
212: InOnly inOnly = (InOnly) mChannel.accept();
213: inOnly.setStatus(ExchangeStatus.DONE);
214: mChannel.send(inOnly);
215: }
216:
217: mLog
218: .info("EngineImpl -- Accepted 100 Exchanges Successfully");
219:
220: /*############################################
221: *## 100 Exchanges Engine -> Binding ##
222: *###########################################*/
223:
224: InOnly inOnly;
225:
226: // Initiate 100 OutOnly exchanges with Binding
227: mLog.info("Initiating 100 InOnly Exchanges");
228: for (int j = 0; j < 100; ++j) {
229: // address the exchange, add the in message, and send it
230: inOnly = mFactory.createInOnlyExchange();
231: inOnly.setEndpoint(mContext
232: .getEndpointsForService(BINDING_SERVICE)[0]);
233: inOnly.setOperation(new QName("InOnlyTest"));
234: inOnly.setInMessage(createMessage(inOnly, "Message "
235: + j + " to Binding"));
236: mChannel.send(inOnly);
237:
238: // track the exchange id
239: mExchanges.add(inOnly.getExchangeId());
240: }
241:
242: // Now perform 100 accepts to get the status on initiated exchanges
243: for (int j = 0; j < 100; ++j) {
244: inOnly = (InOnly) mChannel.accept();
245:
246: if (inOnly.getStatus() != ExchangeStatus.DONE) {
247: throw new javax.jbi.messaging.MessagingException(
248: "exchange received with incomplete/error status");
249: }
250:
251: // remove the exchange id from our list of pending exchanges
252: mExchanges.remove(inOnly.getExchangeId());
253: }
254:
255: // Verify that the pending exchange list is empty
256: if (mExchanges.isEmpty()) {
257: mLog
258: .info("Engine "
259: + mComponentName
260: + " successfully initiated 100 InOnly exchanges to binding");
261: } else {
262: mLog
263: .warning("TEST FAILED: "
264: + mExchanges.size()
265: + " entries remain in the engine's exchange pending list");
266: }
267:
268: } catch (javax.jbi.JBIException e1) {
269: mLog.warning("Engine Exception: " + e1);
270: }
271: }
272:
273: /**
274: * Utility function to create a Normalized message.
275: * @param exchange - the MessageExchange for which a message is needed.
276: * @param content - the content to be added to the message.
277: * @return a normalized message.
278: */
279: private NormalizedMessage createMessage(MessageExchange exchange,
280: String content) {
281: NormalizedMessage msg = null;
282:
283: try {
284: Document doc;
285: Element ele;
286:
287: msg = exchange.createMessage();
288: doc = mDomBuilder.newDocument();
289: ele = doc.createElement("message");
290:
291: // fill in some content
292: ele.appendChild(doc.createTextNode(content));
293: doc.appendChild(ele);
294:
295: msg.setContent(new DOMSource(doc));
296: } catch (javax.jbi.messaging.MessagingException e1) {
297: mLog.warning("MessagingException " + e1);
298: }
299: return msg;
300: }
301: }
|