JBoss.orgCommunity Documentation

User Guide

User Guide for SwitchYard 0.2


1. Overview
2. Service Implementations
2.1. Bean Services
2.1.1. Providing a Service
2.1.2. Consuming a Service
2.1.3. Unit Testing
2.1.4. Forge Tooling
2.1.5. Bean Services In a Java EE Web Application Container
2.1.6. JavaServer Faces
2.2. Camel Services
2.2.1. Java DSL Routes
2.2.2. XML Routes
2.2.3. SwitchYard Endpoints
2.2.4. CDI Integration
2.3. BPM Services
2.3.1. Providing a Service
2.3.2. Consuming a Service
2.3.3. Unit Testing
2.3.4. Forge Tooling
2.4. Rules Services
2.4.1. Providing a Service
2.4.2. Consuming a Service
2.4.3. Unit Testing
2.4.4. Forge Tooling
3. Gateway Bindings
3.1. Camel Bindings
3.1.1. Binding Services with Camel
3.1.2. Binding References with Camel
3.2. SOAP Bindings
3.2.1. Binding Services with SOAP
3.2.2. Binding References with SOAP
4. Transformation
4.1. Adding Transformation to Your Application
4.2. Java Transfomer
4.3. Smooks Transformer
4.4. JSON Transformer
4.5. XSLT Transformer
4.6. JAXB Transformer
4.6.1. JAXB Java Model Creation
4.6.2. JAXB Transformer Configurations
4.6.3. Automatically Detected JAXB Transformations
5. Configuration
5.1. Composite
5.2. Transforms
5.3. Generated Configuration
6. Testing
6.1. Enabling Test Support
6.2. SwitchYardRunner and SwitchYardTestKit
6.3. SwitchYardTestCaseConfig
6.3.1. TestMixIns
6.3.2. Scanners
6.4. Metadata and Support Class Injections
6.4.1. Deployment Injection
6.4.2. SwitchYardModel Injection
6.4.3. ServiceDomain Injection
6.4.4. TransformerRegistry Injection
6.4.5. TestMixIn Injection
6.4.6. Invoker Injection
7. Deployment
7.1. Available Runtimes
7.2. SwitchYard AS6
7.3. SwitchYard AS7
7.3.1. Web Archive Deployments on SwitchYard AS7
7.4. Servlet Container Deployment
8. Tooling
8.1. Forge
8.1.1. Creating a Project
8.1.2. Facets
8.1.3. Commands
8.2. Administration Console
8.2.1. Overview
8.2.2. Console Layout
8.2.3. Application Details
8.2.4. Service Details
8.2.5. System Details

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.

Providing a service with the Bean component is as simple as adding an @Service annotation to your bean.

The SimpleService interface represents the Service Interface, defining the service operations that are exposed by SwitchYard.

The only other thing you need is a META-INF/beans.xml file in your deployed application. When the application is deployed, the Weld runtime scans the application for beans and enlists the SwitchYardCDIServiceDiscovery CDI extension in the CDI lifecycle. Our extension will pick up @Service beans and make them available to the application deployer (will depend on the container). At this point, the service can be invoked from other services within SwitchYard or bound to a wire protocol via SwitchYard gateways.

All SwitchYard Services, no matter what the implementation type, are composed of one or more Service Operations . As you might imagine, in the case of a Bean Service, the Service Operations are the set of Java methods exposed by the Service Interface.

There are a few restrictions when it comes to defining Bean Service Operations:

All Service Operations on a SwitchYard Service can define an Input , Output and Fault message. These messages have a type associated with them, which is defined as a QName. This type is used by the data transformation layer, when trying to work out which transformers to apply to a Message payload.

For bean Services, the default type QName for Input (input param), Output (return value) and Fault (Exception) are derived from the Java class name in each case (param, return, throws). For some types however (e.g. org.w3c.dom.Element ), the Java type name alone does not tell you the real type of the data being held by that Java Object instance. For this reason, Bean Service Operations (methods) can be annotated with the @OperationTypes annotation e.g.

