Friday, September 30, 2011

Mule Expression Transformers

Java Classes:

GameData: 

A simple POJO object.

package com.expressiontransformers;

public class GameData {

    private String gameName;
    private int year;

    public String getGameName() {
        return gameName;
    }

    public void setGameName(String gameName) {
        this.gameName = gameName;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

}

GameInfo:

Another simple POJO that contains the GameData Object.

package com.expressiontransformers;

public class GamingInfo {

    private int gameId;

    private GameData gameData;

    public int getGameId() {
        return gameId;
    }

    public void setGameId(int gameId) {
        this.gameId = gameId;
    }

    public GameData getGameData() {
        return gameData;
    }

    public void setGameData(GameData gameData) {
        this.gameData = gameData;
    }

}


Here we will be using two component classes. One is used to generate the GameInfo Object and the other is used to print the values.

CreateGamingInfoComponent:

package com.expressiontransformers;

public class CreateGamingInfoComponent {

    public GamingInfo create(String msg) {
        GamingInfo info = new GamingInfo();
        info.setGameId(1);
        
        GameData data = new GameData();
        data.setGameName("Cricket");
        data.setYear(2010);
        
        info.setGameData(data);
        return info;
    }
}


GamingComponent:

package com.expressiontransformers;

public class GamingComponent {

    public void addGame(Integer gameId, GameData data) {
        
        System.out.println(gameId);
        System.out.println(data.getGameName());
        System.out.println(data.getYear());
    }
}

Mule-config.xml:

The mule-config.xml uses the expression-transformer in the inbound-endpoint to convert the input GameInfo object to the required values of the GamingComponent.

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:stdio="http://www.mulesource.org/schema/mule/stdio/2.2"
    xmlns:vm="http://www.mulesource.org/schema/mule/vm/2.2"
    xsi:schemaLocation="
          http://www.mulesource.org/schema/mule/core/2.2 http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
          http://www.mulesource.org/schema/mule/stdio/2.2 http://www.mulesource.org/schema/mule/stdio/2.2/mule-stdio.xsd
          http://www.mulesource.org/schema/mule/vm/2.2 http://www.mulesource.org/schema/mule/vm/2.2/mule-vm.xsd">

    <stdio:connector name="stdioIN" promptMessage="Press any key to Continue" />

    <model name="RestaurantServiceE">
        <service name="ExpressionFilterService">
            <inbound>
                <stdio:inbound-endpoint system="IN"
                    connector-ref="stdioIN" />
            </inbound>
            <component
                class="com.expressiontransformers.CreateGamingInfoComponent" />
            <outbound>
                <pass-through-router>
                    <vm:outbound-endpoint path="displayGamingInfo-channel" />
                </pass-through-router>
            </outbound>
        </service>

        <service name="DisplayInfoService">
            <inbound>
                <vm:inbound-endpoint path="displayGamingInfo-channel">
                    <expression-transformer>
                        <return-argument expression="gameId"
                            evaluator="bean" />
                        <return-argument expression="gameData"
                            evaluator="bean" />
                    </expression-transformer>
                </vm:inbound-endpoint>
            </inbound>
            <component class="com.expressiontransformers.GamingComponent" />
        </service>
    </model>
</mule>

Monday, September 26, 2011

Log4j, Mx4j and JMX JConsole Configuration in Mule

Sample Configuration File:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:http="http://www.mulesource.org/schema/mule/http/2.2"
    xmlns:https="http://www.mulesource.org/schema/mule/https/2.2"
    xmlns:saaj="http://www.mulesource.org/schema/mule/saaj/2.2"
    xmlns:vm="http://www.mulesource.org/schema/mule/vm/2.2"
    xmlns:mule-xml="http://www.mulesource.org/schema/mule/xml/2.2"
    xmlns:management="http://www.mulesource.org/schema/mule/management/2.2"
    xmlns:spring="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="
          http://www.mulesource.org/schema/mule/http/2.2 http://www.mulesource.org/schema/mule/http/2.2/mule-http.xsd
          http://www.mulesource.org/schema/mule/https/2.2 http://www.mulesource.org/schema/mule/https/2.2/mule-https.xsd
          http://www.mulesource.org/schema/mule/saaj/2.2 http://www.mulesource.org/schema/mule/saaj/2.2/mule-saaj.xsd
          http://www.mulesource.org/schema/mule/core/2.2 http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
          http://www.mulesource.org/schema/mule/vm/2.2 http://www.mulesource.org/schema/mule/vm/2.2/mule-vm.xsd
          http://www.mulesource.org/schema/mule/xml/2.2 http://www.mulesource.org/schema/mule/xml/2.2/mule-xml.xsd
          http://www.mulesource.org/schema/mule/management/2.2 http://www.mulesource.org/schema/mule/management/2.2/mule-management.xsd
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!--

