Chapter 20. Reference

20.1. Configuration Descriptors

Each SwitchYard application must include a configuration descriptor named switchyard.xml in the /META-INF directory of its archive. The basic structure of this descriptor is:
  • A parent <switchyard> element, which contains all other configuration.
  • One child <composite> element, which contains the SCA description of the application.
  • No more than one <transforms> element, which can contain one or more transform definitions.
  • No more than one <validates> element, which can contain one or more validate definitions.

20.2. Descriptor Configuration Example

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:socketAddr>:18001</soap:socketAddr>
                <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 bean="Transformers"
                        from="{urn:switchyard-quickstart-demo:orders:1.0}submitOrder"
                        to="java:org.switchyard.quickstarts.demos.orders.Order"/>
        <transform.java bean="Transformers"
                        from="java:org.switchyard.quickstarts.demos.orders.OrderAck"
                        to="{urn:switchyard-quickstart-demo:orders:1.0}submitOrderResponse"/>
    </transforms>
    <validates>
        <validate.java bean="Validators"
                        name="java:org.switchyard.quickstarts.demos.orders.Order"/>
        <validate.java bean="Validators"
                        name="java:org.switchyard.quickstarts.demos.orders.OrderAck"/>
    </validates>
</switchyard>

Note

Do not edit the SwitchYard.xml file directly. Red Hat recommends using the JBoss Developer Studio SwitchYard Editor to edit the SwitchYard.xml file.

20.3. Composite

The composition of a SwitchYard application is defined using the Service Component Architecture Assembly Model, an open specification undergoing standardization in OASIS. Through this, a number of elements can be added to a service.

20.4. Composite Elements

Table 20.1. Composite Elements

Name Description
<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 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.

20.5. The Transforms Definition

The <transforms> definition is used to define transformers local to your application. Much like interfaces, bindings, and implementations, each transformer definition includes a type in its definition (e.g. transform.java, transform.smooks). The from and to definitions on each transformer correspond to the message type used on a service and/or reference interface used within SwitchYard.

20.6. The Validates Definition

The <validates> definition is used to set validators locally to your application. Similar to transformers, each validator definition includes a type in its definition (e.g. validate.java, validate.xml). The name definition on each validator corresponds to the message type used on a service and/or reference interface used within SwitchYard.

20.7. Generated Configuration

SwitchYard is capable of generating configurations from annotations in an application code. This negates the need to edit the XML configuration manually. The generated configuration is packaged with the application as part of the Maven build life cycle. It is located in target/classes/META-INF/switchyard.xml. (You may also place a descriptor in src/main/resources/META-INF/switchyard.xml.)
This version of the configuration can be edited by the user directly and is also used by Forge tooling to specify configuration in response to SwitchYard forge commands. During the build process, the user-editable switchyard.xml is merged with any generated configuration to produce the final switchyard.xml in the target/ directory.

20.8. Service Operations

All SwitchYard services, no matter their implementation type, are composed of one or more service operations. In the case of a Bean service, the service operations are the set of Java methods exposed by the service interface.
A Bean service operation does the following:
  • Declares a maximum of one Input type. The Java method signature must have a maximum of one Java parameter.
  • Declares a maximum of one Output type. This is enforced by the Java language. You can only define one return type on a Java method.
  • Declares a maximum of one Fault (exception) type.

20.9. Service Operation Types