It's also possible to set the default data type for a Java type using the @DefaultType Type level annotation. This is useful for setting the type for a hierarchy of Java types. Note in the example code above how we changed the type for OrderCreateFailureException (to "java:com.acme.exceptions.OrderManagementException") by defining a fault type on the @OperationTypes . It's type would otherwise default to "java:com.acme.exceptions.OrderCreateFailureException". We could also do this by annotating the base OrderManagementException class with the @DefaultType annotation. This would set the default type for the OrderManagementException class and all its sub-classes, including OrderCreateFailureException , which would mean not having to defining a fault type on the @OperationTypes wherever one of these exceptions is used on a Bean Service Operation.

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.

The JavaServer Faces (JSF) technology provides a server-side component framework that is designed to simplify the development of user interfaces (UIs) for Java EE applications. JSF has very tight integration with CDI to provide the Object Model behind the JSF user interface components.

The fact that SwitchYard Bean Services are based on CDI means it's possible to have a really nice integration between SwitchYard Bean Services and a JSF based user interface. This section is not an CDI or JSF reference, but does provide some tips/guidelines on using these technologies within the context of SwitchYard. This list of tips will grow and be refined as more use cases are tested and verified.

The following guidelines/tips should apply to any container when building a JSF user interface on top of a SwitchYard Service.

As with any JSF based user interface, the JSF pages will contain EL tokens referencing scoped CDI beans (by name ala the @Named bean annotation). It's possible to annotate your SwitchYard Service CDI beans with the @Named annotation and inject them directly into your application's JSF components, but that would result in your JSF pages making direct invocations on the Service implementation (i.e. the Service implementation bean would be injected directly into the JSF components). What you really want to do is to invoke your SwitchYard Services through the SwitchYard Exchange mechanism. This reduces the coupling between your JSF components and your SwitchYard Service implementations.

Currently, the only way to invoke a SwitchYard CDI Bean Service through the SwitchYard Exchange mechanism is to invoke them through a @Reference injected Service reference (other options may be available in future). This provides a client side proxy bean that handles all the SwitchYard Exchange invocation magic for all the operations exposed by the Service in question. The catch here is that these proxy beans are not available (through CDI) to the JSF components, so you need a bog standard named ( @Named ) CDI bean containing an injected @Reference sitting between the JSF components and the SwitchYard CDI Bean Services. This is not really a problem though, because your JSF components will likely have a more natural interaction with a business/model type value-object bean (getters/setters) than they will with a Service interface type bean (operations). So, a layer of indirection will probably make sense anyway.

So if you consider an example of an OrderService (Service implementation not shown):

Your JSF components will probably have a more natural interaction with the Order bean than with the OrderService e.g.:

However, in order to make this work, we need to make a few tweaks to the Order bean:

To reiterate, because of the @Reference annotation, the orderService property instance is not a reference to the actual Service implementation. Instead, it is a SwitchYard Exchange proxy to that Service implementation.

Also note that by using @Reference injected Service references, your backend Service implementation can be a non CDI Bean Service implementation e.g. a Camel Routing Services. This mechanism opens up all sorts of integration possibilities!

See the "orders" quickstart (in the demos folder) as an example of how to provide a JSF user interface on top of a SwitchYard CDI Bean Service deployed on SwitchYard AS7.

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:

The BPM Component is a pluggable container in SwitchYard which allows a business process to be exposed as a service. One fronts their business process with a custom interface and, if desired, can easily annotate it's methods to define which should start a process, signal a process event, or abort a process.

To provide a service with the BPM component, you will have to:

Here is an example of the component section of the SwitchYard configuration:

The MyService interface can be as simple as this, with no SwitchYard-specific imports:

However, if you want to have the SwitchYard configuration for this section auto-generated for you, you can use annotations and the SwitchYard Maven Plugin. To do this, you can either add SwitchYard-specific annotations to your interface directly, or (and this is the recommended approach) you can create a separate interface for this purpose. Let's do that:

