001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.jaxws.provider.soapmsg;
020:
021: import org.apache.axis2.jaxws.TestLogger;
022:
023: import java.io.ByteArrayInputStream;
024: import java.io.ByteArrayOutputStream;
025: import java.io.InputStream;
026: import java.util.Iterator;
027:
028: import javax.xml.namespace.QName;
029: import javax.xml.soap.AttachmentPart;
030: import javax.xml.soap.Detail;
031: import javax.xml.soap.MessageFactory;
032: import javax.xml.soap.Name;
033: import javax.xml.soap.Node;
034: import javax.xml.soap.SOAPBody;
035: import javax.xml.soap.SOAPConstants;
036: import javax.xml.soap.SOAPElement;
037: import javax.xml.soap.SOAPFactory;
038: import javax.xml.soap.SOAPFault;
039: import javax.xml.soap.SOAPMessage;
040: import javax.xml.transform.OutputKeys;
041: import javax.xml.transform.Result;
042: import javax.xml.transform.Transformer;
043: import javax.xml.transform.TransformerFactory;
044: import javax.xml.transform.stream.StreamResult;
045: import javax.xml.transform.stream.StreamSource;
046: import javax.xml.ws.BindingType;
047: import javax.xml.ws.Provider;
048: import javax.xml.ws.Service;
049: import javax.xml.ws.ServiceMode;
050: import javax.xml.ws.WebServiceException;
051: import javax.xml.ws.WebServiceProvider;
052: import javax.xml.ws.soap.SOAPBinding;
053: import javax.xml.ws.soap.SOAPFaultException;
054:
055: @WebServiceProvider()
056: @ServiceMode(value=Service.Mode.MESSAGE)
057: public class SoapMessageProvider implements Provider<SOAPMessage> {
058:
059: String responseMsgStart = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Header/><soapenv:Body>";
060: String responseMsgEnd = "</soapenv:Body></soapenv:Envelope>";
061:
062: // Requests and Response values of invoke_str and return_str
063: // These constants are referenced by the SoapMessageProviderTest and SoapMessageProvider
064: public static String RESPONSE_NAME = "ReturnType";
065: public static String RESPONSE_DATA_NAME = "return_str";
066: public static String REQUEST_NAME = "invokeOp";
067: public static String REQUEST_DATA_NAME = "invoke_str";
068:
069: public static String XML_REQUEST = "xml request";
070: public static String XML_RESPONSE = "xml response";
071: public static String XML_EMPTYBODY_REQUEST = "xml empty body request";
072: public static String XML_ATTACHMENT_REQUEST = "xml and attachment request";
073: public static String XML_ATTACHMENT_RESPONSE = "xml and attachment response";
074: public static String XML_MTOM_REQUEST = "xml and mtom request";
075: public static String XML_MTOM_RESPONSE = "xml and mtom response";
076: public static String XML_SWAREF_REQUEST = "xml and swaref request";
077: public static String XML_SWAREF_RESPONSE = "xml and swaref response";
078: public static String XML_FAULT_REQUEST = "xml fault";
079: public static String XML_WSE_REQUEST = "xml wse fault";
080:
081: private String XML_RETURN = "<ns2:ReturnType xmlns:ns2=\"http://test\"><return_str>"
082: + SoapMessageProvider.XML_RESPONSE
083: + "</return_str></ns2:ReturnType>";
084: private String ATTACHMENT_RETURN = "<ns2:ReturnType xmlns:ns2=\"http://test\"><return_str>"
085: + SoapMessageProvider.XML_ATTACHMENT_RESPONSE
086: + "</return_str></ns2:ReturnType>";
087: private String MTOM_RETURN = "<ns2:ReturnType xmlns:ns2=\"http://test\"><return_str>"
088: + SoapMessageProvider.XML_MTOM_RESPONSE
089: + "</return_str>"
090: + SoapMessageProvider.MTOM_REF + "</ns2:ReturnType>";
091: private String SWAREF_RETURN = "<ns2:ReturnType xmlns:ns2=\"http://test\"><return_str>"
092: + SoapMessageProvider.XML_SWAREF_RESPONSE
093: + "</return_str>"
094: + SoapMessageProvider.SWAREF_REF + "</ns2:ReturnType>";
095:
096: public static String TEXT_XML_ATTACHMENT = "<myAttachment>Hello World</myAttachment>";
097: public static String ID = "helloWorld123";
098:
099: public static String MTOM_REF = "<data>" + "<xop:Include href='"
100: + ID
101: + "' xmlns:xop='http://www.w3.org/2004/08/xop/include' />"
102: + "</data>";
103: public static String SWAREF_REF = "<data>" + "cid:" + ID
104: + "</data>";
105:
106: public SOAPMessage invoke(SOAPMessage soapMessage)
107: throws SOAPFaultException {
108: TestLogger.logger
109: .debug(">> SoapMessageProvider: Request received.");
110:
111: try {
112: // Look at the incoming request message
113: //System.out.println(">> Request on Server:");
114: //soapMessage.writeTo(System.out);
115: //System.out.println("\n");
116:
117: // Get the discrimination element. This performs basic assertions on the received message
118: SOAPElement discElement = assertRequestXML(soapMessage);
119:
120: // Use the data element text to determine the type of response to send
121: SOAPMessage response = null;
122: // TODO AXIS2 SAAJ should (but does not) support the getTextContent();
123: // String text = dataElement.getTextContent();
124: String text = discElement.getValue();
125: if (XML_REQUEST.equals(text)) {
126: response = getXMLResponse(soapMessage, discElement);
127: } else if (XML_EMPTYBODY_REQUEST.equals(text)) {
128: response = getXMLEmptyBodyResponse(soapMessage,
129: discElement);
130: } else if (XML_ATTACHMENT_REQUEST.equals(text)) {
131: response = getXMLAttachmentResponse(soapMessage,
132: discElement);
133: } else if (XML_MTOM_REQUEST.equals(text)) {
134: response = getXMLMTOMResponse(soapMessage, discElement);
135: } else if (XML_SWAREF_REQUEST.equals(text)) {
136: response = getXMLSWARefResponse(soapMessage,
137: discElement);
138: } else if (XML_FAULT_REQUEST.equals(text)) {
139: throwSOAPFaultException();
140: } else if (XML_WSE_REQUEST.equals(text)) {
141: throwWebServiceException();
142: } else {
143: // We should not get here
144: TestLogger.logger.debug("Unknown Type of Message");
145: assertTrue(false);
146: }
147:
148: // Write out the Message
149: TestLogger.logger
150: .debug(">> Response being sent by Server:");
151: //response.writeTo(System.out);
152: //System.out.println("\n");
153: return response;
154: } catch (WebServiceException wse) {
155: throw wse;
156: } catch (Exception e) {
157: TestLogger.logger
158: .debug("***ERROR: In SoapMessageProvider.invoke: Caught exception "
159: + e);
160: e.printStackTrace();
161: }
162: return null;
163: }
164:
165: /**
166: * Common assertion checking of the request
167: * @param msg
168: * @return SOAPElement representing the data element
169: */
170: private SOAPElement assertRequestXML(SOAPMessage msg)
171: throws Exception {
172: assertTrue(msg != null);
173: SOAPBody body = msg.getSOAPBody();
174: assertTrue(body != null);
175:
176: Node invokeElement = (Node) body.getFirstChild();
177: assertTrue(invokeElement instanceof SOAPElement);
178: assertTrue(SoapMessageProvider.REQUEST_NAME
179: .equals(invokeElement.getLocalName()));
180:
181: Node discElement = (Node) invokeElement.getFirstChild();
182: assertTrue(discElement instanceof SOAPElement);
183: assertTrue(SoapMessageProvider.REQUEST_DATA_NAME
184: .equals(discElement.getLocalName()));
185:
186: String text = discElement.getValue();
187: assertTrue(text != null);
188: assertTrue(text.length() > 0);
189: TestLogger.logger.debug("Request Message Type is:" + text);
190:
191: return (SOAPElement) discElement;
192: }
193:
194: /**
195: * Get the response for an XML only request
196: * @param request
197: * @param dataElement
198: * @return SOAPMessage
199: */
200: private SOAPMessage getXMLResponse(SOAPMessage request,
201: SOAPElement dataElement) throws Exception {
202: SOAPMessage response;
203:
204: // Transport header check
205: assertTrue(request.getContentDescription() != null);
206: assertTrue(request.getContentDescription().equals(
207: SoapMessageProvider.XML_REQUEST));
208:
209: // Additional assertion checks
210: assertTrue(countAttachments(request) == 0);
211:
212: // Build the Response
213: MessageFactory factory = MessageFactory.newInstance();
214: String responseXML = responseMsgStart + XML_RETURN
215: + responseMsgEnd;
216: response = factory.createMessage(null,
217: new ByteArrayInputStream(responseXML.getBytes()));
218:
219: // Set a content description
220: response
221: .setContentDescription(SoapMessageProvider.XML_RESPONSE);
222: return response;
223: }
224:
225: /**
226: * Get the response for an XML only request
227: * @param request
228: * @param dataElement
229: * @return SOAPMessage
230: */
231: private SOAPMessage getXMLEmptyBodyResponse(SOAPMessage request,
232: SOAPElement dataElement) throws Exception {
233: SOAPMessage response;
234:
235: // Additional assertion checks
236: assertTrue(countAttachments(request) == 0);
237:
238: // Build the Response
239: MessageFactory factory = MessageFactory.newInstance();
240: response = factory.createMessage();
241:
242: return response;
243: }
244:
245: /**
246: * Get the response for an XML and an Attachment request
247: * @param request
248: * @param dataElement
249: * @return SOAPMessage
250: */
251: private SOAPMessage getXMLAttachmentResponse(SOAPMessage request,
252: SOAPElement dataElement) throws Exception {
253: SOAPMessage response;
254:
255: // Additional assertion checks
256: assertTrue(countAttachments(request) == 1);
257: AttachmentPart requestAP = (AttachmentPart) request
258: .getAttachments().next();
259: StreamSource contentSS = (StreamSource) requestAP.getContent();
260: String content = getAsString(contentSS);
261: assertTrue(content
262: .contains(SoapMessageProvider.TEXT_XML_ATTACHMENT));
263:
264: // Build the Response
265: MessageFactory factory = MessageFactory.newInstance();
266: String responseXML = responseMsgStart + ATTACHMENT_RETURN
267: + responseMsgEnd;
268: response = factory.createMessage(null,
269: new ByteArrayInputStream(responseXML.getBytes()));
270:
271: // Create and attach the attachment
272: AttachmentPart ap = response.createAttachmentPart(
273: SoapMessageProvider.TEXT_XML_ATTACHMENT, "text/xml");
274: ap.setContentId(ID);
275: response.addAttachmentPart(ap);
276:
277: return response;
278: }
279:
280: /**
281: * Get the response for an XML and an MTOM Attachment request
282: * @param request
283: * @param dataElement
284: * @return SOAPMessage
285: */
286: private SOAPMessage getXMLMTOMResponse(SOAPMessage request,
287: SOAPElement dataElement) throws Exception {
288: SOAPMessage response;
289:
290: TestLogger.logger.debug("Received MTOM Message");
291: // Additional assertion checks
292: assertTrue(countAttachments(request) == 1);
293: AttachmentPart requestAP = (AttachmentPart) request
294: .getAttachments().next();
295: StreamSource contentSS = (StreamSource) requestAP.getContent();
296: String content = getAsString(contentSS);
297: assertTrue(content
298: .contains(SoapMessageProvider.TEXT_XML_ATTACHMENT));
299:
300: TestLogger.logger
301: .debug("The MTOM Request Message appears correct.");
302:
303: // Build the Response
304: MessageFactory factory = MessageFactory.newInstance();
305: String responseXML = responseMsgStart + MTOM_RETURN
306: + responseMsgEnd;
307: response = factory.createMessage(null,
308: new ByteArrayInputStream(responseXML.getBytes()));
309:
310: // Create and attach the attachment
311: AttachmentPart ap = response.createAttachmentPart(
312: SoapMessageProvider.TEXT_XML_ATTACHMENT, "text/xml");
313: ap.setContentId(ID);
314: response.addAttachmentPart(ap);
315:
316: TestLogger.logger.debug("Returning the Response Message");
317: return response;
318: }
319:
320: /**
321: * Get the response for an XML and an MTOM Attachment request
322: * @param request
323: * @param dataElement
324: * @return SOAPMessage
325: */
326: private SOAPMessage getXMLSWARefResponse(SOAPMessage request,
327: SOAPElement dataElement) throws Exception {
328: SOAPMessage response;
329:
330: // Additional assertion checks
331: assertTrue(countAttachments(request) == 1);
332: AttachmentPart requestAP = (AttachmentPart) request
333: .getAttachments().next();
334: assertTrue(requestAP.getContentId().equals(ID));
335: StreamSource contentSS = (StreamSource) requestAP.getContent();
336: String content = getAsString(contentSS);
337: assertTrue(content
338: .contains(SoapMessageProvider.TEXT_XML_ATTACHMENT));
339:
340: // Build the Response
341: MessageFactory factory = MessageFactory.newInstance();
342: String responseXML = responseMsgStart + SWAREF_RETURN
343: + responseMsgEnd;
344: response = factory.createMessage(null,
345: new ByteArrayInputStream(responseXML.getBytes()));
346:
347: // Create and attach the attachment
348: AttachmentPart ap = response.createAttachmentPart(
349: SoapMessageProvider.TEXT_XML_ATTACHMENT, "text/xml");
350: ap.setContentId(ID);
351: response.addAttachmentPart(ap);
352:
353: return response;
354: }
355:
356: private void throwSOAPFaultException() throws SOAPFaultException {
357: try {
358: MessageFactory mf = MessageFactory.newInstance();
359: SOAPFactory sf = SOAPFactory.newInstance();
360:
361: SOAPMessage m = mf.createMessage();
362: SOAPBody body = m.getSOAPBody();
363: SOAPFault fault = body.addFault();
364: QName faultCode = new QName(
365: SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE, "Client");
366: fault.setFaultCode(faultCode);
367: fault.setFaultString("sample fault");
368: Detail detail = fault.addDetail();
369: Name deName = sf.createName("detailEntry");
370: SOAPElement detailEntry = detail.addDetailEntry(deName);
371: detailEntry.addTextNode("sample detail");
372: fault.setFaultActor("sample actor");
373:
374: SOAPFaultException sfe = new SOAPFaultException(fault);
375: throw sfe;
376: } catch (SOAPFaultException e) {
377: throw e;
378: } catch (Exception e) {
379: throw new RuntimeException(e);
380: }
381: }
382:
383: private void throwWebServiceException() throws WebServiceException {
384: throw new WebServiceException("A WSE was thrown");
385: }
386:
387: /**
388: * Count Attachments
389: * @param msg
390: * @return
391: */
392: private int countAttachments(SOAPMessage msg) {
393: Iterator it = msg.getAttachments();
394: int count = 0;
395: assertTrue(it != null);
396: while (it.hasNext()) {
397: it.next();
398: count++;
399: }
400: return count;
401: }
402:
403: public static String getAsString(StreamSource ss) throws Exception {
404:
405: ByteArrayOutputStream out = new ByteArrayOutputStream();
406: Result result = new StreamResult(out);
407: Transformer transformer = TransformerFactory.newInstance()
408: .newTransformer();
409: transformer.transform(ss, result);
410: String text = new String(out.toByteArray());
411: return text;
412: }
413:
414: private void assertTrue(boolean testAssertion) {
415: if (!testAssertion) {
416: throw new RuntimeException("Assertion false");
417: }
418: }
419: }
|