All service operations on a SwitchYard service can define Input, Output and Fault messages. 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 (such as 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.

20.10. The @DefaultType Annotation

You can 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, as shown below:
public interface OrderService {
 
    @OperationTypes(
        in = "{http://acme.com/orders}createOrder",
        out = "{http://acme.com/orders}createOrderResult",
        fault = "java:com.acme.exceptions.OrderManagementException"
    )
    Element createOrder(Element order) throws OrderCreateFailureException;
 
}
In this example, the type for OrderCreateFailureException has been changed to java:com.acme.exceptions.OrderManagementException by defining a fault type on the @OperationTypes. Its type would otherwise default to java:com.acme.exceptions.OrderCreateFailureException. It could also be done 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.

20.11. Bean Services In a Java EE Web Application Container

The JEE Web Application Container can be used to deploy applications (for example, Tomcat or Jetty). This means that you do not have to use the SwitchYard Application Servers for deployment.You can use it to configure the SwitchYard WebApplicationDeployer servlet listener in your web application, and configure Weld into a servlet container.

20.12. JavaServer Faces

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 integrates 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 smooth integration between SwitchYard Bean services and a JSF-based user interface.

20.13. Indirect Service Invocation

SwitchYard services can be indirectly invoked through the SwitchYard Exchange mechanism. This reduces the coupling between JSF components and SwitchYard Service implementations. This is done by invoking a SwitchYard CDI Bean Service and the SwitchYard Exchange mechanism through a @Reference injected Service reference. This provides a client side proxy bean that handles all the SwitchYard Exchange invocation details for all the operations exposed by the service.

Note

The proxy beans for these invocations are not available (through CDI) to the JSF components. To work around this, users can create a standard named (@Named) CDI bean. It must contain a @Reference between the JSF components and the SwitchYard CDI Bean services.

20.14. Indirect Service Invocation Example

This invocation uses an OrderService example:
public interface OrderService {
 
    OrderAck submitOrder(Order order);
 
}
 
public class Order implements Serializable {
 
    private String orderId;
    private String itemId;
    private int quantity = 1;
 
    public String getOrderId() {
        return orderId;
    }
 
    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }
 
    public String getItemId() {
        return itemId;
    }
 
    public void setItemId(String itemId) {
        this.itemId = itemId;
    }
 
    public int getQuantity() {
        return quantity;
    }
 
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }
}

20.15. Indirect Service Invocation With JSF Components Example

JSF components have a more fluid interaction with the Order bean than with the OrderService:
<div id="content">
    <h1>New Order</h1>
 
    <div style="color: red">
       <h:messages id="messages" globalOnly="false" />
    </div>
 
    <h:form id="newOrder">
        <div>
            Order ID:
            <h:inputText id="orderID" value="#{order.orderId}" required="true"/>
            <br/>
            Item ID:
            <h:inputText id="itemID" value="#{order.itemId}" required="true"/>
            <br/>
            Quantity:
            <h:inputText id="quantity" value="#{order.quantity}" required="true"/>
            <p/>
            <h:commandButton id="createOrder" value="Create" action="#{order.create}"/>
        </div>
    </h:form>
 
</div>

20.16. Indirect Service Invocation With Annotations

In the example below, annotations have been added to the bean called Order to manage invocation:
@Named
@RequestScoped
public class Order implements Serializable {
 
    @Inject
    @Reference
    private OrderService orderService;
 
    private String orderId;
    private String itemId;
    private int quantity = 1;
 
    public String getOrderId() {
        return orderId;
    }
 
    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }
 
    public String getItemId() {
        return itemId;
    }
 
    public void setItemId(String itemId) {
        this.itemId = itemId;
    }
 
    public int getQuantity() {
        return quantity;
    }
 
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }
 
    public void create() {
        OrderAck serviceAck = orderService.submitOrder(this);
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(serviceAck.toString()));
    }
}
  • Annotations @Named and @RequestScoped have been added.
  • The OrderService property has a @Reference annotation. Because of this, its instance is not a reference to the actual service implementation. Instead, it is a SwitchYard Exchange proxy to that service implementation. By using @Reference injected service references, backend service implementations can be non-CDI Bean service implementations.
  • Implementing the create method invokes the OrderService reference (exchange proxy).

20.17. Core API Annotations

Table 20.2. Core API Annotations

Feature Feature's Annotations
Policy @Requires
Transformation @Transformer
Validation @Validator
Service Interface @OperationTypes
Serialization @Strategy, @Include, @Exclude

20.18. Component Annotations

Table 20.3. Component Annotations