        Mule Management Console Configurations START............
        Register the Mx4j Console...............................
        Register the JMX Console................................
        Register Log4j Console..................................
    -->
    <management:jmx-default-config port="1098"
        registerMx4jAdapter="true">
        <management:credentials>
            <spring:entry key="vijay" value="vijay123" />
        </management:credentials>
    </management:jmx-default-config>

    <management:jmx-log4j />

    <!-- 
        Mule Management Console Configurations END.
     -->
</mule> 

Handling SOAP Fault with Http Web Service

The sample XML configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:http="http://www.mulesource.org/schema/mule/http/2.2"
    xmlns:https="http://www.mulesource.org/schema/mule/https/2.2"
    xmlns:saaj="http://www.mulesource.org/schema/mule/saaj/2.2"
    xmlns:vm="http://www.mulesource.org/schema/mule/vm/2.2"
    xmlns:mule-xml="http://www.mulesource.org/schema/mule/xml/2.2"
    xmlns:management="http://www.mulesource.org/schema/mule/management/2.2"
    xmlns:spring="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="
          http://www.mulesource.org/schema/mule/http/2.2 http://www.mulesource.org/schema/mule/http/2.2/mule-http.xsd
          http://www.mulesource.org/schema/mule/https/2.2 http://www.mulesource.org/schema/mule/https/2.2/mule-https.xsd
          http://www.mulesource.org/schema/mule/saaj/2.2 http://www.mulesource.org/schema/mule/saaj/2.2/mule-saaj.xsd
          http://www.mulesource.org/schema/mule/core/2.2 http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
          http://www.mulesource.org/schema/mule/vm/2.2 http://www.mulesource.org/schema/mule/vm/2.2/mule-vm.xsd
          http://www.mulesource.org/schema/mule/xml/2.2 http://www.mulesource.org/schema/mule/xml/2.2/mule-xml.xsd
          http://www.mulesource.org/schema/mule/management/2.2 http://www.mulesource.org/schema/mule/management/2.2/mule-management.xsd
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!--

        Mule Management Console Configurations START............
        Register the Mx4j Console...............................
        Register the JMX Console................................
        Register Log4j Console..................................
    -->
    <management:jmx-default-config port="1098"
        registerMx4jAdapter="true">
        <management:credentials>
            <spring:entry key="vijay" value="vijay123" />
        </management:credentials>
    </management:jmx-default-config>

    <management:jmx-log4j />

    <!-- 
        Mule Management Console Configurations END.
     -->

    <spring:beans>
        <spring:import resource="transformers.xml" />
    </spring:beans>

    <custom-transformer
        class="com.restaurantsrevice.transformers.DocumentToSOAPFaultTransformer"
        name="faultTransformer">
        <spring:property name="propagateHeaders" value="false" />
    </custom-transformer>

    <model name="RestaurantServiceModel">

        <!-- Default Service Exception Strategy -->
        <default-service-exception-strategy>
            <vm:outbound-endpoint path="exception-channel" />
        </default-service-exception-strategy>

        <service name="RestaurantService">
            <inbound>
                <http:inbound-endpoint
                    address="http://localhost:8080/RestaurantService"
                    synchronous="true">
                    <transformers>