That's all you need to create the SwitchYard configuration you saw above! The values for the processDefinition, processDefinitionType and processId are all defaulted based on the name of the Process interface (the "value" to the Process annotation), however you can override these if you desire:

At this point you might be wondering what the resources and taskHandlers attributes of the Process annotation are, and how did the SwitchYardServiceTaskHandler is that got added automatically in the SwitchYard configuration above.

First, a Resource represents an additional artifact that is required by your BPM process. It could be anything you could think of, including a properties file, a Drools Rule Language file, or whatever. But it needs to be available to the BPM component's runtime for that process. You can either add the resource to the XML yourself, which would like like this:

, or you can add a class which represents the Resource, and reference that class in the resources attribute of the Process annotation, like this:

A note about Resources: In SwitchYard 0.3, it is expected that the resources attribute of the Process annotation will change from a Class array to a String array, and the resource type (eg: "DRL") will be deduced from the file extension. This will make the annotated class a lot smaller. You can track the progress of this change via jira issue SWITCHYARD-428 .

Next, a TaskHandler is a way for you to add your own code into the business process. Simply implement the org.switchyard.component.bpm.task.TaskHandler interface, and add it to the SwitchYard configuration, either manually in XML, or by referencing your implementation via the taskHandlers attribute of the Process annotation, similarly to how we did with Resources above. A BaseTaskHandler abstract class is available for you to extend, implementing all the boilerplate code, leaving you to just plug in your business logic.

By default, the SwitchYardServiceTaskHandler is always added for you by the SwitchYard Maven plugin. That handler allows you to easily call out to other SwitchYard services by name within your business process. Please see the section "Consuming a BPM Service" below for more information.

In addition to the interface-level Process annotation, there are also three method-level annotations available to you. Here is an example:

