/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.axis2.jaxws.provider;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.axis2.jaxws.framework.AbstractTestCase;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Binding;
import javax.xml.ws.Response;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Future;
/**
* Tests Dispatch<SOAPMessage> client and a Provider<SOAPMessage> service
* with mustUnderstand attribute header.
*/
public class SoapMessageMUProviderTests extends AbstractTestCase {
public static final QName serviceName =
new QName("http://ws.apache.org/axis2", "SoapMessageMUProviderService");
public static final QName portName =
new QName("http://ws.apache.org/axis2", "SimpleProviderServiceSOAP11port0");
public static final String endpointUrl =
"http://localhost:6060/axis2/services/SoapMessageMUProviderService.SimpleProviderServiceSOAP11port0";
public static final String bindingID = SOAPBinding.SOAP11HTTP_BINDING;
public static final Service.Mode mode = Service.Mode.MESSAGE;
public static Test suite() {
return getTestSetup(new TestSuite(SoapMessageMUProviderTests.class));
}
/**
* Test soap message with no MU headers
*/
public void testNoMustUnderstandHeaders() throws Exception {
System.out.println("testNoMustUnderstandHeaders");
// create a service
Service svc = Service.create(serviceName);
svc.addPort(portName, bindingID, endpointUrl);
javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnvPlain);
SOAPMessage response = dispatch.invoke(message);
String string = AttachmentUtil.toString(response);
assertTrue(string.equalsIgnoreCase(AttachmentUtil.XML_HEADER
+ AttachmentUtil.msgEnvPlain));
// Try a second time
response = dispatch.invoke(message);
string = AttachmentUtil.toString(response);
assertTrue(string.equalsIgnoreCase(AttachmentUtil.XML_HEADER
+ AttachmentUtil.msgEnvPlain));
}
/**
* Test the mustUnderstand soap header attribute on the client's
* outbound soap message for headers that are not understood. Should cause an
* exception.
*/
public void testClientRequestNotUnderstoodHeaders() {
System.out.println("testClientRequestNotUnderstoodHeaders");
// create a service
Service svc = Service.create(serviceName);
svc.addPort(portName, bindingID, endpointUrl);
javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
//force SOAPAction to match with wsdl action
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnvMU);
try {
dispatch.invoke(message);
fail("Should have received fault for not understood headers on request");
} catch (Exception e) {
// Expected path
}
// Try a second time
try {
dispatch.invoke(message);
fail("Should have received fault for not understood headers on request");
} catch (Exception e) {
// Expected path
}
}
/**
* Test the mustUnderstand soap header attribute on the server's
* outbound soap message (i.e. the inbound response to the client) for headers that
* are not understood. Should cause an exception.
*/
public void testClientResponseNotUnderstoodHeaders() {
System.out.println("testClientResponseNotUnderstoodHeaders");
// create a service
Service svc = Service.create(serviceName);
svc.addPort(portName, bindingID, endpointUrl);
javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
//force SOAPAction to match with wsdl action
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnv);
try {
dispatch.invoke(message);
fail("Should have received fault for not understood headers on response");
} catch (Exception e) {
// Expected path
}
// Try a second time
try {
dispatch.invoke(message);
fail("Should have received fault for not understood headers on response");
} catch (Exception e) {
// Expected path
}
}
/**
* Test the mustUnderstand soap header attribute on the client's
* outbound soap message for headers that should be understood. Should not cause an
* exception.
*/
public void testClientRequestUnderstoodHeaders() throws Exception {
System.out.println("testClientRequestUnderstoodHeaders");
// create a service
Service svc = Service.create(serviceName);
svc.addPort(portName, bindingID, endpointUrl);
javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
//force SOAPAction to match with wsdl action
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnvMU_understood);
dispatch.invoke(message);
// Try a second time
dispatch.invoke(message);
}
/**
* Test the mustUnderstand soap header attribute on the server's
* outbound soap message (i.e. the inbound response to the client) for headers that
* are understood. Should not cause an exception.
*/
public void testClientResponseUnderstoodHeaders() throws Exception {
System.out.println("testClientResponseUnderstoodHeaders");
// create a service
Service svc = Service.create(serviceName);
svc.addPort(portName, bindingID, endpointUrl);
javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
//force SOAPAction to match with wsdl action
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnv_understood);
dispatch.invoke(message);
// Try a second time
dispatch.invoke(message);
}
/**
* Test the mustUnderstand soap header attribute on the server's
* outbound soap message using multiple handlers. The response contains a header that
* should be understood by the JAX-WS application handler, so there should be no exception.
* Tests that multiple handlers do not cause a collision when registering headers they
* understand.
*/
public void testClientResponseHandlerUnderstoodHeaders2() {
System.out.println("testClientResponseTwoHandlerUnderstoodHeaders2");
// create a service
Service svc = Service.create(serviceName);
svc.addPort(portName, bindingID, endpointUrl);
javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
//force SOAPAction to match with wsdl action
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
// set handler chain for binding provider to add the handler that will
// understand the mU header
Binding binding = ((BindingProvider) dispatch).getBinding();
// create a new list or use the existing one
List<Handler> handlers = binding.getHandlerChain();
if (handlers == null) {
handlers = new ArrayList<Handler>();
}
handlers.add(new MustUnderstandClientHandler2());
handlers.add(new MustUnderstandClientHandler());
binding.setHandlerChain(handlers);
SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnv2);
try {
SOAPMessage response = dispatch.invoke(message);
assertNotNull("No response received", response);
String responseString = AttachmentUtil.toString(response);
assertNotNull(responseString);
} catch (Exception e) {
fail("Should not have caught an exception: " + e.toString());
}
}
/**
* Test that not-understood mustUnderstand headers cause an exception in the async polling
* case.
*/
public void testClientResponseNotUnderstoodHeadersAsyncPolling() {
System.out.println("testClientResponseNotUnderstoodHeadersAsyncPolling");
// create a service
Service svc = Service.create(serviceName);
svc.addPort(portName, bindingID, endpointUrl);
javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
//force SOAPAction to match with wsdl action
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnv);
Response<SOAPMessage> asyncResponse = null;
try {
asyncResponse = dispatch.invokeAsync(message);
assertNotNull("No response received", asyncResponse);
} catch (Exception e) {
fail("Should not have caught an exception on the async invocation: " + e.toString());
}
try {
while (!asyncResponse.isDone()) {
System.out.println(">> Async invocation still not complete");
Thread.sleep(1000);
}
SOAPMessage response = asyncResponse.get();
fail("Should have caught a mustUnderstand exception");
} catch (Exception e) {
// Expected path
assertTrue("Did not received expected exception",
e.getCause().toString().contains("Must Understand check failed for header http://ws.apache.org/axis2 : muserver"));
}
}
/**
* Test that JAX-WS handlers can register they processes certain mustUnderstand headers in the
* async polling case.
*/
public void testClientResponseHandlerUnderstoodHeadersAsyncPolling() {
System.out.println("testClientResponseHandlerUnderstoodHeadersAsyncPolling");
// create a service
Service svc = Service.create(serviceName);
svc.addPort(portName, bindingID, endpointUrl);
javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
//force SOAPAction to match with wsdl action
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
// set handler chain for binding provider to add the handler that will
// understand the mU header
Binding binding = ((BindingProvider) dispatch).getBinding();
// create a new list or use the existing one
List<Handler> handlers = binding.getHandlerChain();
if (handlers == null) {
handlers = new ArrayList<Handler>();
}
handlers.add(new MustUnderstandClientHandler());
binding.setHandlerChain(handlers);
SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnv);
try {
Response<SOAPMessage> asyncResponse = dispatch.invokeAsync(message);
assertNotNull("No response received", asyncResponse);
while (!asyncResponse.isDone()) {
System.out.println(">> Async invocation still not complete");
Thread.sleep(1000);
}
SOAPMessage response = asyncResponse.get();
assertNotNull("Response was nulL", response);
String responseString = AttachmentUtil.toString(response);
assertNotNull(responseString);
} catch (Exception e) {
fail("Should not have caught an exception: " + e.toString());
}
}
/**
* Test that not-understood mustUnderstand headers cause an exception in the async callback
* case.
*/
public void testClientResponseNotUnderstoodHeadersAsyncCallback() {
System.out.println("testClientResponseNotUnderstoodHeadersAsyncCallback");
// create a service
Service svc = Service.create(serviceName);
svc.addPort(portName, bindingID, endpointUrl);
javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
//force SOAPAction to match with wsdl action
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnv);
Future<?> asyncResponse = null;
AsyncCallback<SOAPMessage> callback = new AsyncCallback<SOAPMessage>();
try {
asyncResponse = dispatch.invokeAsync(message, callback);
assertNotNull("No response received", asyncResponse);
} catch (Exception e) {
fail("Should not have caught an exception on the async invocation: " + e.toString());
}
try {
while (!asyncResponse.isDone()) {
System.out.println(">> Async invocation still not complete");
Thread.sleep(1000);
}
assertTrue("Did not receive exception", callback.hasError());
assertTrue("Did not received expected exception",
callback.getError().toString().contains("Must Understand check failed for header http://ws.apache.org/axis2 : muserver"));
} catch (Exception e) {
fail("Received unexpected exception: " + e.toString());
}
}
/**
* Test that JAX-WS handlers can register they processes certain mustUnderstand headers in the
* async callback case.
*/
public void testClientResponseUnderstoodHeadersAsyncCallback() {
System.out.println("testClientResponseUnderstoodHeadersAsyncCallback");
// create a service
Service svc = Service.create(serviceName);
svc.addPort(portName, bindingID, endpointUrl);
javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
//force SOAPAction to match with wsdl action
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
((BindingProvider) dispatch).getRequestContext()
.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
// set handler chain for binding provider to add the handler that will
// understand the mU header
Binding binding = ((BindingProvider) dispatch).getBinding();
// create a new list or use the existing one
List<Handler> handlers = binding.getHandlerChain();
if (handlers == null) {
handlers = new ArrayList<Handler>();
}
handlers.add(new MustUnderstandClientHandler());
binding.setHandlerChain(handlers);
SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnv);
Future<?> asyncResponse = null;
AsyncCallback<SOAPMessage> callback = new AsyncCallback<SOAPMessage>();
try {
asyncResponse = dispatch.invokeAsync(message, callback);
assertNotNull("No response received", asyncResponse);
} catch (Exception e) {
fail("Should not have caught an exception on the async invocation: " + e.toString());
}
try {
while (!asyncResponse.isDone()) {
System.out.println(">> Async invocation still not complete");
Thread.sleep(1000);
}
assertFalse("Receive unexpected exception", callback.hasError());
SOAPMessage response = callback.getValue();
assertNotNull(response);
} catch (Exception e) {
fail("Received unexpected exception" + e.toString());
}
}
// ============================================================================================
// Test handlers and test classes
// ============================================================================================
class MustUnderstandClientHandler implements
javax.xml.ws.handler.soap.SOAPHandler<SOAPMessageContext> {
public Set<QName> getHeaders() {
// Understand the header {http://ws.apache.org/axis2}muserver that will be sent back
// by the server; the other headers are just to test multiple entries in the Set
Set<QName> result = new HashSet<QName>();
result.add(new QName("http://ws.apache.org/axis2", "muserverAnother"));
result.add(new QName("http://ws.apache.org/axis2", "muserver"));
result.add(new QName("http://ws.apache.org/axis2", "muserverYetAnother"));
return result;
}
public void close(MessageContext context) {
}
public boolean handleFault(SOAPMessageContext context) {
return true;
}
public boolean handleMessage(SOAPMessageContext context) {
return true;
}
}
class MustUnderstandClientHandler2 implements
javax.xml.ws.handler.soap.SOAPHandler<SOAPMessageContext> {
public Set<QName> getHeaders() {
// Understand the header {http://ws.apache.org/axis2}muserver2 that will be sent back
// by the server; the other headers are just to test multiple entries in the Set
Set<QName> result = new HashSet<QName>();
// The first header is a collision with one understood by the other handler
result.add(new QName("http://ws.apache.org/axis2", "muserverAnother"));
result.add(new QName("http://ws.apache.org/axis2", "muserver2"));
result.add(new QName("http://ws.apache.org/axis2", "muserverYetAnother2"));
return result;
}
public void close(MessageContext context) {
}
public boolean handleFault(SOAPMessageContext context) {
return true;
}
public boolean handleMessage(SOAPMessageContext context) {
return true;
}
}
class AsyncCallback<T> implements AsyncHandler<T> {
private T value;
private Throwable exception;
public void handleResponse(Response<T> response) {
try {
value = response.get();
} catch (Throwable t) {
exception = t;
}
}
public boolean hasError() {
return (exception != null);
}
public Throwable getError() {
return exception;
}
public T getValue() {
return value;
}
}
}