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: * @(#)PBTestEngine.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package TestEngine;
030:
031: import java.io.IOException;
032: import java.io.PrintWriter;
033: import java.io.InputStreamReader;
034: import java.io.StringReader;
035:
036: import java.util.logging.Logger;
037:
038: import javax.activation.DataHandler;
039:
040: import javax.jbi.component.Component;
041: import javax.jbi.component.ComponentLifeCycle;
042: import javax.jbi.component.ComponentContext;
043: import javax.jbi.component.ServiceUnitManager;
044:
045: import javax.jbi.messaging.DeliveryChannel;
046: import javax.jbi.messaging.ExchangeStatus;
047: import javax.jbi.messaging.Fault;
048: import javax.jbi.messaging.InOut;
049: import javax.jbi.messaging.InOptionalOut;
050: import javax.jbi.messaging.InOnly;
051: import javax.jbi.messaging.MessageExchange;
052: import javax.jbi.messaging.NormalizedMessage;
053:
054: import javax.jbi.servicedesc.ServiceEndpoint;
055:
056: import javax.naming.InitialContext;
057:
058: import javax.xml.namespace.QName;
059: import javax.xml.parsers.DocumentBuilder;
060: import javax.xml.parsers.DocumentBuilderFactory;
061: import javax.xml.transform.Source;
062: import javax.xml.transform.Transformer;
063: import javax.xml.transform.TransformerFactory;
064: import javax.xml.transform.stream.StreamSource;
065: import javax.xml.transform.dom.DOMSource;
066: import javax.xml.transform.dom.DOMResult;
067:
068: import org.w3c.dom.Document;
069: import org.w3c.dom.DocumentFragment;
070: import org.w3c.dom.Element;
071:
072: /**
073: * This is a servlet that acts as a Service Engine and tests the dynamic
074: * registration support provided by JBI. It registers itself as an engine and
075: * then performs a fixed set of message exchanges with another servlet that
076: * acts as a Binding Component. That servlet is ESBBindingServlet.
077: *
078: * @author Sun Microsystems, Inc.
079: */
080: public class PBTestEngine implements Component, ComponentLifeCycle {
081:
082: /**
083: * Logger for the servlet.
084: */
085: private java.util.logging.Logger mLog;
086:
087: /**
088: * Handle to the XML Document Builder.
089: */
090: private DocumentBuilder mDocumentBuilder;
091:
092: /**
093: * Engine channel for NMS communications.
094: */
095: private DeliveryChannel mChannel;
096:
097: /**
098: * Engine's endpoint.
099: */
100: private ServiceEndpoint mEngineEndpoint1;
101: private ServiceEndpoint mEngineEndpoint2;
102:
103: /**
104: * Component LifeCycle.
105: */
106: private ComponentContext mContext;
107:
108: /**
109: * Runner Thread.
110: */
111: private Thread mRunnerThread;
112: private boolean mRunning;
113:
114: /**
115: * The action for an initialize request.
116: */
117: private static final String ACTION_INIT = "init";
118:
119: /**
120: * The action for a pingbinding request.
121: */
122: private static final String ACTION_START = "dostart";
123:
124: /**
125: * The action for a acceptping request.
126: */
127: private static final String ACTION_STOP = "dostop";
128:
129: /**
130: * The engine's service name.
131: */
132: private static final QName ENGINE_SERVICE = new QName(
133: "pb-test-engine_service");
134:
135: /**
136: * Qualified name for the binding's service.
137: */
138: private static final QName BINDING_SERVICE = new QName(
139: "pb-test-binding_service");
140:
141: /**
142: * The engine's endpoint name.
143: */
144: private static final String ENGINE_ENDPOINT1 = "pb-test-engine_endpoint1";
145: private static final String ENGINE_ENDPOINT2 = "pb-test-engine_endpoint2";
146:
147: /**
148: * JBI component name
149: */
150: private static final String JBI_COMPONENT_NAME = "PBTestEngine";
151:
152: /**
153: * JBI component description
154: */
155: private static final String JBI_COMPONENT_DESC = "PBTestEngine acting as an SE";
156:
157: public PBTestEngine() {
158: mLog = Logger.getLogger(this .getClass().getPackage().getName());
159: }
160:
161: //--------------------------- Component Methods ------------------------------
162:
163: /**
164: * Get the ComponentLifeCycle instance.
165: * @return The ComponentLifeCycle instance for this component.
166: */
167: public ComponentLifeCycle getLifeCycle() {
168: mLog.info("Component getLifeCycle() called");
169: return this ;
170: }
171:
172: /**
173: * Get the ServiceUnitManager instance.
174: * @return The ServiceUnitManager instance, which is always null for
175: * this test.
176: */
177: public ServiceUnitManager getServiceUnitManager() {
178: mLog.info("Component getServiceUnitManager() called");
179: return null;
180: }
181:
182: /**
183: * This method is called by JBI to check if this component, in the role of
184: * provider of the service indicated by the given exchange, can actually
185: * perform the operation desired.
186: *
187: * @param endpoint
188: * @param exchange
189: *
190: * @return true if its OK.
191: */
192: public boolean isExchangeWithConsumerOkay(
193: javax.jbi.servicedesc.ServiceEndpoint endpoint,
194: javax.jbi.messaging.MessageExchange exchange) {
195: /* Should not always return true
196: * The capabilities of this component has to be checked first.
197: * Not implemented right now
198: */
199: return true;
200: }
201:
202: /**
203: * This method is called by JBI to check if this component, in the role of
204: * consumer of the service indicated by the given exchange, can actually
205: * interact with the the provider completely.
206: *
207: * @param endpoint
208: * @param exchange
209: *
210: * @return true if OK.
211: */
212: public boolean isExchangeWithProviderOkay(
213: javax.jbi.servicedesc.ServiceEndpoint endpoint,
214: javax.jbi.messaging.MessageExchange exchange) {
215: /* Should not always return true
216: * The capabilities of this component has to be checked first.
217: * Not implemented right now
218: */
219: return true;
220: }
221:
222: /**
223: * Returns a resolver for meta-data.
224: *
225: * @param ServiceEndpoint endpoint reference object.
226: *
227: * @return Descriptor for this engine.
228: */
229: public org.w3c.dom.Document getServiceDescription(
230: javax.jbi.servicedesc.ServiceEndpoint ServiceEndpoint) {
231: org.w3c.dom.Document desc = null;
232:
233: try {
234: Source source;
235: DOMResult dr;
236: Transformer transform;
237: String wsdl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
238: + "<definitions xmlns=\"http://www.w3.org/2006/01/wsdl\" "
239: + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
240: + "xsi:schemaLocation=\"http://www.w3.org/2006/01/wsdl wsdl20.xsd\" "
241: + "targetNamespace=\"http://sun.com/proxybinding.wsdl\">"
242: + "<interface name=\"testPBIF\">"
243: + "<operation name=\"transform\" style=\"http://www.w3.org/2006/01/wsdl/style/rpc\" "
244: + "pattern=\"http://www.w3.org/2006/01/wsdl/in-out\">"
245: + "<input messageLabel=\"A\" />"
246: + "<output messageLabel=\"B\" />"
247: + "</operation>"
248: + "</interface>"
249: + "<binding name=\"testPB\" interface=\"tns:testPBIF\" "
250: + "type=\"http://sun.com/jbi/wsdl/proxybinding10\">"
251: + "<operation ref=\"transform\">"
252: + "<input messageLabel=\"A\">"
253: + "</input>"
254: + "<output messageLabel=\"B\">"
255: + "</output>"
256: + "</operation>"
257: + "</binding>"
258: + "<service name=\"testPBService\" interface=\"tns:testPBIF\">"
259: + "<documentation>"
260: + "Tests the ProxyBinding service."
261: + "</documentation>"
262: + "<endpoint name=\"testPB\" binding=\"tns:testPB\"/>"
263: + "</service>" + "</definitions>";
264: source = new StreamSource(new StringReader(wsdl));
265: transform = TransformerFactory.newInstance()
266: .newTransformer();
267: transform.transform(source, dr = new DOMResult());
268: desc = (Document) dr.getNode();
269: } catch (Exception e) {
270: mLog.info("PBTestEngine: getServiceDescription failed: "
271: + e);
272: }
273:
274: return desc;
275: }
276:
277: /**
278: * Resolve the endpoint reference using the given capabilities of the
279: * consumer. This is called by JBI when its trying to resove the given EPR
280: * on behalf of the component.
281: *
282: * @param epr endpoint reference.
283: *
284: * @return Service enpoint.
285: */
286: public ServiceEndpoint resolveEndpointReference(DocumentFragment epr) {
287: return mEngineEndpoint1;
288: }
289:
290: //----------------------- ComponentLifeCycle Methods -------------------------
291:
292: /**
293: * Initializes the JBI LifeCycle. This creates/opens a delivery channel
294: * for the servlet to use for interactions with the NMR.
295: * @param context - the component context provided by the JBI framework.
296: * @throws javax.jbi.JBIException if any error occurs.
297: */
298: public void init(ComponentContext context)
299: throws javax.jbi.JBIException {
300: mLog.info("PBTEstEngine: LifeCycle init() entered");
301:
302: DocumentBuilderFactory dbf = DocumentBuilderFactory
303: .newInstance();
304: dbf.setNamespaceAware(true);
305: try {
306: mDocumentBuilder = dbf.newDocumentBuilder();
307: } catch (javax.xml.parsers.ParserConfigurationException pcEx) {
308: throw new javax.jbi.JBIException(
309: "Unable to create new DocumentBuilder instance: "
310: + pcEx, pcEx);
311: }
312:
313: getServiceDescription(null);
314:
315: mContext = context;
316: mChannel = mContext.getDeliveryChannel();
317: mEngineEndpoint1 = mContext.activateEndpoint(ENGINE_SERVICE,
318: ENGINE_ENDPOINT1);
319: mEngineEndpoint2 = mContext.activateEndpoint(ENGINE_SERVICE,
320: ENGINE_ENDPOINT2);
321:
322: mLog.info("PBTEstEngine: LifeCycle init() exited");
323: }
324:
325: /**
326: * Get the Extension MBean name.
327: * @return The JMX object name of the Extension MBean for this SE,
328: * which is always null in this test.
329: */
330: public javax.management.ObjectName getExtensionMBeanName() {
331: return null;
332: }
333:
334: /**
335: * Start the JBI LifeCycle. This activates an inbound service and an
336: * outbound service for use in message exchanges with the binding servlet.
337: * @throws javax.jbi.JBIException if any error occurs.
338: */
339: public void start() throws javax.jbi.JBIException {
340: mLog.info("PBTestEngine: LifeCycle start() entered");
341: mRunning = true;
342: mRunnerThread = new Thread(new EngineRunner());
343: mRunnerThread.setName("PBTestEngine-Runner");
344: mRunnerThread.setDaemon(true);
345: mRunnerThread.start();
346: mLog.info("PBTestEngine: LifeCycle start() exited");
347: }
348:
349: /**
350: * Stop the JBI LifeCycle. This deactivates the inbound and outbound
351: * services.
352: * @throws javax.jbi.JBIException if any error occurs.
353: */
354: public void stop() throws javax.jbi.JBIException {
355: mLog.info("PBTestEngine: LifeCycle stop() entered");
356: mRunning = false;
357: mRunnerThread.interrupt();
358: mContext
359: .deactivateEndpoint((javax.jbi.servicedesc.ServiceEndpoint) mEngineEndpoint1);
360: mContext
361: .deactivateEndpoint((javax.jbi.servicedesc.ServiceEndpoint) mEngineEndpoint2);
362:
363: mLog.info("PBTestEngine: LifeCycle stop() exited");
364: }
365:
366: /**
367: * Shutdown the JBI LifeCycle. This closes the engine channel.
368: * @throws javax.jbi.JBIException if any error occurs.
369: */
370: public void shutDown() throws javax.jbi.JBIException {
371: mLog.info("PBTestEngine: LifeCycle shutDown() entered");
372:
373: mChannel.close();
374:
375: mLog.info("PBTestEngine: LifeCycle shutDown() exited");
376: }
377:
378: //----------------------------- Private Methods ------------------------------
379:
380: /**
381: * Create a Normalized Message.
382: * @param exchange - a MessageExchange for which a message is to be created.
383: * @param content - a String containing the message content.
384: * @return The NormalizedMessage instance with the provided content.
385: */
386: private NormalizedMessage createMessage(MessageExchange exchange,
387: String content) {
388: NormalizedMessage msg = null;
389: try {
390: Document doc;
391: Element elem;
392: msg = exchange.createMessage();
393: doc = mDocumentBuilder.newDocument();
394: elem = doc.createElement("message");
395: elem.appendChild(doc.createTextNode(content));
396: doc.appendChild(elem);
397: msg.setContent(new DOMSource(doc));
398: } catch (javax.jbi.messaging.MessagingException ex) {
399: mLog.warning("MessagingException " + ex.toString());
400: }
401: return msg;
402: }
403:
404: /**
405: * Create a Normalized Message.
406: * @param exchange - a MessageExchange for which a message is to be created.
407: * @param content - a String containing the message content.
408: * @return The NormalizedMessage instance with the provided content.
409: */
410: private Fault createFault(MessageExchange exchange, String content) {
411: Fault fault = null;
412: try {
413: Document doc;
414: Element elem;
415: fault = exchange.createFault();
416: doc = mDocumentBuilder.newDocument();
417: elem = doc.createElement("message");
418: elem.appendChild(doc.createTextNode(content));
419: doc.appendChild(elem);
420: fault.setContent(new DOMSource(doc));
421: } catch (javax.jbi.messaging.MessagingException ex) {
422: mLog.warning("MessagingException " + ex.toString());
423: }
424: return fault;
425: }
426:
427: class EngineRunner implements java.lang.Runnable {
428: public void run() {
429: MessageExchange me;
430: boolean expectFailure = false;
431:
432: mLog.info("PBTestEngine: Start processing requests");
433:
434: String respMsg = null;
435: String a;
436:
437: while (mRunning) {
438: try {
439: expectFailure = false;
440: respMsg = null;
441: me = mChannel.accept();
442: if (me instanceof InOut) {
443: InOut io = (InOut) me;
444:
445: mLog
446: .info("PBTestEngine: InOut exchange received");
447: io
448: .setOutMessage(createMessage(io,
449: "PBTestEngine message to InOut service"));
450: io.setProperty("InOutProp", "OK");
451: mChannel.send(io);
452: io = (InOut) mChannel.accept();
453: if (io.getStatus() != ExchangeStatus.DONE) {
454: mLog.warning("PBTestEngine: InOut failed");
455: }
456: mLog
457: .info("PBTestEngine: InOut exchange finished");
458: } else if (me instanceof InOnly) {
459: InOnly io = (InOnly) me;
460: mLog
461: .info("PBTestEngine: InOnly exchange received");
462: if (!getAttachment(me)
463: .equals(
464: "This is the contents of the attachment.")) {
465: io.setStatus(ExchangeStatus.ERROR);
466: io.setProperty("InOnlyProp", "OK");
467: mChannel.send(io);
468: mLog
469: .warning("PBTestEngine: InOnly attachment content error");
470: } else {
471: if (io.getOperation().getLocalPart()
472: .equals("InOnlyTimeout")) {
473: expectFailure = true;
474: synchronized (this ) {
475: this .wait(6000);
476: }
477: }
478: io.setStatus(ExchangeStatus.DONE);
479: mChannel.send(io);
480: mLog
481: .info("PBTestEngine: InOnly exchange finished");
482: }
483: } else if (me instanceof InOptionalOut) {
484: InOptionalOut io = (InOptionalOut) me;
485: Fault f;
486:
487: mLog
488: .info("PBTestEngine: InOptionalOut exchange received");
489: f = createFault(io, "Fault");
490: io.setFault(f);
491: io.setProperty("InOptionalOutProp", "OK");
492: mChannel.send(io);
493: io = (InOptionalOut) mChannel.accept();
494: if (io.getStatus() != ExchangeStatus.DONE) {
495: mLog
496: .warning("PBTestEngine: InOptionalOut failed");
497: }
498: mLog.info("PBTestEngine: In exchange finished");
499: }
500: } catch (javax.jbi.messaging.MessagingException mEx) {
501: respMsg = "PBTestEngine: Messaging error: " + mEx;
502: if (!expectFailure) {
503: mRunning = false;
504: }
505: } catch (java.lang.InterruptedException iEx) {
506: mLog
507: .warning("PBTestEngine: Interrupted Exception: "
508: + iEx);
509: mRunning = false;
510: }
511: }
512:
513: mLog.info("PBTestEngine: Processing stopping");
514: }
515: }
516:
517: String getAttachment(MessageExchange me) {
518: NormalizedMessage nm;
519: DataHandler a;
520: StringBuffer s = new StringBuffer();
521: int c;
522:
523: try {
524: nm = me.getMessage("in");
525: a = nm.getAttachment("Attachment1");
526: InputStreamReader isr = new InputStreamReader(a
527: .getInputStream());
528: while ((c = isr.read()) != -1) {
529: s.append((char) c);
530: }
531: return (s.toString());
532: } catch (java.io.IOException ioEx) {
533: }
534: return (null);
535: }
536: }
|