JBoss Fuse Service Works (FSW) 6.1 is the new release of the JBoss SOA Platform recently branded by Red Hat. As opposed to the previous releases, like JBoss SOA-P 5.3, which were proprietary solutions based products, FSW 6.1 is an implementation of the OASIS SCA (Service Component Architecture) Assembly specifications (https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sca-assembly). This article shows a simple practical example of using SCA with FSW 6.1 to implement simple services leveraging different technologies like Apache Camel. But first, let’s look at some basics concepts.
At the core of the SCA specifications is the Assembly Model, i.e. the XML notation to describe the components assembling into applications and to provide the framework into which extensions are plugged such that to support a wide variety of services, implementations and communication technologies. As such, SCA is an essential complement of SOA (Services Oriented Architecture) in the sense that, while SOA advocates the utilization of the enterprise services and defines their characteristics, SCA specifies what a service exactly is from a physical and an assembly point of view.
Everything in SCA is about software components. An SCA component is a configured instance of some business logic. It provides services and it may use services. An SCA service has a name and at least an interface. FSW 6.1 supports Java, WSDL and ESB interfaces for services. Any SCA component defines one or more services. The business logic of these services is provided by their implementations. FSW 6.1 supports CDI (Common Dependency Injection), Camel, BPEL (Business Process Execution Language) and Rules (JBoss Drools) implementations for the services. An SCA service may call other SCA services via service references. This connection between calling and callee services, via references, is called wire in SCA terminology. References are wired to services and so a network of components is described within a composite application. Accordingly, the composite is the basic unit of SCA assembly. The technology used to join the components together in composites is unrelated to the one in which the components are implemented. For example, a Camel based service might be connected with a caller service through HTTP, JMS or SOAP. This abstraction process is called binding in the SCA terminology. FSW 6.1 supports a long list of bindings, like HTTP, JMS, JPA, SOAP, REST, File, FTP/SFTP/FTPS, Camel, TCP/UDP, etc.
Based on the previous notions which should resume in a few sentences the SCA basics and essentials, let’s try now to implement a Hello World composite and to deploy and test it in FSW 6.1. Our Hello World project is an SCA service, having an ESB interface, a Camel implementation and a HTTP binding.
An SCA composite as a FSW project is, essentially, a maven project with a JAR packaging type and, as such, it may be developed using any development tool supporting maven. In this exercise we choose however to use JBoss Development Studio (JBDS) 7.1. SwitchYard is the name of the JBoss open-source project providing the SCA Assembly implementation and it has included as such by Red Hat in their FSW commercial release. Hence, JBDS has a SwitchYard plugin which will be used here for our example purposes. Here are the required steps:
- Create a new SwitchYard project in JBDS. The New SwithchYard Project wizard will ask you for this new project’s name. A simple naming conversion consists in using a pattern like <name>-<interface>-<implementation>-<binding> for the project name. With the risk of coming to quite long names, this pattern is self-documenting as it specifies the type of the composite service interface, implementation and binding. In our case, this name is helloworld-esb-camel-http. Click Next.
- The SwitchYard Project Configuration wizard lets you specify information like the maven group-id, the project’s target name-space the package name for the Java classes, if any, the target runtime, etc. Concerning the target runtime, this supposes that FSW 6.1 be installed locally and that you have created a runtime and an associated server in JBDS. More important, the wizard lets you select the required SwitchYard components. This means that the generated maven POM will only include dependencies for the SwitchYard components you specify at this step. For our example, select Camel Route for Implementation Support, HTTP for Gateway Bindings and HTTP Mixins for Test Mixins. Click Next and your maven POM will be generated.
- Now you might want to amend the generated POM, for example, if you use jboss-as:deploy/undeploy or exec:java plugins you need to add the following:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<executable>java</executable>
<classpathScope>test</classpathScope>
<mainClass>…</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.4.Final</version>
</plugin>
- Our service uses a Camel implementation, hence you need to create it. Go to the src/main/java, right-click on the package name that you configured in the Step 2 and create a new class. The following listing shows an example of a Camel Route:
package …;
import org.apache.camel.*;
import org.apache.camel.builder.*;
import org.switchyard.common.camel.*;
public class HelloWorldRoute extends RouteBuilder
{
@Override
public void configure() throws Exception
{
from("switchyard://HelloWorldESBComponentService")
.process(new Processor()
{
@Override
public void process(Exchange exchange) throws Exception
{
String hello = exchange.getIn().getBody(String.class);
SwitchYardMessage out = new SwitchYardMessage();
out.setBody(hello);
exchange.setOut(out);
}
})
.log("*** ${body}");
}
}
- We will look more in details later to the code above. Now, that we have the implementation class, we go back to the switchyard.xml file and, in its design tab, drag from the Palette the Camel (Java) icon, located in the Implementations tab, onto the component you created previously. In the Camel Java Route Details click on the Browse button and then select the name of the class you created in the previous step.
- Now your component is created with its associated implementation. In order to be used, you need to create a service for it. Drag the Service icon from the Core tab of the Palette onto your component. This will open the New Service wizard. Type in the service name and select the ESB radio button for the Interface Type. Now click on the Inteface link in order to define the input, output and fault types for your ESB interfaces. In our case, we chose to have a java.lang.String type as input and output an no fault type. Click Finish.
- Now you have created an SCA component having a service definition associated to it. Your component is accessible via its associated service in the containing composite. But in order to be accessible from outside the composite, another service associated to the composite itself is required. Drag the Service icon from the Core tab of the Palette to the main canvas and repeat the steps you performed at the Step 7 to define the service name and interface. Once this composite level service is created, you need to wire it to your component level service. Move your mouse onto the composite level service and different icons will be displayed around the service. Select the Wire icon, displayed as a bidirectional arrow, and drag it onto the component layer service. The wire will appear on the canvas as a solid line connecting the composite level service to the component level one.
- The idea behind the operation performed at the Step 8 was to have a composite level service to be used in order to access the component level service from outside the composite. In this respect, the SCA terminology calls this operation a service promotion. This means that our component level service is promoted such that to be accessible at the composite level, from outside the composite. Wiring your services will automatically perform the promotion.
Finally, your switchyard.xml file should look similar to the one below. Please notice that the file is not editable in the Source tab of the SwitchYard Editor in JBDS but only in the Design one, using the Palette, as we did. Should you prefer to edit it using XML, you need to use your preferred text editor but not JBDS. Caution should be observed that making mistakes while editing this file with a text editor could prevent you to open it further into JBDS.
<?xml version="1.0" encoding="UTF-8"?>
<sy:switchyard xmlns:camel="urn:switchyard-component-camel:config:1.1"
xmlns:http="urn:switchyard-component-http:config:1.1" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
xmlns:sy="urn:switchyard-config:switchyard:1.1" name="helloworld-esb-camel-hhtp"
targetNamespace="urn:com.example.switchyard:helloworld-esb-camel-hhtp:1.0">
<sca:composite name="helloworld-esb-camel-hhtp"
targetNamespace="urn:com.example.switchyard:helloworld-esb-camel-hhtp:1.0">
<sca:service name="HelloWorldESBCompositeService" promote="HelloWorld/HelloWorldESBComponentService">
<sy:interface.esb inputType="java.lang.String" outputType="java.lang.String"/>
<http:binding.http>
<http:contextPath>hello-world2</http:contextPath>
</http:binding.http>
</sca:service>
<sca:component name="HelloWorld">
<camel:implementation.camel>
<camel:java class="fr.simplex_software.switchyard.HelloWorldRoute"/>
</camel:implementation.camel>
<sca:service name="HelloWorldESBComponentService">
<sy:interface.esb inputType="java.lang.String" outputType="java.lang.String"/>
</sca:service>
</sca:component>
</sca:composite>
</sy:switchyard>
Using an editor as the SwitchYard one in JBDS avoids you having to learn the XML notations like the previous one. Here we define an SCA component named HelloWorld implemented by a Camel route defined by the HelloWorldRoute Java class. There is a component level service associated to this component. Its name is HelloWorldComponentService and its interface is of ESB type accepting a string as its input and output. The implemnation class uses a Camel route which reads the input string. Please notice that, for this purposes, the Camel endpoint is switchyard://HelloWorldESBComponentService. A Camel processor is then used to copy the Camel payload to the Camel output which will be the service output as well. This output string will be finally logged in the FSW log file. The component level service is promoted to a composite level service named HelloWorldCompositeService. This is a useful naming convention to use ComponentService and CompositeService suffixes for the services names. Please notice how the services promotion works.
Last but not least, we need a test class like the following:
package …;
import org.switchyard.component.test.mixins.http.*;
public class TestHelloWorld
{
private static final String HELLO_WORLD_URL = "http://localhost:8080/hello-world2";
public static void main(String[] args) throws Exception
{
HTTPMixIn http = new HTTPMixIn();
http.initialize();
http.sendString(HELLO_WORLD_URL, "Hello World !", HTTPMixIn.HTTP_POST);
}
}
SwitchYard comes with a test framework called Mixin. This framework comes in different flavours like CDI, HTTP, HornetQ, etc. Here since our service has an HTTP binding, we’re using the HTTP flavor for Mixin. As you may see, once instantiated and initialized, the HTTPMixIn class may be used to send HTTP request to HTTP endpoints. So, here we’re using an HTTP transport in order to send the input string to our service implemented by a Camel route.
In order to deploy our project and to test it, after having started the FSW server, use the following command:
mvn clean install jboss-as:undeploy jboss-as:deploy exec:java
The maven command above will clean the previously created files, will compile, package and install the JAR into the local maven repository, it will also undeploy the JAR from the FSW server if it is already deployed and it will deploy it again on the FSW server. Finally the test class will be executed. If everything goes well, you should see the following message in the FSW log file.
12:32:36,722 INFO [route4] (http-localhost/127.0.0.1:8080-1) *** Hello World !
The example could be downloaded from the download page of this site. Enjoy and don’t hesitate to let me know your comments.