                        <!-- Transform Incoming Soap Message to XML String -->
                        <saaj:soap-message-to-document-transformer />
                        <mule-xml:dom-to-xml-transformer
                            returnClass="java.lang.String" />
                    </transformers>
                </http:inbound-endpoint>
            </inbound>
            <outbound>
                <pass-through-router>
                    <vm:outbound-endpoint path="router-channel"
                        synchronous="true" />
                </pass-through-router>
            </outbound>

            <async-reply>
                <vm:inbound-endpoint path="success-response-channel"
                    synchronous="true" />
                <vm:inbound-endpoint path="exception-response-channel"
                    synchronous="true" />
                <single-async-reply-router />
            </async-reply>
        </service>

        <service name="RouterService">
            <inbound>
                <vm:inbound-endpoint path="router-channel"
                    synchronous="true" />
            </inbound>
            <log-component />
            <outbound>
                <filtering-router>
                    <vm:outbound-endpoint path="request-processing-channel"
                        synchronous="true">
                        <transformer ref="addFoodRequestTransformer" />
                    </vm:outbound-endpoint>
                    <wildcard-filter pattern="*AddFoodRequest*" />
                </filtering-router>
            </outbound>
        </service>

        <service name="RequestProcessingService">
            <inbound>
                <vm:inbound-endpoint path="request-processing-channel"
                    synchronous="true" />
            </inbound>
            <component
                class="org.restaurantservice.RestaurantService"></component>
            <outbound>
                <filtering-router>
                    <vm:outbound-endpoint path="success-response-channel">
                        <transformers>
                            <transformer ref="addFoodResponseTransformer" />

                            <!-- Transform XML to SOAP response -->
                            <mule-xml:xml-to-dom-transformer
                                returnClass="org.w3c.dom.Document" />
                            <saaj:document-to-soap-message-transformer
                                propagateHeaders="false" />
                        </transformers>
                    </vm:outbound-endpoint>
                    <payload-type-filter
                        expectedType="com.services.restaurantservice.AddFoodResponse" />
                </filtering-router>
            </outbound>
        </service>

        <service name="ExceptionService">
            <inbound>
                <vm:inbound-endpoint path="exception-channel"
                    synchronous="true" />
            </inbound>
            <component
                class="com.services.restaurantservice.components.ExceptionHandler" />
            <outbound>
                <filtering-router>
                    <vm:outbound-endpoint path="exception-response-channel"
                        synchronous="true">

                        <transformers>
                            <transformer
                                ref="FoodAdditionFailedExceptionMap" />
                            <!-- Transform to Document Object -->
                            <mule-xml:xml-to-dom-transformer
                                returnClass="org.w3c.dom.Document" />

                            <!-- Transform to SOAP Fault -->
                            <transformer ref="faultTransformer" />
                        </transformers>

                    </vm:outbound-endpoint>
                    <payload-type-filter
                        expectedType="com.services.restaurantservice.webservice.FoodAdditionFailed" />
                </filtering-router>
                <filtering-router>
                    <vm:outbound-endpoint path="exception-response-channel"
                        synchronous="true">

                        <transformers>
                            <transformer ref="IncompleteRequestExceptionMap" />
                            <!-- Transform to Document Object -->
                            <mule-xml:xml-to-dom-transformer
                                returnClass="org.w3c.dom.Document" />

                            <!-- Transform to SOAP Fault -->
                            <transformer ref="faultTransformer" />
                        </transformers>

