/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package mtom.issue_671.client;
import junit.framework.TestCase;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.soap.MTOMFeature;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.http.HTTPBinding;
import javax.xml.soap.*;
import javax.xml.namespace.QName;
import java.io.*;
import java.util.*;
/**
* Test that the messages are XOPed when MTOM is enabled.
* Tests issue JAX-WS-671
*
* @author Rama Pulavarthi
*/
public class Issue671Test extends TestCase {
private Hello mtom_proxy;
private Hello no_mtom_proxy;
private Dispatch<DataSource> dispatch;
private Hello provider_proxy;
public Issue671Test(String name) throws Exception {
super(name);
}
protected void setUp() throws Exception {
mtom_proxy = new HelloService().getHelloPort(new MTOMFeature());
no_mtom_proxy = new HelloService().getHelloPort();
provider_proxy = new HelloService().getHelloProviderPort(new MTOMFeature());
String helloPortAddress = (String) ((BindingProvider) mtom_proxy).getRequestContext().get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
QName serviceName = new QName("http://example.org/mtom", "Hello");
QName portName = new QName("http://example.org/mtom", "HelloPort");
Service service = Service.create(serviceName);
service.addPort(portName, HTTPBinding.HTTP_BINDING, helloPortAddress);
dispatch = service.createDispatch(portName, DataSource.class, Service.Mode.MESSAGE);
}
/**
* Normal MTOMEnabled SEI case, (useful for capturing sample messages).
*
* @throws Exception
*/
public void testMtomEnabled() throws Exception {
XDoc xdoc = new XDoc();
xdoc.setDoc1(getSource("gpsXml.xml"));
XDoc out = mtom_proxy.xDoc(xdoc);
}
/**
* Server is Provider<DataSource>, verifies if the request is XOPed.
*
* @throws Exception if the request is not XOPed
*/
public void testVerifyMtomEnabled() throws Exception {
XDoc xdoc = new XDoc();
xdoc.setDoc1(getSource("gpsXml.xml"));
XDoc out = provider_proxy.xDoc(xdoc);
assertNotNull(out.getDoc1());
}
/**
* MTOMFeature not enabled on this proxy.
* The messages should not be XOPed though MTOM is enabled on endpoint.
*
* @throws Exception
*/
public void testNoMTOM() throws Exception {
XDoc xdoc = new XDoc();
xdoc.setDoc1(getSource("gpsXml.xml"));
XDoc out = no_mtom_proxy.xDoc(xdoc);
}
/**
* Request is normal SOAPMessage,
* Verfies that the response is normal message from a MTOM enabled endpoint.
*
* @throws Exception
*/
public void testVerifyNoMtom() throws Exception {
// Create a request SOAPMessage
SOAPMessage in = getSOAPMessage();
DataSource ds = getDataSource(in);
ds = dispatch.invoke(ds);
assertFalse(ds.getContentType().contains("application/xop+xml"));
// Create a SOAPMessage from response
MimeHeaders headers = new MimeHeaders();
headers.addHeader("Content-Type", ds.getContentType());
SOAPMessage out = MessageFactory.newInstance().createMessage(headers, ds.getInputStream());
// verify S:Body
SOAPBody body = out.getSOAPBody();
Iterator it = body.getChildElements();
SOAPElement elem = (SOAPElement) it.next();
assertEquals(new QName("http://example.org/mtom", "XDocOut"), elem.getElementQName());
SOAPElement docit = (SOAPElement) elem.getChildElements().next();
assertEquals(new QName("http://example.org/mtom", "doc1"), docit.getElementQName());
//assert that there is no xop include
assertFalse(docit.getChildElements(new QName("http://www.w3.org/2004/08/xop/include", "Include")).hasNext());
}
/**
* Send a MTOM request, ContentType of request is application/xop+xml
* Verfies that the response is MTOM message.
*
* @throws Exception
*/
public void testMtomWithContentTypeHeader() throws Exception {
// Create a request SOAPMessage
SOAPMessage in = getXOPedSOAPMessage();
DataSource ds = getDataSource(in);
ds = dispatch.invoke(ds);
// Create a SOAPMessage from response
MimeHeaders headers = new MimeHeaders();
headers.addHeader("Content-Type", ds.getContentType());
SOAPMessage out = MessageFactory.newInstance().createMessage(headers, ds.getInputStream());
// verify S:Body
SOAPBody body = out.getSOAPBody();
Iterator it = body.getChildElements();
SOAPElement elem = (SOAPElement) it.next();
assertEquals(new QName("http://example.org/mtom", "XDocOut"), elem.getElementQName());
SOAPElement docit = (SOAPElement) elem.getChildElements().next();
assertEquals(new QName("http://example.org/mtom", "doc1"), docit.getElementQName());
// verify <doc1> contains xop:Include
SOAPElement xopit = (SOAPElement) docit.getChildElements().next();
assertEquals(new QName("http://www.w3.org/2004/08/xop/include", "Include"), xopit.getElementQName());
String href = xopit.getAttributeValue(new QName("", "href"));
assertEquals("cid:", href.substring(0, 4));
}
/**
* Request is normal SOAPMessage, but Accept header is set to application/xop+xml
* Verfies that the response is MTOM
*
* @throws Exception
*/
public void testMtomWithAcceptHeader() throws Exception {
// Create a request SOAPMessage
SOAPMessage in = getSOAPMessage();
DataSource ds = getDataSource(in);
Map<String, java.util.List<String>> httpheaders = new HashMap<String, java.util.List<String>>();
httpheaders.put("Accept", Arrays.asList("multipart/related; type=application/xop+xml"));
((BindingProvider) dispatch).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, httpheaders);
ds = dispatch.invoke(ds);
// Create a SOAPMessage from response
MimeHeaders headers = new MimeHeaders();
headers.addHeader("Content-Type", ds.getContentType());
SOAPMessage out = MessageFactory.newInstance().createMessage(headers, ds.getInputStream());
// verify S:Body
SOAPBody body = out.getSOAPBody();
Iterator it = body.getChildElements();
SOAPElement elem = (SOAPElement) it.next();
assertEquals(new QName("http://example.org/mtom", "XDocOut"), elem.getElementQName());
SOAPElement docit = (SOAPElement) elem.getChildElements().next();
assertEquals(new QName("http://example.org/mtom", "doc1"), docit.getElementQName());
// verify <doc1> contains xop:Include
SOAPElement xopit = (SOAPElement) docit.getChildElements().next();
assertEquals(new QName("http://www.w3.org/2004/08/xop/include", "Include"), xopit.getElementQName());
String href = xopit.getAttributeValue(new QName("", "href"));
assertEquals("cid:", href.substring(0, 4));
}
private void validate(DataHandler exp, DataHandler got) throws Exception {
InputStream inExp = exp.getInputStream();
InputStream inGot = got.getInputStream();
int ch;
while ((ch = inExp.read()) != -1) {
assertEquals(ch, inGot.read());
}
assertEquals(-1, inGot.read());
inExp.close();
inGot.close();
}
private StreamSource getSource(String file) throws Exception {
InputStream is = getClass().getClassLoader().getResourceAsStream(file);
return new StreamSource(is);
}
private InputStream getResource(String file) throws Exception {
InputStream is = getClass().getClassLoader().getResourceAsStream(file);
return is;
}
private DataHandler getDataHandler(final String file) throws Exception {
return new DataHandler(new DataSource() {
public String getContentType() {
return "text/html";
}
public InputStream getInputStream() {
return getClass().getClassLoader().getResourceAsStream(file);
}
public String getName() {
return null;
}
public OutputStream getOutputStream() {
throw new UnsupportedOperationException();
}
});
}
private DataSource getDataSource(final SOAPMessage msg) throws Exception {
return new DataSource() {
public String getContentType() {
return msg.getMimeHeaders().getHeader("Content-Type")[0];
}
public InputStream getInputStream() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
msg.writeTo(baos);
} catch (SOAPException e) {
throw new RuntimeException(e);
}
return new ByteArrayInputStream(baos.toByteArray());
}
public String getName() {
return null;
}
public OutputStream getOutputStream() {
throw new UnsupportedOperationException();
}
};
}
private SOAPMessage getXOPedSOAPMessage() throws Exception {
MimeHeaders headers = new MimeHeaders();
headers.addHeader("Content-Type", "text/xml");
SOAPMessage msg = MessageFactory.newInstance().createMessage(headers, getResource("xop.envelope"));
AttachmentPart doc1 = msg.createAttachmentPart(getDataHandler("gpsXml.xml"));
doc1.setContentId("2c5bbb50-5679-4fea-9982-666753769e20@example.jaxws.sun.com");
msg.addAttachmentPart(doc1);
MimeHeaders hdrs = msg.getMimeHeaders();
String boundary = "BOUNDARY_123456789_BOUNDARY";
String ct =
"multipart/related;type=\"application/xop+xml\";boundary=" + boundary + ";start-info=\"text/xml\"";
hdrs.setHeader("Content-Type", ct);
msg.saveChanges();
return msg;
}
private SOAPMessage getSOAPMessage() throws Exception {
MimeHeaders headers = new MimeHeaders();
headers.addHeader("Content-Type", "text/xml");
SOAPMessage msg = MessageFactory.newInstance().createMessage(headers, getResource("normal.envelope"));
msg.saveChanges();
return msg;
}
}