So after an entire weekend of frustration with tutorials such as http://xfire.codehaus.org/JSR+181+Annotations and http://docs.codehaus.org/pages/viewpage.action?pageId=44565 I think I have come up with a way to test XFire services deployed through Tomcat during my Maven build.

So I created an annotated version of an Echo Service:

package com.baselogic.service;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService(name = "EchoService",
targetNamespace = "http://service.baselogic.com")
public interface EchoService {

@WebMethod(operationName = "echoString", action = "urn:EchoString")
@WebResult(name = "echoResult", targetNamespace = "http://service.baselogic.com")
public String echoString(
@WebParam(name = "echoParam", targetNamespace = "http://service.baselogic.com", header = true)
String echoParam);

}
Then created my implementation class:
package com.baselogic.service;

import javax.jws.WebService;

/**
* Echo XFire Web Service
*/
@WebService(serviceName = "Echo",
targetNamespace = "http://service.baselogic.com", endpointInterface = "com.baselogic.service.EchoService")
public class EchoImpl implements EchoService {

public String echoString(String input) {
return "Echo Response: " + input;
}
}
I then created a /WEB-INF/xfire-servlet.xml resource that only contains the following mappings:
class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations"/>
class="org.codehaus.xfire.annotations.AnnotationServiceFactory">

com.baselogic.service.EchoService
In my web.xml, I added my xfire-servlet.xml:
contextConfigLocation      classpath:/applicationContext-resources.xml
classpath:/applicationContext-service.xml
classpath:org/codehaus/xfire/spring/xfire.xml
/WEB-INF/xfire-servlet.xml
I added my xfire spring servlet:
xfire
org.codehaus.xfire.spring.XFireSpringServlet
Now I kept seeing several JUnit examples with many convenience methods, but I wanted to use TestNG instead. So I created a testng-functional.xml file with some parameters that I needed.

Then I used those in my TestNG test like:

package com.baselogic.service;

import com.baselogic.service.impl.UserManagerImpl;
import com.baselogic.util.StringUtil;
import com.baselogic.domain.User;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.codehaus.xfire.XFire;
import org.codehaus.xfire.XFireFactory;
import org.codehaus.xfire.aegis.AegisBindingProvider;
import org.codehaus.xfire.annotations.AnnotationServiceFactory;
import org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.ServiceRegistry;
import org.codehaus.xfire.xmlbeans.XmlBeansTypeRegistry;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import java.net.MalformedURLException;
import java.net.URL;

public class UserServiceTest {

// configure log4j
static {
URL log4j = Thread.currentThread().getContextClassLoader().getResource(
"log4j.xml");
DOMConfigurator.configure(log4j);
}

protected Logger log = Logger.getLogger(getClass());

protected String echoUrl = "http://localhost:8080/services/Echo";
protected String serviceUrlLocal;

Service serviceModel;
AnnotationServiceFactory factory;
ServiceRegistry serviceRegistry;
XFire xfire;

@Parameters({"serviceUrlLocal"})
@BeforeClass(groups = {"functional"})
protected void init(String serviceUrlLocal) throws Exception {
log.info("Setup XFire Registry");
this.serviceUrlLocal = serviceUrlLocal;

xfire = XFireFactory.newInstance().getXFire();

AnnotationServiceFactory factory = new AnnotationServiceFactory(new Jsr181WebAnnotations(),
xfire.getTransportManager(),
new AegisBindingProvider(new XmlBeansTypeRegistry()));
serviceModel = factory.create(UserManagerImpl.class);

xfire.getServiceRegistry().register(serviceModel);
serviceRegistry = xfire.getServiceRegistry();
serviceRegistry.register(serviceModel);
}

@AfterClass(groups = {"functional"})
protected void stop() throws Exception {
log.info("Stopping XFire Registry");
xfire.getServiceRegistry().unregister(serviceModel);
}

@Test(groups = {"functional"})
public void testGetUser() throws Exception {

XFireProxyFactory xFireProxyFactory = new XFireProxyFactory(xfire);
UserManager userManager = null;
User user = null;
try {
userManager = (UserManager) xFireProxyFactory.create(serviceModel, serviceUrlLocal);
user = userManager.getUser("mknutson");

AssertJUnit.assertNotNull(user.getUsername());
AssertJUnit.assertEquals("mknutson", user.getUsername());
} catch (MalformedURLException e) {
log.debug("WsClient.callWebService(): EXCEPTION: " + e.toString());
}
catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
The difference I found out that was different in testNG from the examples I saw, was the use of a local URL verse the full service url. I could never get the full url o work, but I assume that the JUnit helper classes from xfire resolve that url to a local anyways. When I changed to the local url, my service started working fine. I later removed the serviceUrl parameter later and just used the serviceUrlLocal parameter for my tests going forward.

Mick Knutson

Java, JavaEE, J2EE, WebLogic, WebSphere, JBoss, Tomcat, Oracle, Spring, Maven, Architecture, Design, Mentoring, Instructor and Agile Consulting. http://www.baselogic.com/blog/resume

View all posts

Java / JavaEE / Spring Boot Channel

BLiNC Supporters

BLiNC Adsense

Archives

Newsletter