JBoss.orgCommunity Documentation

User Guide

User Guide for SwitchYard 0.1


The Bean Component is a pluggable container in SwitchYard which allows Java classes (or beans) to provide and consume services. This means that you can implement a service by simply annotating a Java class. It also means you can consume a service by injecting a reference to that service directly into your Java class. Rather than writing our own POJO container to provide this capability, we have implemented the bean component as a Weld extension. No need to learn a new programming model - bean services are standard CDI beans with a few extra annotations. This also opens up the possibilities of how SwitchYard is used; you can now expose existing CDI-based beans in your application as services to the outside world or consume services within your bean.

Consuming a SwitchYard service from within a CDI bean is done via @Reference annotations.

Note that the contract for the service is all that's exposed to the bean consumer. The reference could point to a service that is hosted outside of SwitchYard and exposed over JMS, SOAP, FTP, etc. The SwitchYard runtime handles the resolution of the service reference to a concrete service, allowing your service logic to remain blissfully ignorant. Invocations made through this reference are routed through the SwitchYard exchange mechanism.

The @Reference annotation can accept a service name in cases where the default name resolution (interface Class simple name e.g. "OrderService") are not appropriate.

This can be useful when the default name resolution is not appropriate. Keep in mind that the name used by the reference is not required to match the target service, but it resolve to a service through some mechanism. For example, the deployed application could contain wiring configuration which maps the service name used by the bean reference to a different service name in the runtime.

Camel services allow you to leverage the core routing engine inside of Apache Camel to route between services in SwitchYard. The route itself is exposed as a service within SwitchYard, which means it has a well-defined contract and can be injected into any other service in the runtime. The routing logic can be expressed in XML and included directly in the service component configuration, or you can use the Java DSL to define the route in an annotated Java class.

SwitchYard provides an @Route annotation which can be used to declare that a class contains a Camel route which should be represented as a service in SwitchYard. The @Route annotation has a single required element which identifies the service interface to be used by the route. Aside from this annotation, the class looks exactly like a route that you would define in Camel alone.

When an application containing one or more Java DSL routes is built, the SwitchYard Maven plugin will automatically generate the required service component configuration in META-INF/switchyard.xml . The above route would produce the following configuration:

Configuring a Camel service using XML is done using the <implementation.camel> configuration directly as follows:

You'll notice in the above configuration that the route in the <implementation.camel> does not specify a from endpoint on the route definition. For Camel XML routes, Switchyard automatically adds this for the service. The above would be invokable by using the following code (snippet from a SwitchYard test):

Running the above code snippet would generate the following in you console log:

Camel binding support in SwitchYard allows Camel components to be used as gateway bindings for services and references within an application.

The SOAP component in SwitchYard provides SOAP-based web service binding support for services and references in SwitchYard.

Transformation represents a change to the format and/or representation of a message's content. The representation of a message is simply the Java contract (e.g. java.lang.String, org.example.MyFancyObject) used to access the underlying content. The format of a message refers to the actual structure of the data itself. Examples of data formats include XML, JSON, CSV, and EDI.

Take the following message content:

<MyBook>
  <Chapter1>
  <Chapter2>
</MyBook>

The format of this content is XML. One representation of XML in Java is as a String. Of course, the representation could also be a org.w3c.dom.Document, java.io.InputStream, etc.

String content = "<MyBook>...";

Transformation plays an important role in connecting service consumers and providers, since the format and representation of message content can be quite different between the two. For example, a SOAP gateway binding will likely use a different representation and format for messages than a service offered by a Java Bean. In order to route services from the SOAP gateway to the Bean providing the service, the format and representation of the SOAP message will need to change. Implementing the transformation logic directly in the consumer or provider pollutes the service logic and can lead to tight coupling. SwitchYard allows for the transformation logic to declared outside the service logic and injected into the mediation layer at runtime.

There are three distinct transformation models available with Smooks in SwitchYard:

  1. XML to Java : Based on a standard Smooks Java Binding configuration.

  2. Java to XML : Based on a standard Smooks Java Binding configuration.

  3. Smooks : This is a "normal" Smooks transformation in which the developer must define which Smooks filtering Result is to be exported back to the SwitchYard Message as the transformation result.

Smooks transformations are declared by including a <transform.smooks> definition in switchyard.xml.

<transform.smooks config="/smooks/OrderAck_XML.xml"
                  from="java:org.switchyard.quickstarts.transform.smooks.OrderAck"
                  to="{urn:switchyard-quickstart:transform-smooks:1.0}submitOrderResponse"
                  type="JAVA2XML"/>

