domingo, 11 de julio de 2010

Cómo probar tus Servicios Web con Apache CXF

Una vez hemos creado el servidor y el cliente con Apache CXF y Spring, vamos a preparar una aplicación web con el WS que nos haga de entorno de pruebas.

Como comentamos en el primero de los posts de la serie, el módulo svc-ws contendrá los ficheros necesarios para montar la aplicación. Así, situado en, src/main/webapp/WEB-INF tendremos el web.xml y el ws-ctx.xml.

Para el caso de ws-ctx.xml vemos,

 <?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxws:endpoint
id="servicio"
implementor="#servicioImpl"
address="/Servicio" />
</beans>


y un trozo de web.xml sería,

      <context-param>  
<param-name>contextConfigLocation</param-name>
<param-value>classpath:emilio/escobar/svc-ctx.xml
WEB-INF/ws-ctx.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>


Pero la magia está en el pom.xml,

 <?xml version="1.0"?>  
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>svc</artifactId>
<groupId>emilio.escobar</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>svc-ws</artifactId>
<packaging>war</packaging>
<name>SVC :: WS</name>
<dependencies>
<dependency>
<groupId>emilio.escobar</groupId>
<artifactId>svc-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.google.collections</groupId>
<artifactId>google-collections</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>2.5.6.SEC02</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>2.5.6.SEC02</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-core</artifactId>
<version>2.1</version>
<exclusions>
<exclusion>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-simple</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-local</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.1</version>
<exclusions>
<exclusion>
<artifactId>spring-web</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-common-utilities</artifactId>
<version>2.1</version>
<exclusions>
<exclusion>
<artifactId>spring-beans</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>2.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>svc-ws</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>failsafe-maven-plugin</artifactId>
<version>2.4.3-alpha-1</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>7.0.1.v20091125</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webAppConfig>
<contextPath>/svc-ws</contextPath>
</webAppConfig>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>9000</port>
<host>0.0.0.0</host>
</connector>
</connectors>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>


Los plugins failsafe-maven-plugin y jetty-maven-plugin son los encargados de arrancar el contenedor y de ejecutar los tests de integración.

Para este ejemplo he preparado un pequeño test que no hace gran cosa. Simplemente carga el contexto con el cliente,

 <?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:client id="servicioClient"
serviceClass="emilio.escobar.api.Servicio"
address="http://localhost:9000/svc-ws/Servicio" />
</beans>


y lo ejecuta. El código del test,

 public class ServiceWSIT {  
private static final String MEMORY_PATH = "emilio/escobar/wsclictx.xml";
private static final String[] MEMORY = {MEMORY_PATH};
private static ConfigurableApplicationContext context;
private Servicio servicio;
@BeforeClass
public static void loadContext() {
context = new ClassPathXmlApplicationContext(MEMORY);
}
@AfterClass
public static void shutdown() {
context.close();
}
@Before
public void setUp() {
this.servicio = getBean(Servicio.class);
}
@Test
public void test() {
assertNotNull(servicio);
}
@Test
public void methodTest() {
final String nombre = "it-test";
final ParametroDTO param1 = new ParametroDTO();
param1.setKey("param1");
param1.setValue("1");
final ParametroDTO param2 = new ParametroDTO();
param2.setKey("param2");
param2.setValue("2");
final EntradaDTO entrada = new EntradaDTO();
entrada.setNombre(nombre);
entrada.setParametros(Lists.newArrayList(param1, param2));
final List<String> salida = servicio.operacion(entrada);
assertNotNull(salida);
assertTrue(salida.size() == 3);
assertEquals(nombre, salida.get(0));
assertEquals("param1-1", salida.get(1));
assertEquals("param2-2", salida.get(2));
}


Por último, a lo largo de la semana publicaré el enlace a la descarga del código utilizado hasta el momento.

No hay comentarios: