Páginas

jueves, 8 de noviembre de 2012

Configurar Log4j en Apache CXF

En la anterior entrada dejamos montado un ejemplo con Apache CFX y WS-Security. Pero como Apache CXF utiliza por defecto slf4j el lugar de log4j, teníamos el log de las peticiones y respuestas en ficheros distintos al resto de los módulos, donde usamos log4j.

Vamos a repasar como ajustar ambos módulos para que se genere la traza en nuestro fichero de log habitual.

Aplicativo cxf-web

1) Deberemos ajustar el fichero /src/main/resources/log4j.properties con el siguiente contenido:

log4j.rootCategory=INFO,CONSOLA

log4j.logger.es.ine.cxf.ws=INFO

log4j.logger.org.apache.cxf.interceptor.LoggingInInterceptor.level=INFO
log4j.logger.org.apache.cxf.interceptor.LoggingOutInterceptor.level=INFO
log4j.logger.org.apache.cxf.ws.rm.security.wss4j.WSS4JInInterceptor.level=INFO
log4j.logger.org.apache.cxf.ws.rm.security.wss4j.WSS4JOutInterceptor.level=INFO

log4j.appender.CONSOLA=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLA.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLA.layout.ConversionPattern=%d %p [%c] - <%m>%n

log4j.appender.FICHERO=org.apache.log4j.RollingFileAppender
log4j.appender.FICHERO.file=${log4j.debug.ruta_fichero}/cxf-web.log
log4j.appender.FICHERO.append=true
log4j.appender.FICHERO.MaxFileSize=${log4j.debug.MaxFileSize}
log4j.appender.FICHERO.MaxBackupIndex=${log4j.debug.MaxBackupIndex}
log4j.appender.FICHERO.layout=org.apache.log4j.PatternLayout
log4j.appender.FICHERO.layout.ConversionPattern=[%d{dd-MM-yyyy HH\:mm\:ss,SSS}] thread\:[%t] nivelTraza\:[%p] lugarTraza\:[%c] mensajeTraza[%m]%n


2) Deberemos crear un fichero llamado:

/src/main/resources/META-INF/cxf/org.apache.cxf.Logger

El contenido de este fichero será:

org.apache.cxf.common.logging.Log4jLogger

3) Deberemos ajustar nuestra clase cliente así:

package es.ins.sgtic.app;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;

import es.ine.cxf.ws.impl.Calculadora;
import es.ine.cxf.ws.impl.CalculadoraImplService;

public class AppTest {

    private static final QName SERVICE_NAME = new QName("http://impl.ws.cxf.ine.es/", "CalculadoraImplService");
   
    public static void main(String[] args) {

        //Definimos el servicio web a usar
        final URL wsdlURL = CalculadoraImplService.WSDL_LOCATION;
        final CalculadoraImplService calcService = new CalculadoraImplService(wsdlURL, SERVICE_NAME);
        final Calculadora calculadora = calcService.getCalculadoraImplPort();
               
        //Obtenemos la referencia al endpoint del ws
        final Client client = ClientProxy.getClient(calculadora);
        final Endpoint cxfEndpoint = client.getEndpoint();
       
        //Ajustamos el log del cliente
        final LoggingInInterceptor incerceptorLogIn = new LoggingInInterceptor();
        incerceptorLogIn.setPrettyLogging(true);
        final LoggingOutInterceptor incerceptorLogOut = new LoggingOutInterceptor();
        incerceptorLogOut.setPrettyLogging(true);
        client.getInInterceptors().add(incerceptorLogIn);
        client.getOutInterceptors().add(incerceptorLogOut);

       
        //Configuramos el interceptor de cifrado/firmado para los envíos
        final Map<String,Object> outProps = new HashMap<String,Object>();
        outProps.put("action", "Timestamp Signature Encrypt");
        outProps.put("user", "edugarci");
        outProps.put("signaturePropFile", "props/client-key-store.properties");
        outProps.put("signatureKeyIdentifier", "DirectReference");
        outProps.put("passwordCallbackClass", "es.ine.cxf.ws.sec.PasswordCallback");
        outProps.put("signatureParts", "{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body");
        outProps.put("encryptionPropFile", "props/client-trust-store.properties");
        outProps.put("encryptionUser", "desarrollo-internet");
        outProps.put("encryptionParts", "{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body");
        outProps.put("encryptionSymAlgorithm", "http://www.w3.org/2001/04/xmlenc#tripledes-cbc");
        outProps.put("encryptionKeyTransportAlgorithm", "http://www.w3.org/2001/04/xmlenc#rsa-1_5");
        WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); //request
        cxfEndpoint.getOutInterceptors().add(wssOut);
        cxfEndpoint.getOutInterceptors().add(new SAAJOutInterceptor());
       
        //Configuramos el interceptor de descifrado/verificacion-firma para las recepciones
        Map<String,Object> inProps= new HashMap<String,Object>();
        inProps.put("action", "Timestamp Signature Encrypt");
        inProps.put("signaturePropFile", "props/client-trust-store.properties");
        inProps.put("passwordCallbackClass", "es.ine.cxf.ws.sec.PasswordCallback");
        inProps.put("decryptionPropFile", "props/client-key-store.properties");
        WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps); //response
        cxfEndpoint.getInInterceptors().add(wssIn);
        cxfEndpoint.getInInterceptors().add(new SAAJInInterceptor());
       
        //Lanzamos unas peticiones de ejemplo
        System.out.println(String.format("port.suma(15, 3) --> %d",calculadora.suma(15, 3)));
        System.out.println(String.format("port.resta(15, 3) --> %d",calculadora.resta(15, 3)));
        System.out.println(String.format("port.multiplica(15, 3) --> %d",calculadora.multiplica(15, 3)));
        System.out.println(String.format("port.divide(15, 3) --> %d",calculadora.divide(15, 3)));
    }
}