This will then create the following SwitchYard configuration (note that the default processAction type is START_PROCESS for a method, which is why in our original version of this example we didn't have to use the @StartProcess annotation):

There are two ways of consuming Services with the SwitchYard BPM component. The first way is to invoking the BPM implementation through a gateway binding, and the second is invoking other SwitchYard Services from within a BPM process itself.

Since the BPM component exposes a java interface fronting the business process, you can use any of the bindings provided by SwitchYard. This could be a SOAP Binding or a Camel Binding , for example. Please refer to those sections of this guide for more information.

To invoke a SwitchYard Service from inside a BPM process, we use the SwitchYardServiceTaskHandler (provided out-of-the-box) which we described above. To make authoring BPMN2 processes easier, SwitchYard provides a new widget for the jBPM 5 Eclipse visual editor palette. Here is a screenshot from the "Help Desk" demo quickstart:


On the left hand side under "Service Tasks", you can see the SwitchYard Service widget. On the right hand side, you can see the various points of the business process where SwitchYard Services are being invoked. Once you have dropped a SwitchYard Service task in the main window, you can customize it via the Eclipse Properties Editor. The two properties you will care about most are ServiceName and ServiceOperationName . In our example, we might have a different Service called "AnotherService", with a method called "doSomething". To invoke that operation of that service, we would configure those properties respectively. That's all there is to it!

You can read a more detailed explanation of the Help Desk quickstart demo, as well as how to set up Eclipse to make use of new widget, on this wiki page .

The Rules Component is a pluggable container in SwitchYard which allows business rules to be exposed as a service. One fronts their rules with a custom interface and, if desired, can easily annotate it's methods to define which should execute the rules.

To provide a service with the Rules component, you will have to:

  1. Define your rules. The Rules Component currently supports Drools as the rule engine. Even though it is quite simple to write rules in Drools , that project's developer tooling and business analyst tooling are very mature.

  2. Create a java interface, fronting your rules, which can be exposed to other services, and/or to your binding(s).

  3. Add the component containing the implementation and service interface to the SwitchYard configuration. This step can be automated using annotations and the SwitchYard plugin, explained below.

Here is an example of the component section of the SwitchYard configuration:

<component name="MyService">
    <implementation.rules xmlns="urn:switchyard-component-rules:config:1.0" stateful="false">
        <rulesAction name="process" type="EXECUTE_RULES"/>
        <resource xmlns="urn:switchyard-config:switchyard:1.0" location="/org/switchyard/userguide/MyService.drl" type="DRL"/>
    </implementation.rules>
    <service name="MyService">
        <interface.java interface="org.switchyard.userguide.MyService"/>
    </service>
</component>

The MyService interface can be as simple as this, with no SwitchYard-specific imports:

package org.switchyard.userguide;
public interface MyService {
    public void process(MyData data);
}

However, if you want to have the SwitchYard configuration for this section auto-generated for you, you can use annotations and the SwitchYard Maven Plugin. To do this, you can either add SwitchYard-specific annotations to your interface directly, or (and this is the recommended approach) you can create a separate interface for this purpose. Let's do that:

package org.switchyard.userguide;
import org.switchyard.component.rules.ExecuteRules;
import org.switchyard.component.rules.Rules;
@Rules(value=MyService.class, stateful="false", resources={MyServiceDrl.class})
public interface MyServiceRules extends MyService {
    @ExecuteRules @Override
    public void process(MyData data);
    public static final class MyServiceDrl extends SimpleResource {
        public MyServiceDrl() {
          super("/org/switchyard/userguide/MyService.drl", "DRL");
        }
    }
}

That will create the SwitchYard configuration you saw above!

A few important points:

  1. In the original switchyard xml, the <rulesAction/> element is optional. If not specified, the behavior is to execute the rules. In the future, more rulesActions will be supported.

  2. You will have to configure the switchyard maven plugin with the RulesSwitchYardScanner .

  3. The "stateful" attribute is not necessary. It defaults to "false" (stateless). Please visit the Drools documentation to learn more about stateless vs. stateful knowledge sessions .

  4. You can list as many resources as the Drools knowledge session requires.

  5. You don't have to define the drl in java. You can create a switchyard.xml file with the drl defined (as shown in the first example), and the plugin will merge what it found via annotations with what you provided in a preliminary switchyard.xml file.

A note about Resources: In SwitchYard 0.3, it is expected that the resources attribute of the Rules annotation will change from a Class array to a String array, and the resource type (eg: "DRL") will be deduced from the file extension. This will make the annotated class a lot smaller. You can track the progress of this change via jira issue SWITCHYARD-428 .

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.

Composite-level services can be exposed as a SOAP-based web service using the <binding.soap> binding definition. The following configuration options are available for binding.soap when binding services:

Here's an example of what a SOAP service binding looks like:

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 basic mapping facility between POJOs and JSON (JSON marshalling and unmarshalling). Just like the JAXB Transformer , specification of the transformer requires a to and from specification with one Java type and one QNamed JSON type, depending on whether you're performing a Java to JSON or JSON to Java transformation.

The following configuration illustrates a JSON to Java transformation.

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

The following configuration illustrates a Java to JSON transformation of the same types as above.

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

The XSLT transformer allows you to perform a transformation between 2 types, using an XSLT . It is configured simply by specifying the to and from QNames, as well as the path to the XSLT to be applied.

<transform.xslt from="{http://acme/}A" to="{http://acme/}B" xsltFile="com/acme/xslt/A2B.xslt"/>

The JAXB transformer allows you to perform Java to XML (and XML to Java) transformations using JAXB (XML marshalling and unmarshalling). It is exactly like the JSON Transformer in terms of how it is configured i.e. a to and from configuration with one Java type and one QNamed XML type.

One of the nice things about the JAXB Transformer integrations in SwitchYard is the fact that JAXB Transformations are automatically detected and automatically added, for your application deployment. So, if for example, you develop a CDI Bean Service and use JAXB generated types in the Service Interface, you will not need to configure any of the transformations. SwitchYard will automatically detect their availability for your application and will automatically apply them at the appropriate time during service invocation.

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" targetNamespace="urn:switchyard-quickstart-demo:orders:0.1.0">       
        <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">
            <bean:implementation.bean class="org.switchyard.quickstarts.demos.orders.InventoryServiceBean"/>
            <sca:service name="InventoryService">
                <sca:interface.java interface="org.switchyard.quickstarts.demos.orders.InventoryService"/>
            </sca:service>
        </sca:component>
        <sca:component name="OrderService">
            <bean:implementation.bean class="org.switchyard.quickstarts.demos.orders.OrderServiceBean"/>
            <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>
        </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 three primary elements to test support in SwitchYard:

  • SwitchYardRunner : JUnit test Runner class which takes care of bootstrapping an embedded SwitchYard runtime and deploying a SwitchYard application for the test instance. Its behavior is influenced heavily by the optional SwitchYardTestCaseConfig annotation. Its runtime state is represented by the SwitchYardTestKit .

  • SwitchYardTestKit : represents the runtime state of the deployed SwitchYard application instance deployed by SwitchYardRunner . Also provides access to a set of test utility methods for the test (e.g. assertion methods). The SwitchYardTestKit is reflectively injected into the test instance, if a property of type SwitchYardTestKit is declared in the test.

  • SwitchYardTestCaseConfig : optional annotation allows additional information to be specified for controlling the behavior of the SwitchYardRunner .

To take advantage of the test support in SwitchYard, your unit test should be annotated with the SwitchYardRunner JUnit test Runner class. SwitchYardRunner takes care of creating and starting an embedded runtime for each test method. After the embedded runtime is started, the project containing the test is packaged as a SwitchYard application and deployed to it. The runtime state of the deployed SwitchYard test application is represented by an instance of the SwitchYardTestKit class, which is injected into the test when a property of type SwitchYardTestKit is declared in the test.

@RunWith(SwitchYardRunner.class)
public class MyServiceTest  {

    private SwitchYardTestKit testKit;

    @Test   
    public void testOperation() {
        MyTestServiceHandler service = new MyTestServiceHandler();

        // register the service...
        testKit.registerInOutService("MyService", service);
        
        // invoke the service and capture the response...
        Message response = newInvoker("MyService")
        .sendInOut("<create>A1234</create>");

        // test the response content by doing an XML comparison with a 
        // file resource on the classpath...
        testKit.compareXMLToResource(response.getContent(String.class), "/myservice/expected-create-response.xml");
    }

    private class MyTestServiceHandler implements ExchangeHandler {
        // implement methods....
    }
}

The SwitchYardTestKit provides a set of utility methods for performing all sorts of deployment configuration and test operations.

The optional SwitchYardTestCaseConfig annotation can be used control the behavior of the SwitchYardRunner :

As shown above, injecting the SwitchYardTestKit instance into the test at runtime is simply a case of declaring a property of that type in the test class.

The SwitchYard test framework also injects other test support and metadata classes, which we outline in the following sections.

Things are a bit different in SwitchYard AS7 (based on JBoss AS7). Auto-deploy still exists, but there are some subtle changes to the process. Deploy is still just a matter of copying the archive to the server, but the target directory should be standalone/deployments .

To undeploy the application, you need to remove the .deployed marker file that is generated upon successful deployment of your application:

You can find more information on the ins and outs of deployment on JBoss AS7 in the README.txt file contained in the standalone/deployments directory of the distribution.

The following guidelines/tips apply when deploying Web Archive (.war) based SwitchYard deployments on a SwitchYard AS7 distribution.

See the "orders" quickstart (in the demos folder) as an example of .war deployment on SwitchYard AS7.

Some maven POM tweaks are required when using both the switchyard-plugin and maven-war-plugin plugins to build a SwitchYard deployable .war file. By default, the switchyard-plugin expects the base switchyard.xml file to be located at src/main/resources/META-INF/ within your maven project structure. This results in the maven-war-plugin putting the generated switchyard.xml (base switchyard.xml + scanned additions) into WEB-INF/classes/META-INF/ in the generated .war artifact. This is fine when deploying a .war file on Tomcat (or other pure Servlet Container), but not when deploying on SwitchYard AS7, because the SwitchYard AS7 deployer is what's doing the SwitchYard deployment work. When deploying a .war on SwitchYard AS7, we need the generated switchyard.xml to be in META-INF/ , where it can be located by the SwitchYard AS7 deployer.

In order to do this we need to move away from the defaults a little bit. We need to locate the base switchyard.xml somewhere other than in src/main/resources/META-INF/ , and configure the switchyard-plugin and maven-war-plugin accordingly. Lets assume we put the base switchyard.xml in src/main/webResources/META-INF/ :


The POM configuration changes (away from the default) to the switchyard-plugin and maven-war-plugin plugins would be as follows:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    ...

    <build>
        <plugins>
 
            ...

            <plugin>
                <groupId>org.switchyard</groupId>
                <artifactId>switchyard-plugin</artifactId>
                <version>0.3.0-SNAPSHOT</version>
                <configuration>
                    <scannerClassNames>
                        <param>org.switchyard.component.bean.config.model.BeanSwitchYardScanner</param>
                        <param>org.switchyard.transform.config.model.TransformSwitchYardScanner</param>
                        ...
                    </scannerClassNames>
                    <!-- 
                        Specify specific scan directories to reflect the new location of the
                        base switchyard.xml ...
                    -->
                    <scanDirectories>
                        <param>target/classes</param>
                        <param>src/main/webResources</param>
                    </scanDirectories>
                    <!-- 
                        Specify different output directory for the generated switchyard.xml because we don't
                        want it ending up in WEB-INF/classes/META-INF.  The maven-war-plugin is configured to
                        pick up the generated switchyard.xml from this new location...
                    -->
                    <outputDirectory>target/switchyard_xml</outputDirectory>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>configure</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1.1</version>
                <configuration>
                    <!-- Java EE 6 doesn't require web.xml, Maven needs to catch up! -->
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <webResources>
                        <resource>
                            <!-- 
                                Pick up the generated switchyard.xml from location specified by 
                                the switchyard-plugin...
                            -->
                            <directory>target/switchyard_xml</directory>
                        </resource>
                    </webResources>
                </configuration>
            </plugin>

            ...

        </plugins>
    </build>
</project>

See the "orders" quickstart (in the demos folder) as an example of .war deployment on SwitchYard AS7.

SwitchYard provides a Servlet <listener-class> in support for deploying SwitchYard applications in a Java EE Web Application Container such as Tomcat or Jetty. To use this component, you simply need to include the switchyard-deploy-webapp artifact as a dependency on your web application project.

You then need to add the WebApplicationDeployer class as a Servlet <listener-class> in your application's web.xml file.

The WebApplicationDeployer class looks for a switchyard.xml file at WEB-INF/classes/META-INF/switchyard.xml , so if you are using maven to build your Web Application, you need to put your switchyard.xml in the resources/META-INF folder (i.e. not in webapp/META-INF ). Your basic project structure should look as follows.


Once you've made these configurations, the process of creating the Web Application is no different to developing any other Web Application. Note however that, since this is only a new feature in version 0.2.0, we have tested only a very limited set of use cases:

  1. A Basic SwitchYard .war deployment:

  2. A more detailed SwitchYard .war deployment:

    • Without any dependencies bundled in the application and structured to work on the SwitchYard AS7 distribution.

    • Deployable on the SwitchYard AS7 distribution (Not deployable on Tomcat or Jetty).

    • More detailed CDI Bean Service.

    • SOAP binding on the CDI Bean Service.

    • JSF web ui interface on the CDI Bean Service. For more information on building a JSF interface on top of your SwitchYard CDI Bean Services, see the Bean Services documentation .

    • See the "orders" quickstart (in the demos).

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.

The following SwitchYard commands are available in Forge (grouped by facet).

switchyard

switchyard.bean

switchyard.bpm

switchyard.rules

switchyard.camel

switchyard.soap

Clicking on an item under the Applications section in the navigator will open the application details in the content panel. This panel displays a Services and Transformers tab.