Component Annotations
Bean @DefaultType, @Inject, @Service, @Reference, @Property
Camel @Route
Knowledge Services @Channel, @Listener, @Logger, @Manifest, @Container, @Resource, @Property
BPM @BPM, @WorkItemHandler, @StartProcess, @SignalEvent, @AbortProcessInstance
Rules @Rules, @Execute, @Insert, @FireAllRules, @FireUntilHalt

20.19. Testing Annotations

Table 20.4. Testing Annotations

Action Annotations
Testing @RunWith, @Test, @SwitchYardTestCaseConfig, @ServiceOperation, @BeforeDeploy

20.20. JBoss Rules

20.20.1. JBoss Rules

JBoss Rules is the name of the business rule engine provided as part of the Red Hat JBoss Fuse Service Works product.

20.20.2. The JBoss Rules Engine

The JBoss Rules engine is the computer program that applies rules and delivers Knowledge Representation and Reasoning (KRR) functionality to the developer.

20.20.3. Production Rules

A production rule is a two-part structure that uses first order logic to represent knowledge. It takes the following form:
when
	<conditions>
then
	<actions>

20.20.4. The Inference Engine

The inference engine is the part of the BRMS engine which matches production facts and data to rules. It performs the actions based on what it infers from the information. A production rules system's inference engine is stateful and is responsible for truth maintenance.

20.20.5. ReteOO

The Rete implementation used in JBoss Rules is called ReteOO. It is an enhanced and optimized implementation of the Rete algorithm specifically for object-oriented systems. The Rete Algorithm has now been deprecated, and PHREAK is an enhancement of Rete. This section merely describes how the Rete Algorithm functions.

20.20.6. Using JBoss Rules

To learn how to use JBoss Rules, please refer to the BRMS Development Guide.

20.21. Apache Camel

20.21.1. Apache Camel

Camel is an open source rules-based router developed by the Apache Project.

20.21.2. Using Apache Camel

To learn how to use Apache Camel, refer to the Red Hat JBoss Fuse Web Services and Routing with Camel CXF Guide.

20.21.3. Using Camel Routes Directly

You can deploy Camel routes directly in your user application, without needing to use SwitchYard. For example, you can deploy the Camel routes as a WAR file, fronted by a servlet or CXF.

20.21.4. Running Camel Examples

The Camel CXF (code first) example uses code-first to expose a web service in Camel running on JBoss EAP. It can be run using Maven.

Procedure 20.1. Task

  1. To build the example, navigate to its directory and run the following command:
    mvn clean install
  2. To run the example, deploy it in JBoss EAP by copying the camel-example-cxf-tomcat.war located in the target directory to the standalone/deployments/ folder.
    The webservice is available in http://localhost:8080/camel-example-cxf-tomcat/webservices/incident?wsdl.

20.21.5. Sample Client With Camel CXF

This is what a sample client made with Camel CXF looks like:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <ns1:reportIncident xmlns:ns1="http://incident.cxf.example.camel.apache.org/">
            <arg0>
                <details>Accounting Department</details>
                <email>johncitizen@acompany.com</email>
                <familyName>Citizen</familyName>
                <givenName>John</givenName>
                <incidentId>12345</incidentId>
                <summary>Incident</summary>
            </arg0>
        </ns1:reportIncident>
    </soap:Body>
</soap:Envelope>

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <ns1:statusIncident xmlns:ns1="http://incident.cxf.example.camel.apache.org/">
            <arg0>
                <incidentId>12345</incidentId>
            </arg0>
        </ns1:statusIncident>
    </soap:Body>
</soap:Envelope>

20.21.6. Camel Servlet Without Spring Example

Procedure 20.2. Task

  1. To build the example, navigate to the Apache Tomcat directory and enter the following command:
    mvn package
  2. To deploy the example, copy the resulting .war file into Apache Tomcat's Deploy folder.
  3. To access the example, open your browser and navigate to http://localhost:8080/camel-example-servlet-tomcat-no-spring-2.10.0