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: * @(#)BindingImpl.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package binding1;
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 BindingImpl 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 Binding service.
076: */
077: private static final QName BINDING_SERVICE = new QName(
078: "binding_service");
079:
080: /**
081: * Endpoint name for the Binding service.
082: */
083: private static final String BINDING_ENDPOINT = "binding_endpoint";
084:
085: /**
086: * Service name for the Engine service.
087: */
088: private static final QName ENGINE_SERVICE = new QName(
089: "engine_service");
090:
091: /**
092: * DeliveryChannel for this binding.
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: * Binding-provided endpoint reference.
108: */
109: private ServiceEndpoint mBindingEndpoint;
110:
111: /**
112: * InOnly exchanges.
113: */
114: private Vector mExchanges;
115:
116: /**
117: * Logger instance
118: */
119: private Logger mLog;
120:
121: /**
122: * Constructor for the Binding Implementation.
123: * @param context - the component context for this binding.
124: * @param channel - the delivery channel provided by the NMR.
125: * @param logger - the logger for this binding.
126: */
127: public BindingImpl(ComponentContext context,
128: DeliveryChannel channel, Logger logger) {
129: mComponentName = context.getComponentName();
130: mContext = context;
131: mChannel = channel;
132: mFactory = mChannel.createExchangeFactory();
133: mLog = logger;
134: mExchanges = new Vector();
135: }
136:
137: /**
138: * Initialize.
139: * @throws Exception on any error.
140: */
141: public void init() throws Exception {
142: mLog.info("BindingImpl activating binding endpoint");
143: mBindingEndpoint = mContext.activateEndpoint(BINDING_SERVICE,
144: BINDING_ENDPOINT);
145:
146: DocumentBuilderFactory dbf = DocumentBuilderFactory
147: .newInstance();
148: dbf.setNamespaceAware(true);
149: mDomBuilder = dbf.newDocumentBuilder();
150: }
151:
152: /**
153: * The thread run method which starts the message exchange.
154: */
155: public void run() {
156: try {
157: /**
158: * NOTE: This example provides a serial test of exchanging messages
159: * between a binding and an engine. A single InOnly and OutOnly
160: * object is reused over and over again to keep code bloat down.
161: * Also, the order of the exchanges is lock-step; any change to the
162: * order of sending and receiving may cause this test to fail.
163: */
164:
165: /*############################################
166: *## PING Binding -> Engine ##
167: *###########################################*/
168:
169: // Initiate 'ping' exchange with engine
170: InOnly ping1 = mFactory.createInOnlyExchange();
171: ping1.setEndpoint(mContext
172: .getEndpointsForService(ENGINE_SERVICE)[0]);
173: ping1.setOperation(new QName("EnginePing"));
174: ping1.setInMessage(createMessage(ping1,
175: "Ping message to InOnly service"));
176:
177: mLog.info("Sending ping exchange to engine "
178: + ENGINE_SERVICE);
179: mChannel.send(ping1);
180:
181: ping1 = (InOnly) mChannel.accept();
182: if (ping1.getStatus() != ExchangeStatus.DONE) {
183: throw new javax.jbi.messaging.MessagingException(
184: "Engine ping failed");
185: }
186:
187: mLog.info("Engine ping exchange successful");
188:
189: /*############################################
190: *## PING Engine -> Binding ##
191: *###########################################*/
192:
193: // Accept 'ping' exchange from engine
194: mLog.info("Accepting ping exchange from engine");
195: InOnly ping2 = (InOnly) mChannel.accept();
196: mLog.info("Exchange received, sending done status");
197: ping2.setStatus(ExchangeStatus.DONE);
198: mChannel.send(ping2);
199:
200: /*############################################
201: *## 100 Exchanges Binding -> Engine ##
202: *###########################################*/
203:
204: // Initiate 100 InOnly exchanges with Engine
205: mLog.info("Initiating 100 InOnly Exchanges");
206:
207: InOnly inOnly;
208:
209: for (int j = 0; j < 100; ++j) {
210: // address the exchange, add the in message, and send it
211: inOnly = mFactory.createInOnlyExchange();
212: inOnly.setEndpoint(mContext
213: .getEndpointsForService(ENGINE_SERVICE)[0]);
214: inOnly.setOperation(new QName("InOnlyTest"));
215: inOnly.setInMessage(createMessage(inOnly, "Message "
216: + j + " to InOnly Service"));
217: mChannel.send(inOnly);
218:
219: // track the exchange id
220: mExchanges.add(inOnly.getExchangeId());
221: }
222:
223: // Now perform 100 accepts to get the status on initiated exchanges
224: for (int j = 0; j < 100; ++j) {
225: inOnly = (InOnly) mChannel.accept();
226:
227: if (inOnly.getStatus() != ExchangeStatus.DONE) {
228: throw new javax.jbi.messaging.MessagingException(
229: "exchange received with incomplete/error status");
230: }
231:
232: // remove the exchange id from our list of pending exchanges
233: mExchanges.remove(inOnly.getExchangeId());
234: }
235:
236: // Verify that the pending exchange list is empty
237: if (mExchanges.isEmpty()) {
238: mLog
239: .info("Binding "
240: + mComponentName
241: + " successfully initiated 100 InOnly exchanges to engine");
242: } else {
243: mLog
244: .warning("TEST FAILED: "
245: + mExchanges.size()
246: + " entries remain in the binding's exchange pending list");
247: }
248:
249: /*############################################
250: *## 100 Exchanges Engine -> Binding ##
251: *###########################################*/
252:
253: // Accept 100 message test from binding
254: mLog.info("BindingImpl -- Accepting 100 InOnly Exchanges");
255: for (int j = 0; j < 100; ++j) {
256: inOnly = (InOnly) mChannel.accept();
257: inOnly.setStatus(ExchangeStatus.DONE);
258: mChannel.send(inOnly);
259: }
260:
261: mLog
262: .info("BindingImpl -- Accepted 100 Exchanges Successfully");
263:
264: } catch (javax.jbi.JBIException e1) {
265: mLog.warning("Binding Exception: "
266: + e1.getClass().getName() + ", " + e1);
267: e1.printStackTrace();
268: }
269:
270: }
271:
272: /**
273: * Utility function to create a Normalized message.
274: * @param exchange - the message exchange for which a message is needed.
275: * @param content - the content to be added to the message.
276: * @return the normalized message.
277: */
278: private NormalizedMessage createMessage(MessageExchange exchange,
279: String content) {
280: NormalizedMessage msg = null;
281:
282: try {
283: Document doc;
284: Element ele;
285:
286: msg = exchange.createMessage();
287: doc = mDomBuilder.newDocument();
288: ele = doc.createElement("message");
289:
290: // fill in some content
291: ele.appendChild(doc.createTextNode(content));
292: doc.appendChild(ele);
293:
294: msg.setContent(new DOMSource(doc));
295: } catch (javax.jbi.messaging.MessagingException e1) {
296: mLog.warning("MessagingException " + e1);
297: }
298: return msg;
299: }
300: }
|