                    </vm:outbound-endpoint>
                    <payload-type-filter
                        expectedType="com.services.restaurantservice.webservice.IncompleteRequest" />
                </filtering-router>
            </outbound>
        </service>
    </model>
</mule> 
Java Code to transform to Soap Fault:
package com.restaurantsrevice.transformers;

import javax.xml.namespace.QName;
import javax.xml.soap.Detail;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;

import org.mule.api.MuleMessage;
import org.mule.api.transformer.TransformerException;
import org.mule.module.saaj.SaajUtils;
import org.mule.module.saaj.i18n.SaajMessages;
import org.mule.transformer.AbstractMessageAwareTransformer;
import org.w3c.dom.Document;

public class DocumentToSOAPFaultTransformer extends
        AbstractMessageAwareTransformer {

    private boolean propagateHeaders = true;
    private String headerURI = "http://www.mulesource.org/schema/mule/saaj/2.2";
    private String headerPrefix = "mule-saaj";

    private SOAPFactory soapFactory;
    private MessageFactory messageFactory;

    public DocumentToSOAPFaultTransformer() throws Exception {
        soapFactory = SOAPFactory.newInstance();
        messageFactory = MessageFactory.newInstance();
    }

    public void setPropagateHeaders(boolean propagateHeaders) {
        this.propagateHeaders = propagateHeaders;
    }

    public void setHeaderURI(String headerURI) {
        this.headerURI = headerURI;
    }

    public void setHeaderPrefix(String headerPrefix) {
        this.headerPrefix = headerPrefix;
    }

    public Object transform(MuleMessage muleMessage, String s)
            throws TransformerException {

        Document document = (Document) muleMessage.getPayload();
        SOAPMessage soapMessage;

        try {
            soapMessage = messageFactory.createMessage();
            SOAPBody body = soapMessage.getSOAPBody();

            addFault(body, document);

            if (propagateHeaders) {
                propagateHeaders(muleMessage, soapMessage);
            }
            soapMessage.saveChanges();
        } catch (SOAPException ex) {
            throw new TransformerException(SaajMessages
                    .failedToBuildSOAPMessage());
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Transformation result: "
                    + SaajUtils.getSOAPMessageAsString(soapMessage));
        }

        return SaajUtils.getSOAPMessageAsBytes(soapMessage);
    }

    void propagateHeaders(MuleMessage muleMessage, SOAPMessage soapMessage)
            throws SOAPException {
        for (Object n : muleMessage.getPropertyNames()) {
            String propertyName = (String) n;
            SOAPHeader header = soapMessage.getSOAPHeader();

            Name name = soapFactory.createName(propertyName, headerPrefix,
                    headerURI);
            SOAPHeaderElement headerElement = header.addHeaderElement(name);
            headerElement.addTextNode(muleMessage.getProperty(propertyName)
                    .toString());
        }
    }

    private void addFault(SOAPBody soapBody, Document document)
            throws SOAPException {

        org.w3c.dom.Element docElement = document.getDocumentElement();
        QName qName = new QName(docElement.getLocalName());

        SOAPFault soapFault = soapBody.addFault(qName, docElement
                .getTextContent());

        Detail detail = soapFault.addDetail();
        detail.addChildElement(soapFactory.createElement(docElement));
    }

}

Sunday, September 25, 2011

Customization of WSDL using bindings.xml

<?xml version="1.0" encoding="UTF-8"?>
<jaxws:bindings wsdlLocation="RestaurantService.wsdl"
    xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

    <jaxws:bindings node="wsdl:definitions/wsdl:types/xsd:schema">
        <jaxb:globalBindings choiceContentProperty="true" 
            collectionType="java.util.Set"
            generateIsSetMethod="true"
            enableJavaNamingConventions="true">
            <!--
                <jaxb:javaType name="java.util.Date"
                xmlType="xs:dateTime"
                parseMethod="org.apache.cxf.tools.common.DataTypeAdapter.parseDateTime"
                printMethod="org.apache.cxf.tools.common.DataTypeAdapter.printDateTime"/>
                <jaxb:javaType name="java.util.Date" xmlType="xs:date"
                parseMethod="org.apache.cxf.tools.common.DataTypeAdapter.parseDate"
                printMethod="org.apache.cxf.tools.common.DataTypeAdapter.printDate"/>
            -->
        </jaxb:globalBindings>
    </jaxws:bindings>
</jaxws:bindings> 


Reference Link