Ok

En poursuivant votre navigation sur ce site, vous acceptez l'utilisation de cookies. Ces derniers assurent le bon fonctionnement de nos services. En savoir plus.

  • FSW 6.1 – Developing SCA Composites

    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:

     

    1. 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.
    2. 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.
    3. 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>

     

    1. 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}");
      }
    }

    1. 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.
    2. 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.
    3. 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.
    4.  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.

  • Tightening Together SOA and MDM with AIA

    Okay, as an Enterprise Software Architect, you were successfull in the process of implementation of the SOA in your organization. You built SOA services to the highest standard, you adopted all the best practices, you established design-time and run-time SOA governance, however your end users keep complaining about the quality of the data served by your services. As a matter of fact, despite all the efforts that your company has made in order to re-design and to re-implement its services, such that to achieve a very high quality of the business infrastructure, these services still deliver poor quality data. Suddenly, you realize tha your SOA infrastructure doesn’t store operational data and that you need to provide as much management and governance for your enterprise data as you provide for your enterpeise services. Enter Master Data Management (MDM).

     

    Having the right level of sponsorship from your business, you, together with other enterprise architects, create a roadmap meant to define the global strategy towards implementing a full MDM solution in your organization. This solution, based on the utilization of the Oracle MDM Suite and Oracle Data Quality familly products, is designed such that to steward, profile, match, merge and audit your enterprise data. Given the extremly etherogeneous landscape of your enterprise IT software, the business data has critical issues as the fact of being redundant in different systems like CRMs, ERPs, B2C services, etc. and not providing a centralized and unique enterprise wide view. So, one of the most critical challenges of your MDM solution is to unify your data by defining a business comon semantic and to promote this common semantic as being your enterprise master data. But while MDM subject-matter experts recruited to assist you are working hard to construct and implement the solution, you identify a new challenge : using a business common semantic as the enterprise master data requires to constantly collect and replicate data from your enterprise various systems. And since these systems are many, this seems like an onerous task and designing the right interfaces is not trivial.

     

    However, after having conducted several researches, you and your other colleagus in the enterprise architecture team, discovered that Oracle provides so-called Process Integration Packs (PIP) in its Application Integration Architecture Foundation Pack (AIA FP). These PIPs are constructed to address end-to-end integration challenges in processes like « Order to Cash », « Procure to Pay », « Record to Report » and « MDM Integration ». This PIP come out-of-the-box and their implementation and customization requires generally little effort, saving this way many work-hours. One that particularly retains your attention is the Customer MDM Integration Based Pack which aims at being a true Customer Hub for all your enterprise services and systems. This Customer Hub will offer an unified view of the Customer business object to your Siebel CRM, your Oracle e-Business Suite ERP, your Oracle BRM revenue management system, your B2C web-apps, etc.

     

    Implementing PIPs that come out-of-the-box with AIA FP is a win to win scenario because it not only accelerates the MDM rollout but, given that they are SOA based, all the enterprise systems and services are potentially beneficiaries. Moreover, by adopting Oracle AIA FP, the enterprise takes advantage of all the artifacts provided by this foundation, including the use of the Oracle Enterprise Repository (OER) to promte services visibility, re-use and policy enforcement. Also, using the JDeveloper plugins, business services, WSDls and XSDs that come out-of-the-box with Oracle AIA FP, and adopting AIA FP standards and taxonomies, the enterprise should be able to dramatically reduce costs and to mature and enforce its SOA best practicies.

     

    AIA FP features and facilities would be difficult to resume in a couple of lines as they make the object of several hundreds of pages of product documentation. This foundation provides a real development life-cycle with all the required tools, including but not limited to

     

    • Runtime artifacts like policies, composites, pre-built integrations and error handling frameworks.
    • Utilities like Business Process Analysis (BPA), Process Lifetime Workbench (PLB), AIA Service Constructor, etc.
    • AIA Refernce Architecture providing service re-usability, modularity, granularity, composability, loosing coupling, discoverability, etc.
    • AIA Conceptual Architecture providing process, activity, data and utility services.
    • Etc.

     

    But one of the most important component of the AIA FP is probably its Shared Service Library, consisting in a number of artifacts and defining the AIA Service Taxonomy. Based on this taxonomy, complex SOA solutions can be implemented using the following building blocks :

     

    • Composite Business Processes (CBP) : application agnostic processes implemented in BPMN2 using BPM Suite 11g or in BPEL using SOA Suite 11g.
    • Enterprise Business Services (EBS) : application agnostic activity or data services, exposing coarse grained business logic like CRUD operations against first-class enterprise entities like customers, sales, orders, purchases, etc. They are implemented as SOA Suite 11g Mediators.
    • Enterprise Business Flows (EBF) : application agnostic activity services responsible of delivering specific business tasks and implemented as BPEL with SOA Suite 11g.
    • Application Business Connector Services (ABCS) : data services providing fine grained business logic and connection logic. They are implemented as SOA 11g Mediators. They come in two flavors : ABCS Requesters and ABCS Providers depending on their responsibility to receive messages or to expose fine grained functionality.
    • Application Business Flows (ABF) : dedicated services to support point-to-point integrations. While usefull in scenarios where introducing several layers of abstraction might be penalisant from a performance poit of view, this kind of pattern is to be used carrefuly.

     

    All these service patterns are exchanging abstarctions like Enterprise Business Messages (EBM) and Enterprise Business Objects (EBO) defined as WSDLs and XSDs and comming out-of-the-box with AIA FP. All the first-class enterprise entities are present and, consequently, they don’t have to be any more invented by every application, system or service as it is so often the case.

     

    Download the stuff, try and enjoy !

  • Using Camel Producer Template with FSW 6

    Apache Camel provides a powerfull unit testing framework that developpers use since years and which name is Camel Test Kit. This unit testing framework consists in a number of classes on top of JUnit that facilitate Camel routes unit testing. Among these classes, one of the developer’s prefered is ProducerTemplate which represents a very convenient way to send Camel messages to Camel routes, for testing purposes. But when it comes to deploy Camel routes into the new Fuse Service Works application server, the developer skeptically discovers that, while SwitchYard comes with a very strong unit testing frameworks supporting HTTP, CDI, HornetQ/JMS and Smooks, the old good Camel Test Kit is not supported. At least this is what the Red Hat technical support will advise to the developers submiting tickets in order to complain that statements like :

     

    @Test public void testStartService() throws Exception
    {
      template.sendBody ("switchyard://HelloWorldComponentService", "Hello World !");
    }

     

    raise the following exception :

     

    java.lang.ClassCastException: org.apache.camel.impl.DefaultCamelContext cannot be cast to org.switchyard.common.camel.SwitchYardCamelContext at …

     

    What happens here is that the Camel ProducerTemplate uses a CamelDefaultContext while producing message to SwitchYard endpoints obviously requires a SwitchYardCamelContext instance. And the SwitchYardCamelContext cannot be casted to a CamelDefaultContext instance. How then is one supposed to use the Camel unit test framework with SwitchYard ?

     

    The Red Hat support will tell you that this is simply not supported and that, if you want to test Camel routes using HTTP or JMS endpoints, then you may do it using SwitchYard MixIn like explained here  https://docs.jboss.org/author/display/SWITCHYARD/Testing, otherwise you need to use real test clients like in integration/functional testing. This is what happened to me and, after a several days debate at the end of which they simply closed my ticket without my agreement, I decided to submit the same case to the SwitchYard community forum. And guess what ? One hour later, thanks to Keith Baboo, I got my solution. Given a SCA service like the following :

     

    <sca:service name="Hello/HelloService" promote="Hello/HelloService">  

      <sca:interface.java interface="org.jboss.example.ExampleService"/>  

      <camel_1:binding.uri name="camel1" configURI="direct://HelloService"/>  

    </sca:service>

     

    One may test it like this :

     

    @RunWith(SwitchYardRunner.class)
    @SwitchYardTestCaseConfig (config = SwitchYardTestCaseConfig.SWITCHYARD_XML, mixins = { CDIMixIn.class }) 
    public class ExampleTest 
    {
      private SwitchYardTestKit testKit;  
      @Test  
      public void testIntake() throws Exception 
      {  
        ServiceDomain domain = testKit.getServiceDomain();  
        CamelContext ctx = (CamelContext)domain.getProperty("CamelContextProperty");  
        ProducerTemplate producer = ctx.createProducerTemplate();  
        producer.sendBody("direct://HelloService", "Message content");  
      }  
    }  

     

    The way we instantiate the Camel ProducerTemplate here is very different compared to the way we do it in plain vanilla Camel and, since this is not documented, the developer would probably have difficulties to guess it. Hence, I wanted to document it here, waiting that the official documentation be updated and hoping that the Red Hat FSW technical support will also read it. The morality is that, sometimes, it is not worth paying expansive technical support because free users forum might be more proficient and, in any case, more polite and respectfull.

     

    Thanks Keith !