Show Table of Contents
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
- To build the example, navigate to its directory and run the following command:
mvn clean install
- To run the example, deploy it in JBoss EAP by copying the
camel-example-cxf-tomcat.war
located in the target directory to thestandalone/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
- To build the example, navigate to the Apache Tomcat directory and enter the following command:
mvn package
- To deploy the example, copy the resulting
.war
file into Apache Tomcat'sDeploy
folder. - To access the example, open your browser and navigate to http://localhost:8080/camel-example-servlet-tomcat-no-spring-2.10.0
- To access the servlet, go to http://localhost:8080/camel-example-servlet-tomcat-no-spring-2.10.0/camel