The config attribute points to a Smooks resource containing the mapping definition. The type attribute can be one of SMOOKS , XML2JAVA , or JAVA2XML .

The JSON transformer provides a basically mapping facility between POJOs and JSON using the popular Jackson processor. Specification of the transformer requires one Java type and one named type. The following example converts a JSON serialization of an order to the Order object.

<trfm:transform.json
            from="{urn:switchyard-quickstart:transform-json:1.0}order"
            to="java:org.switchyard.quickstarts.transform.json.Order"/>

Each SwitchYard application must include a configuration descriptor named switchyard.xml in the /META-INF directory of it's archive. The basic structure of this descriptor is:

  • A parent <switchyard> element which contains all other configuration.

  • Exactly one child <composite> element, which contains the SCA description of the application.

  • Zero or one <transforms> elements which can contain one or more transform definitions.

Here's an example of what a SwitchYard descriptor looks like:

<switchyard xmlns="urn:switchyard-config:switchyard:1.0"   
            xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"   
            xmlns:bean="urn:switchyard-component-bean:config:1.0"   
            xmlns:soap="urn:switchyard-component-soap:config:1.0">   
    <sca:composite name="orders">       
        <sca:service name="OrderService" promote="OrderService">
            <soap:binding.soap>
                <soap:serverPort>18001</soap:serverPort>
                <soap:wsdl>wsdl/OrderService.wsdl</soap:wsdl>
            </soap:binding.soap>
        </sca:service>
        <sca:component name="InventoryService">
            <sca:service name="InventoryService">
                <sca:interface.java interface="org.switchyard.quickstarts.demos.orders.InventoryService"/>
            </sca:service>
            <bean:implementation.bean/>
        </sca:component>
        <sca:component name="OrderService">
            <sca:service name="OrderService">
                <sca:interface.java interface="org.switchyard.quickstarts.demos.orders.OrderService"/>
            </sca:service>
            <sca:reference name="InventoryService">
                <sca:interface.java interface="org.switchyard.quickstarts.demos.orders.InventoryService"/>
            </sca:reference>
            <bean:implementation.bean/>
        </sca:component>
    </sca:composite>
    <transforms xmlns="urn:switchyard-config:transform:1.0">
        <transform.java class="org.switchyard.quickstarts.demos.orders.Transformers"
                        from="{urn:switchyard-quickstart-demo:orders:1.0}submitOrder"
                        to="java:org.switchyard.quickstarts.demos.orders.Order"/>
        <transform.java class="org.switchyard.quickstarts.demos.orders.Transformers"
                        from="java:org.switchyard.quickstarts.demos.orders.OrderAck"
                        to="{urn:switchyard-quickstart-demo:orders:1.0}submitOrderResponse"/>
    </transforms>
</switchyard>

Luckily, SwitchYard can generate the bulk of the above description based off of annotations in your application code, so you won't have to muck with this XML directly. For the portions that can't be generated, Forge tooling fills the gap nicely. While you certainly can play with the XML directly, we try to do what we can to protect you from those pointy angle brackets.

The composition of a SwitchYard application is defined using the Service Component Architecture Assembly Model , an open specification undergoing standardization in OASIS . For the nitty gritty details of the assembly model, please consult the SCA specification. This section provides a brief overview of the important elements:

  • <composite> : single, top-level application element which defines a set of services, the relationships and dependencies of those services, and the linkage (if any) to services available outside the application.

  • <component> : contains the implementation of a service and the dependencies of that service

  • <service> : defines the name and interface for a service. This element is used inside a component definition to declare a service and can also appear inside a composite definition to indicate that a service is visible to outside applications.

  • <interface.XXX> : the contract for a service. The type of the interface replaces 'XXX' in the definition. Supported interface types at this point are "java" and "wsdl".

  • <binding.XXX> : the binding of a service. The type of the binding replaces 'XXX' in the definition. Example bindings include "binding.soap" and "binding.camel".

  • <implementation.XXX> : the implementation of a service. The type of the implementation replaces 'XXX' in the definition. Example implementations include 'implementation.bean" and "implementation.camel".

Testing your applications is dead simple with the comprehensive unit test support provided in SwitchYard. There are two primary elements to test support in SwitchYard:

  • SwitchYardTestCase - base unit test class which takes care of bootstrapping an embedded SwitchYard runtime and deploying the project as a SwitchYard application.

  • TestMixIn s - composition-based method for adding specific testing tools to your test case. Each MixIn provides customized testing tools for things like service implementations, gateway bindings, and transformers.

SwitchYard integrates with Seam Forge to provide a set of rapid application development tools for service-oriented applications. Please consult the Getting Started guide for information on how to install Forge and the SwitchYard extensions to Forge.