Aplicativocxf-client

1) Deberemos ajustar el fichero /src/main/resources/log4j.properties con el siguiente contenido:

log4j.rootCategory=INFO,CONSOLA

log4j.logger.es.ine.cxf.ws=INFO

log4j.logger.org.apache.cxf.interceptor.LoggingInInterceptor.level=INFO
log4j.logger.org.apache.cxf.interceptor.LoggingOutInterceptor.level=INFO
log4j.logger.org.apache.cxf.ws.rm.security.wss4j.WSS4JInInterceptor.level=INFO
log4j.logger.org.apache.cxf.ws.rm.security.wss4j.WSS4JOutInterceptor.level=INFO

log4j.appender.CONSOLA=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLA.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLA.layout.ConversionPattern=%d %p [%c] - <%m>%n

log4j.appender.FICHERO=org.apache.log4j.RollingFileAppender
log4j.appender.FICHERO.file=${log4j.debug.ruta_fichero}/cxf-web.log
log4j.appender.FICHERO.append=true
log4j.appender.FICHERO.MaxFileSize=${log4j.debug.MaxFileSize}
log4j.appender.FICHERO.MaxBackupIndex=${log4j.debug.MaxBackupIndex}
log4j.appender.FICHERO.layout=org.apache.log4j.PatternLayout
log4j.appender.FICHERO.layout.ConversionPattern=[%d{dd-MM-yyyy HH\:mm\:ss,SSS}] thread\:[%t] nivelTraza\:[%p] lugarTraza\:[%c] mensajeTraza[%m]%n


2) Deberemos crear un fichero llamado:

/src/main/resources/META-INF/cxf/org.apache.cxf.Logger

El contenido de este fichero será:

org.apache.cxf.common.logging.Log4jLogger

3) Deberemos ajustar el contenido del fichero applicationContext.xml, dejándolo así:

<?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"
    xmlns:cxf="http://cxf.apache.org/core"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                        http://cxf.apache.org/jaxws
                        http://cxf.apache.org/schemas/jaxws.xsd
                        http://cxf.apache.org/core
                        http://cxf.apache.org/schemas/core.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" />

    <bean id="firmaPeticion" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
        <constructor-arg>
            <map>
                <entry key="action" value="Timestamp Signature Encrypt" />
                <!-- Ajustamos la verificación de la firma de las peticiones que nos
                    llegan -->
                <entry key="signaturePropFile" value="props/server-trust-store.properties" />
                <!-- Ajustamos el desencriptado de los datos de la petición que recibimos -->
                <entry key="decryptionPropFile" value="props/server-key-store.properties" />
                <entry key="passwordCallbackClass" value="es.ine.cxf.ws.sec.PasswordCallback" />
            </map>
        </constructor-arg>
    </bean>

    <bean id="firmaRespuesta" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
        <constructor-arg>
            <map>
                <entry key="action" value="Timestamp Signature Encrypt" />
                <!-- Ajustamos el firmado de las respuestas -->
                <entry key="signaturePropFile" value="props/server-key-store.properties" />
                <entry key="user" value="desarrollo-internet" />
                <!-- Ajustamos el encriptado de las respuestas -->
                <entry key="encryptionPropFile" value="props/server-trust-store.properties" />
                <entry key="encryptionUser" value="edugarci" />
                <entry key="signatureKeyIdentifier" value="DirectReference" />
                <entry key="passwordCallbackClass" value="es.ine.cxf.ws.sec.PasswordCallback" />
                <entry key="signatureParts"
                    value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body" />
                <entry key="encryptionParts"
                    value="{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body" />
                <entry key="encryptionKeyTransportAlgorithm" value="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
                <entry key="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
            </map>
        </constructor-arg>
    </bean>

    <jaxws:endpoint xmlns:tns="http://impl.ws.cxf.ine.es/"
        id="calculadora" implementor="es.ine.cxf.ws.impl.CalculadoraImpl"
        wsdlLocation="wsdl/calculadoraimpl.wsdl" endpointName="tns:CalculadoraImplPort"
        serviceName="tns:CalculadoraImplService" address="/CalculadoraImplPort">
        <jaxws:outInterceptors>
            <bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
            <ref bean="firmaRespuesta" />
        </jaxws:outInterceptors>
        <jaxws:inInterceptors>
            <ref bean="firmaPeticion" />
            <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
        </jaxws:inInterceptors>
    </jaxws:endpoint>

    <bean id="abstractLoggingInterceptor" abstract="true">
        <property name="prettyLogging" value="true" />
    </bean>
    <bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"
        parent="abstractLoggingInterceptor" />
    <bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"
        parent="abstractLoggingInterceptor" />

    <cxf:bus>
        <cxf:inInterceptors>
            <ref bean="loggingInInterceptor" />
        </cxf:inInterceptors>
        <cxf:outInterceptors>
            <ref bean="loggingOutInterceptor" />
        </cxf:outInterceptors>
        <cxf:outFaultInterceptors>
            <ref bean="loggingOutInterceptor" />
        </cxf:outFaultInterceptors>
        <cxf:inFaultInterceptors>
            <ref bean="loggingInInterceptor" />
        </cxf:inFaultInterceptors>
    </cxf:bus>

</beans>
 

No hay comentarios:

Publicar un comentario