Using the event API to publish an event to the Event Delivery Network (EDN) – the Spring way

January 12, 2010 gschmutz Leave a comment

The Event Delivery Network (EDN) in Oracle SOA Suite 11g provides a declarative way to use a publish/subscribe model to generate and consume business events without worrying about the underlying message infrastructure. Events can be published / subscribed from a variety of programming environments such as Java, PL/SQL, SOA Composites, and ADF-BC applications

In his blog Clemens showed how the Event API can be used to publish an event programmatically to the Event Delivery Network (EDN). I took the sample code Clemens provided and did some refactoring to make it more “Spring like”.

My idea is to use some of the features of the Spring Framework to simplify the publishing of Business Events to EDN from Java, without worrying about the details of the Java event API. The following features are of interest:

    The goal is to make publishing an Business Event to EDN from Java as simple as that:
// create a new customer
Customer cust = new Customer();
cust.setId(1);
cust.setFirstName("Guido");
cust.setLastName("Schmutz");

Address adr = new Address();
adr.setStreet("Papiermuehlestrasse 73");
adr.setZipCode(3014);
adr.setCity("Bern");
adr.setCountry("Switzerland");
cust.setAddress(adr);

// create a new customer event, passing the customer object as the payload
NewCustomerEvent event = new NewCustomerEvent(this, cust);

// publish the event through the Spring Event Handling mechanism
context.publishEvent(event);

    We just use simple Java objects (POJOs) to create an event and its payload and then publish it through the Spring application context as a standard Spring event.
    Sounds interesting to you? Yes, but what is needed behind the scene to make this work?
    Before we start to dig into the Java implementation, let’s first create the Business Event inside the Oracle SOA Suite 11g and implement a composite subscribing to this event.

    First, you need to define the data-shape of the event. This is done conventionally through the usage of XML Schema (File customer.xsd).

    <?xml version="1.0" encoding="windows-1252" ?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:cus="http://www.trivadis.com/cdm/customer"
                targetNamespace="http://www.trivadis.com/cdm/customer"
                elementFormDefault="qualified">
      <xsd:element name="customer">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="id" type="xsd:integer"/>
            <xsd:element name="firstName" type="xsd:string"/>
            <xsd:element name="lastName" type="xsd:string"/>
            <xsd:element name="address">
              <xsd:complexType>
                <xsd:sequence>
                  <xsd:element name="street" type="xsd:string"/>
                  <xsd:element name="city" type="xsd:string"/>
                  <xsd:element name="zipCode" type="xsd:integer"/>
                  <xsd:element name="country" type="xsd:string"/>
                </xsd:sequence>
              </xsd:complexType>
            </xsd:element>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:schema>
    

     

    After that the Business Event can be defined using the Event Definition Language (EDL).

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <definitions xmlns="http://schemas.oracle.com/events/edl"
                 targetNamespace="http://www.trivadis.com/events/edl/CustomerEventDefinition">
      <schema-import namespace="http://www.trivadis.com/cdm/customer"
                     location="xsd/customer.xsd"/>
      <event-definition name="NewCustomer">
        <content xmlns:ns0="http://www.trivadis.com/cdm/customer"
                 element="ns0:customer"/>
      </event-definition>
    </definitions>
    

     

    At last we can publish/subscribe to that event from a SOA Suite composite. For our example, I have defined a simple Mediator component listening on the NewCustomer event, which is then sent to a BPEL component for processing.

    tmp

       

      After deploying this SCA composite to the server, we are ready on the SOA Suite side to consume NewCustomer events. Now let’s implement the producer side in Java.

      Defining the Event in Java


      We start with the payload (the information) of the event. As shown in the Java snippet above, the goal is to pass the event payload as a normal Java object, without having to worry about the XML representation necessary for publishing the event through the API.

      The act of converting an XML document to/from an object is called Object/XML Mapping or O/X Mapping for short. There are quite a lot of Java frameworks supporting this Object/XML Mapping, like JAXB, Castor, XMLBean, JiBX or XStream. For this post I will use the JiBX framework, as it offers a flexible approach when starting with an XML Schema.

      In my previous post Using the new Object/XML Mapping Support of Spring 3.0 with JiBX and Maven I have presented how to work with JiBX from Spring using Maven as the build tool. The same approach I will use here as well.

      With the XML Schema customer.xsd used for the BusinessEvent definition above as input, the JiBX framework generates the two Java classes Customer and Address defining the payload of our event in Java.

      public class Customer
      {
          private int id;
          private String firstName;
          private String lastName;
          private Address address;
      
          // public getter and setter method not shown
      }
      
      public class Address
      {
          private String street;
          private String city;
          private int zipCode;
          private String country;
      
          // public getter and setter method not shown
      }
      

      Next let’s define the NewCustomerEvent class, which defines the event itself and acts as a wrapper for the event payload.

      public class NewCustomerEvent extends AbstractApplicationEventForEDN {
      
      	private Customer customer;
      	private final static String NAMESPACE = "http://www.trivadis.com/events/edl/CustomerEventDefinition";
      	private final static String NAME = "NewCustomer";
      
      	public NewCustomerEvent(Object source, Customer customer)
                                throws XmlMappingException, ParserConfigurationException, IOException {
      		super(source, NAMESPACE, NAME, customer);
      	}
      }
      

      The payload, customer in the case here, can be passed in the 2nd argument of the constructor. The other properties necessary for a Business Event in EDN (namespace and name) are defined as constant values, passed to the constructor of the parent class.
      NewCustomerEvent inherits from AbstractApplicationEventForEDN, the base class for all events to be published to EDN. It defines the common properties of an Business Event, like namespace, local name, content, event id and conversation id.

      public abstract class AbstractApplicationEventForEDN extends ApplicationEvent {
      
      	private String namespace;
      	private String name;
      	private Object content;
      	private Object eventId;
      	private Object conversationId;
      
      	public AbstractApplicationEventForEDN(Object source, String namespace, String name, Object content) throws ParserConfigurationException, XmlMappingException, IOException {
      		super(source);
      
      		this.namespace = namespace;
      		this.name = name;
      		this.content = content;
      		this.eventId = UUID.randomUUID();
      		this.conversationId = UUID.randomUUID();
      	}
      
      	// setter method not shown
      }
      

      AbstractApplicationEventForEDN itself inherits from ApplicationEvent, a class provided by the Spring event handling mechanism. This means that such a Java Business Event is automatically a Spring ApplicationEvent so that it can be published in the Spring event handling mechanism like any other Spring event.

      So far we have a Java representation of the Business Event with its payload and we are able to publish these events through Spring.
      Next we will see how we can connect to EDN and publish the Business Events in a Spring way.

      Creating a FactoryBean to abstract away the creation of a BusinessEventConnection

      First let’s start with the link from Java to the Event Delivery Network. To talk to EDN, we need an instance of oracle.fabric.blocks.event.BusinessEventConnection. To create such an instance, the EDN Java API provides a factory interface named BusinessEventConnectionFactory together with an implementation through SAQRemoteBusinessEventConnectionFactory.
      I use such a FactoryBean to wrap the creation of a BusinessEventConnection.

      public class BusinessEventConnectionFactoryBean implements FactoryBean, InitializingBean {
      
      	DataSource dataSource;
      	BusinessEventConnectionFactory businessEventConnectionFactory;
      
      	public void setDataSource(DataSource dataSource) {
      		this.dataSource = dataSource;
      	}
      
      	public void afterPropertiesSet() throws Exception {
              businessEventConnectionFactory =
                  new SAQRemoteBusinessEventConnectionFactory(
                      dataSource, dataSource, null);
      	}
      
      	public Object getObject() throws Exception {
      		return businessEventConnectionFactory.createBusinessEventConnection();
      	}
      
      	public Class getObjectType() {
      		return BusinessEventConnection.class;
      	}
      
      	public boolean isSingleton() {
      		return false;
      	}
      }
      
      BusinessEventConnectionFactoryBean  declares a dependency to a DataSource, which is necessary for creating a BusinessEventConnectionFactory. This means that the DataSource needs to be injected through Spring, so a bean configuration is necessary in the Spring context XML definition
    <context:property-placeholder location="classpath:jdbc.properties"/>
    
    <bean id="businessEventConnection" class="com.trivadis.soa.BusinessEventConnectionFactoryBean">
    	<property name="dataSource" ref="dataSource"/>
    </bean>
    
    <bean id="dataSource" class="oracle.jdbc.xa.client.OracleXADataSource">
    	<property name="user" value="${jdbc.username}"/>
    	<property name="password" value="${jdbc.password}"/>
    	<property name="URL" value="${jdbc.url}"/>
    	<property name="implicitCachingEnabled" value="false"/>
    </bean>
    

     

    The DB connection properties can be externalized into a properties file (jdbc.properties) by using the Spring context:property-placeholder element.

    jdbc.url=jdbc:oracle:thin:@soavm11.trivadis.com:1521:repoas
    jdbc.username=dev_soainfra
    jdbc.password=oracle
    

     

    When running in an Java EE application server, the DataSource can easily be retrieved via JNDI by switching the bean configuration as follows

    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="jdbc/MyDataSource"/>
    </bean>
    

     

    With the BusinessEventConnection bean set up, let’s see how the Java event classes (i.e. NewCustomerEvent) can be published to EDN.

       

      Publishing the Event to the Event Delivery Network (EDN)

    According to Spring Best Practices we first define an interface which the event publisher implementation will need to implement. The publishEvent() method declares a parameter of type AbstractApplicationEventForEDN, so any child class extending it will be accepted and published.

    public interface BusinessEventPublisher {
    
    	public abstract void publishEvent(AbstractApplicationEventForEDN applicationEvent)
    			throws XmlMappingException, IOException;
    
    }
    

     

    My implementation of the BusinessEventPublisher can be seen below with the BusinessEventPublisherEDN class. The publishEvent() method first marshals the payload (content property) of the AbstractApplicationEventForEDN into an XML document using the Spring O/X Mapping support. The Marshaller implementation to be used is injected by Spring at initialization time (for more information see my other blog post).

    After that an instance of oracle.fabric.common.BusinessEvent is created and published via the BusinessEventConnection, which is also injected by Spring (i.e. the bean declared before).

    public class BusinessEventPublisherEDN implements BusinessEventPublisher {
    
    	private BusinessEventConnection conn;
    	private Marshaller marshaller;
    
    	public void setBusinessEventConnection(BusinessEventConnection conn) {
    		this.conn = conn;
    	}
    
    	public void setMarshaller(Marshaller marshaller) {
    		this.marshaller = marshaller;
    	}
    
    	public void publishEvent(AbstractApplicationEventForEDN applicationEvent) throws XmlMappingException, IOException {
    		DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
    				.newInstance();
    		DocumentBuilder builder = null;
    		try {
    			builder = documentBuilderFactory.newDocumentBuilder();
    		} catch (ParserConfigurationException e) {
    			e.printStackTrace();
    		}
    		Document document = builder.newDocument();
    		DOMResult result = new DOMResult(document);
    
    		marshaller.marshal(applicationEvent.getContent(), result);
    		Element payload = document.getDocumentElement();
    
    		BusinessEvent event = buildEvent(applicationEvent, payload);
    		conn.publishEvent(event, 3);
    	}
    
    	private BusinessEvent buildEvent(
    			AbstractApplicationEventForEDN applicationEvent, Element payload) {
    		BusinessEventBuilder beb = BusinessEventBuilder.newInstance();
    		QName eventName = new QName(applicationEvent.getNamespace(), applicationEvent
    				.getName());
    		beb.setEventName(eventName);
    		beb.setBody(payload);
    		beb.setProperty(BusinessEvent.EVENT_ID, applicationEvent.getEventId());
    		beb.setProperty(BusinessEvent.PROPERTY_CONVERSATION_ID, applicationEvent
    				.getConversationId());
    		beb.setProperty(BusinessEvent.PRIORITY, 1);
    		BusinessEvent be = beb.createEvent();
    		return be;
    	}
    }
    

     

    I could use this EventPublisher implementation directly to publish events by injecting it all the event producer beans.

    But my idea is to use the Spring event handling mechanism as the base event transport inside the Spring application and to have one common/central place where all Spring event of type AbstractApplicationEventForEDN are forwarded to Oracle EDN.

    For that I have implemented the Spring ApplicationListener using the AbstractApplicationEventForEDN base class as the type parameter. This has the effect that the listener does only subscribe to subclasses of AbstractApplicationEventForEDN, i.e. all my Java EDN events. The listener uses the injected BusinessEventPublisher instance to publish the events to EDN. This listener implementation basically acts as a bridge from the Spring event handling mechanism to the Event Delivery Network.

    public class ApplicationEventListenerEDN implements ApplicationListener<AbstractApplicationEventForEDN> {
    
    	private BusinessEventPublisher businessEventPublisher;
    
    	public void setBusinessEventPublisher(
    			BusinessEventPublisher businessEventPublisher) {
    		this.businessEventPublisher = businessEventPublisher;
    	}
    
    	public void onApplicationEvent(AbstractApplicationEventForEDN applicationEvent) {
    		try {
    			businessEventPublisher.publishEvent(applicationEvent);
    		} catch (XmlMappingException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    }
    

    The configuration of this classes as Spring beans and the dependencies between them is shown here:

    <bean id="applicationEventListener" class="com.trivadis.soa.ApplicationEventListenerEDN">
    	<property name="businessEventPublisher" ref="businessEventPublisher"/>
    </bean>
    
    <bean id="businessEventPublisher" class="com.trivadis.soa.BusinessEventPublisherEDN">
    	<property name="businessEventConnection" ref="businessEventConnection"/>
    	<property name="marshaller" ref="marshaller"/>
    </bean>
    
    <oxm:jibx-marshaller id="marshaller" target-class="com.trivadis.cdm.product.Product"/>
    

     

    That’s it! The Java event producer implementation is ready to be tested.

       

      Testing the publishing of an Event


      I have used the Spring Integration Testing support to test the event publishing. The test class PublisherTest implements the Spring ApplicationContextAware interface. This will force the class to implement the setApplicationContext() method, so that the Spring ApplicationContext will be injected at runtime. This ApplicationContext is necessary to publish an event to the Spring event handling mechanism.

      @RunWith(SpringJUnit4ClassRunner.class)
      //ApplicationContext will be loaded from "classpath:/com/trivadis/soa/PublisherTest-context.xml"
      @ContextConfiguration
      public class PublisherTest implements ApplicationContextAware  {
      
      	private ApplicationContext context;
      
      	public void setApplicationContext(ApplicationContext context) throws BeansException {
      		this.context = context;
      	}
      
      	@Test
      	public void testPublishNewCustomer() throws Exception {
      		Customer cust = new Customer();
      		cust.setId(1);
      		cust.setFirstName("Guido");
      		cust.setLastName("Schmutz");
      		Address adr = new Address();
      		adr.setStreet("Papiermuehlestrasse 73");
      		adr.setZipCode(3014);
      		adr.setCity("Bern");
      		adr.setCountry("Switzerland");
      		cust.setAddress(adr);
      
      		NewCustomerEvent event = new NewCustomerEvent(this, cust);
      		context.publishEvent(event);
      	}
      }
      

      The test method uses the code shown at the beginning of this post. So the goal of simplifying the event publishing to EDN from Java has been achieved!

      The Enterprise Manager console proves that the event publishing to EDN works!

      temp[7]

    Above the Flow Trace overview and below the details for the EventConsumer is shown. 

        temp[9]

         

        Source code

         

        The code shown in this post is only a proof-of-concept and before using it in a real project, some things like error handling need to be improved. All the source code can be downloaded from here.

        In addition to the NewCustomerEvent shown above, the downloadable version implements two other events, UpdateCustomerEvent and NewProductEvent.

      The download contains he following projects:

        Project IDE/Build Description
        spring-edn Eclipse/Maven all reusable classes described in my post
        spring-edn-sample Eclipse/Maven simulates a Spring application with the Business Event class definition. Depends on the spring-edn project and references these classes when setting up the Spring context at startup time.
        maven-local-repo Maven Handles JAR’s not available in public Maven Repositories but necessary for the build of the two projects. There is a script which will install these JARs into the local repository on your machine. Except of the jms.jar, the JAR files are not provided here (because I don’t know if I would be allowed to), they are copied from your own local installation when running the script.
        EDNProject JDeveloper SOA Suite 11g project defining the Business Event for the Event Delivery Network (EDN) and the composite subscribing to the event on EDN.
        In order for the JiBX customization to work when building the spring-edn-sample project, a patched version of the JiBX maven plugin (1.2.1.1a) is necessary, downloadable from here. For more information see my previous post. For the deployment of the projects, follow these steps:
      1. deploy the EDNProject to a SOA Suite 11g instance.
      2. install the missing JAR’s into your local maven repository by running maven-local-repo/install-jars.bat. Don’t forget to change the environment variable to point to your local installation of FMW
      3. install the necessary artifacts to your local maven repository
      4. create the spring-edn project using mvn install
      5. create the spring-edn-sample project using mvn install.

      Now you can test the installation by running the unit test class as shown above! Hope your are successful!

      Using the new Object/XML Mapping Support of Spring 3.0 with JiBX and Maven

      January 6, 2010 gschmutz 1 comment

      The Object to XML mapping functionality (OXM) has been moved from Spring Web Services project to the core Spring Framework with version 3.0 of Spring.

      Object/XML Mapping, or O/X mapping for short, is the act of converting an XML document to and from an object. This conversion process is also known as XML Marshalling, XML Serialization or Data Binding. A marshaller serializes an object to XML, and an unmarshaller deserializes XML stream to an object.

      Similar to the Object/Relational support, the Spring O/X mapping support does not implement an O/X mapping. It just offers a consistent abstraction for the most popular O/X frameworks available for Java. By that it allows for easily switching from one O/X mapping framework to another. It currently supports JAXB, Castor, XMLBean, JiBX and XStream.

      I have used the JAXB abstraction together with Spring Web Services before. So for this blog post I have decided to test the O/X support together with JiBX.

      JiBX is a very flexible framework for O/X mapping

      • allowing you to start from existing Java code and generate an XML schema
      • or start from an XML schema and generate Java code
      • or bridge existing code to a schema that represents the same data.

      Setting up Maven and JiBX to generate the source code

       

      For this test, let’s start with the XML schema and generate the Java code from there, which matches the contract-first approach in a SOA.

      <?xml version="1.0" encoding="windows-1252" ?>
      <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                  xmlns:cus="http://www.trivadis.com/cdm/customer"
                  targetNamespace="http://www.trivadis.com/cdm/customer"
                  elementFormDefault="qualified">
        <xsd:element name="customer" type="cus:CustomerType"/>
        <xsd:complexType name="CustomerType">
          <xsd:sequence>
            <xsd:element name="id" type="xsd:integer"/>
            <xsd:element name="firstName" type="xsd:string"/>
            <xsd:element name="lastName" type="xsd:string"/>
            <xsd:element name="address" type="cus:AddressType"/>
          </xsd:sequence>
        </xsd:complexType>
        <xsd:complexType name="AddressType">
          <xsd:sequence>
            <xsd:element name="street" type="xsd:string"/>
            <xsd:element name="city" type="xsd:string"/>
            <xsd:element name="zipCode" type="xsd:integer"/>
            <xsd:element name="country" type="xsd:string"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:schema>
      

       

      Starting from a schema and generating Java code and binding definitions is easy with JiBX. The CodeGen tool allows to use both automatic and customized generation for the XML schemas. CodeGen can be used directly from Java, from the Command Line, from an Ant build and there is also a Maven 2  Plugin for JiBX.

      Personally I favor Maven over Ant, so let’s use Maven.

      The first thing we have to do is add the JiBX Maven 2 Plugin to the project POM.

      <plugin>
      	<groupId>org.jibx</groupId>
      	<artifactId>maven-jibx-plugin</artifactId>
      	<version>1.2.1.1</version>
      	<executions>
      		<execution>
      			<id>generate-java-code-from-schema</id>
      			<goals>
      				<goal>schema-codegen</goal>
      			</goals>
      			<configuration>
      				<directory>src/main/xsd</directory>
      				<includes>
      					<include>customer.xsd</include>
      				</includes>
      			</configuration>
      		</execution>
      		<execution>
      			<id>compile-binding</id>
      			<goals>
      				<goal>bind</goal>
      			</goals>
      			<configuration>
      				<directory>target/generated-sources</directory>
      				<load>true</load>
      				<validate>true</validate>
      				<verify>true</verify>
      			</configuration>
      		</execution>
      	</executions>
      </plugin>
      

       

      The POM also needs to include jibx-run and optionally jibx-extras in its dependencies

      <dependency>
      	<groupId>org.jibx</groupId>
      	<artifactId>jibx-run</artifactId>
      	<version>1.2.1</version>
      </dependency>
      <dependency>
      	<groupId>org.jibx</groupId>
      	<artifactId>jibx-extras</artifactId>
      	<version>1.2.1</version>
      </dependency>
      

       

      Now with customer.xsd under src/main/xsd we can generate the sources by running mvn generate-sources.

      tmp

       

      We can see from the output that a CustomerType and AddressType class has been generated. Here is the source code of the generated CustomerType class

      package com.trivadis.cdm.customer;
      
      import com.trivadis.cdm.customer.AddressType;
      import java.math.BigInteger;
      
      /**
       * Schema fragment(s) for this class:
       * <pre>
       * &lt;xs:complexType xmlns:ns="http://www.trivadis.com/cdm/customer" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="CustomerType">
       *   &lt;xs:sequence>
       *     &lt;xs:element type="xs:integer" name="id"/>
       *     &lt;xs:element type="xs:string" name="firstName"/>
       *     &lt;xs:element type="xs:string" name="lastName"/>
       *     &lt;xs:element type="ns:AddressType" name="address"/>
       *   &lt;/xs:sequence>
       * &lt;/xs:complexType>
       * </pre>
       */
      public class CustomerType
      {
          private BigInteger id;
          private String firstName;
          private String lastName;
          private AddressType address;
      
          /**
           * Get the 'id' element value.
           *
           * @return value
           */
          public BigInteger getId() {
              return id;
          }
      
          /**
           * Set the 'id' element value.
           *
           * @param id
           */
          public void setId(BigInteger id) {
              this.id = id;
          }
      
          /**
           * Get the 'firstName' element value.
           *
           * @return value
           */
          public String getFirstName() {
              return firstName;
          }
      
          /**
           * Set the 'firstName' element value.
           *
           * @param firstName
           */
          public void setFirstName(String firstName) {
              this.firstName = firstName;
          }
      
          /**
           * Get the 'lastName' element value.
           *
           * @return value
           */
          public String getLastName() {
              return lastName;
          }
      
          /**
           * Set the 'lastName' element value.
           *
           * @param lastName
           */
          public void setLastName(String lastName) {
              this.lastName = lastName;
          }
      
          /**
           * Get the 'address' element value.
           *
           * @return value
           */
          public AddressType getAddress() {
              return address;
          }
      
          /**
           * Set the 'address' element value.
           *
           * @param address
           */
          public void setAddress(AddressType address) {
              this.address = address;
          }
      }
      

       

      We can see that a POJO has been generated with a reference to another POJO, the AddressType class. This exactly represents the structure of the XML schema. The name of the classes are derived from the Complex Types and the Java data types used are derived from the XML types. Because we have used xs:integer for the id, a Java BigInteger is generated.

      If you are not happy with this default generation, then a lot of things can be customized with JiBX CodeGen!

      So let’s say that we would like to remove the suffix “Type” from the class names, so the generated classes are named Customer and Address and that we like to use a Java Integer instead of the BigInteger.

      Customizations are normally supplied to JiBX CodeGen in the form of an XML document, although certain customizations can alternatively be set via command line parameters. Here is the XML needed for the customizations mentioned before.

      <schema-set prefer-inline="true" generate-all="true"
      	xmlns:xs="http://www.w3.org/2001/XMLSchema" type-substitutions="xs:integer xs:int xs:decimal xs:float">
      	<name-converter strip-suffixes="Type AttributeGroup Group Attributes" />
      </schema-set>
      

       

      It specifies some type substitutions as well as suffixes to strip away from names through a name converter. If the suffix stripping is too general, then a more precise way by specifying the mapping from a complex type to the class name can be used:

      <schema-set prefer-inline="true" generate-all="true"
      	xmlns:xs="http://www.w3.org/2001/XMLSchema" type-substitutions="xs:integer xs:int xs:decimal xs:float">
      	<name-converter strip-suffixes="Type AttributeGroup Group Attributes" />
      	<schema name="customer.xsd">
      		<complexType name="CustomerT" class-name="Customer" />
      		<complexType name="AddressT" class-name="Address" />
      	</schema>
      </schema-set>
      

       

      In order for Maven to use the customization, we need to change the configuration of the JiBX plugin in the POM and add the <customizations> element with the reference to the customization file.

       

      <configuration>
      	<directory>src/main/xsd</directory>
      	<customizations>
      		<customization>src/main/jibx/customization.xml</customization>
      	</customizations>
      

       

      With that in place we can again run mvn clean generate-sources and we should now get a Customer and an Address class.

      Unfortunately the currently available version 1.2.1.1 of the JiBX Maven Plugin does not support the <customizations> element, even though it’s documented. The following error message will be produced: “Command line options must precede all other arguments: error on ‘-c’”. This is a known bug (JIBX-331) with a patch available but not yet applied!

      Thanks to open source, I’ve just got the source code from the repository and applied the patch myself. You can download the patched version 1.2.1.1a from here. Just install it in your local maven repository by running mvn install from the project root.

      Before running mvn clean generate-sources again, you need to switch the version for the JiBX plugin in the project POM from 1.2.1.1 to 1.2.1.1a

      <plugin>
      	<groupId>org.jibx</groupId>
      	<artifactId>maven-jibx-plugin</artifactId>
      	<version>1.2.1.1a</version>
      

       

      Finally a Customer and Address class is generated and available to be used!

       

      Combine the JiBX framework with Spring to marshal from Java objects to XML

      To show the O/X mapping of Spring in Action, I just implemented a simple JUnit test class with one method showing the marshalling and unmarshalling from/to a Customer instance.

      Spring abstracts all marshalling operations behind the org.springframework.oxm.Marshaller interface and all unmarshalling operations behind the org.springframework.oxm.Unmarshaller interface.

      For each supported O/X mapping framework there is an implementation of theses two interfaces. In most cases, one class implements both interfaces. For the JiBX framework this is the org.springframework.oxm.jibx.JibxMarshaller class.

      To simplify configuration, Spring also supports XML Schema-based configuration by the OXM namespace. To make the OXM tags available, the appropriate schema has to be referenced first in the preamble of the XML configuration file. Here is the Spring configuration for the JUnit test class.

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:oxm="http://www.springframework.org/schema/oxm"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
      
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      
      http://www.springframework.org/schema/oxm
      
      http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">
      
      	<oxm:jibx-marshaller id="marshaller" target-class="com.trivadis.cdm.customer.Customer"/>
      
      </beans>
      

       

      When using the XML Schema-bases configuration, adding the marshaller implementation is a simple one-liner.

      Here is the source code of the JUnit test class using the Spring TestContext framework.

      @RunWith(SpringJUnit4ClassRunner.class)
      //ApplicationContext will be loaded from "classpath:/com/trivadis/soa/PublisherTest-context.xml"
      @ContextConfiguration
      public class MarshallingTest {
      
      	@Autowired
      	private Marshaller marshaller;
      	@Autowired
      	private Unmarshaller unmarshaller;
      
      	private static final String FILE_NAME = "C:/temp/customer.xml";
      
      	@Test
      	public void testMarshalUnmarshalCustomer() throws Exception {
      		Customer cust = null;
      		Customer custRead = null;
      
      		cust = new Customer();
      		cust.setId(1);
      		cust.setFirstName("Guido");
      		cust.setLastName("Schmutz");
      
      		Address adr = new Address();
      		adr.setStreet("Papiermuehlestrasse 73");
      		adr.setZipCode(3014);
      		adr.setCity("Bern");
      		adr.setCountry("Switzerland");
      
      		cust.setAddress(adr);
      
      		FileOutputStream os = null;
              try {
                  os = new FileOutputStream(FILE_NAME);
                  marshaller.marshal(cust, new StreamResult(os));
              } finally {
                  if (os != null) {
                      os.close();
                  }
              }
      
              FileInputStream is = null;
              try {
                  is = new FileInputStream(FILE_NAME);
                  custRead = (Customer) this.unmarshaller.unmarshal(new StreamSource(is));
              } finally {
                  if (is != null) {
                      is.close();
                  }
              }
      
              Assert.assertEquals(cust.getId(), custRead.getId());
              Assert.assertEquals(cust.getFirstName(), custRead.getFirstName());
              Assert.assertEquals(cust.getLastName(), custRead.getLastName());
              Assert.assertEquals(cust.getAddress().getStreet(), custRead.getAddress().getStreet());
              Assert.assertEquals(cust.getAddress().getZipCode(), custRead.getAddress().getZipCode());
              Assert.assertEquals(cust.getAddress().getCity(), custRead.getAddress().getCity());
              Assert.assertEquals(cust.getAddress().getCountry(), custRead.getAddress().getCountry());
      	}
      }
      

      The JUnit test class defines a dependency on the Marshaller as well as the Unmarshaller. Using @Autowired, the instance defined in the Spring configuration is automatically injected when running the test. The only test method creates an instance of Customer, marshals it to XML and stores it in a file. Then this file is read, unmarshalled from XML to a new Customer instance and compared with the original one.

      Before the test can be run, the project needs to be built by running mvn package.  This will also run the JiBX binding compiler which will enhance the Java byte code of the generated classes, i.e. Customer and Address, with the binding information necessary at runtime.

       

      The example project can be downloaded from here.

      The patched version (1.2.1.1a) of the Maven 2 JiBX Plugin project can be downloaded from here.

      Solving “javax.naming.NameNotFoundException: Unable to resolve ‘jdbc.SOAAppUserDataSource’ “ with Oracle SOA Suite 11g Adapter Services

      January 1, 2010 gschmutz 1 comment

      I ran into this rather “stupid user error” a couple of times already. It’s very easy to solve, however it’s also very easy to do it wrong when configuring Oracle SOA Suite 11g Adapter services through the WebLogic Console.

      I hope this blog entry will help new users when running into this problem:

      You get the following error in the SOA Server Log when testing your Adapter service:

      Exception occured when binding was invoked.
      Exception occured during invocation of JCA binding: “JCA Binding execute of Reference operation ‘insert’ failed due to: Could not create/access the TopLink Session.
      This session is used to connect to the datastore.
      Caused by Exception [TOPLINK-7060] (Oracle TopLink – 11g Release 1 (11.1.1.2.0) (Build 091016)): oracle.toplink.exceptions.ValidationException
      Exception Description: Cannot acquire data source [jdbc/SOAAppUserDataSource].
      Internal Exception: javax.naming.NameNotFoundException: Unable to resolve ‘jdbc.SOAAppUserDataSource’. Resolved ‘jdbc’; remaining name ‘SOAAppUserDataSource’.

      The invoked JCA adapter raised a resource exception.

       

      The setup of the Adapter Connection Factory configuration

      tmp

      as well as the corresponding DataSource (i.e. jdbc/SoaAppUserDataSource) seems to be correct at first sight.

      tmp[13] 

      But you might have forgotten to select the server, on which the JDBC data source should be deployed when adding the DataSource in the first place. This is possible when clicking the Finish button too early, before the last step which would ask to select a target server!

      The missing target information for the SoaAppUserDataSource is clearly shown in the summary page of the JDBC Data Sources.

      tmp[9]

      To fix that, just edit the Data Source, click on the Targets tab and select the servers or cluster it should be deployed on (i.e. soa_server1 in my case):

      tmp[11]

      After that the error should disappear!

      I think it would be good to get an error/warning on the console when trying to add a DataSource without selecting a target server!

      Using SnagIt Screen Capture Plug-In for Windows Live Writer

      December 27, 2009 gschmutz 1 comment

      Screen captures are important when blogging and having an easy way to capture images from the screen and embedding them into a blog entry is a key feature. SnagIt from Techsmith Corporation is a popular and very usable utility for taking such snapshots of screens.

      When using Windows Live Writer blogging client software there are different plug-ins which integrates SnagIt with Live Writer. I first installed various versions from the “official” Plug-in website, but they all did not work for me and the version of SnagIt I have installed on my machine (SnagIt 8.0.1). After some Google searches I have found this plug-in which works for me!

      Posting Source Code with Microsoft Live Writer and WordPress

      December 27, 2009 gschmutz 1 comment

      Today I searched for a solution to post source code using Microsoft Live Writer to my blog hosted on WordPress.com.

      WordPress itself has an integrated Syntax Highlighter supporting most popular languages. Details of how to use it can be found here.

      But how do you use the WordPress Syntax Highlighter when using Microsoft’s Live Writer (which I really find a good tool for offline writing) for posting? There are syntax highlighting Plug-ins available for Live Writer, but they are all not compatible with the WordPress way of syntax highlighting. After doing some Google searches, I’ve found a special Live Writer Plug-in supporting WordPress written by Rich Hewlett. It can be downloaded here.

      After that inserting nicely formatted source code is just a matter of a few mouse clicks:

       public static BusinessEvent buildEvent(String input)
              throws Exception
          {
              QName eventName =
                  new QName ("http://schemas.oracle.com/events/edl/HelloWorldEvents",
                             "InitiateHelloWorldEvent");
              BusinessEventBuilder beb = BusinessEventBuilder.newInstance();
                  // set the event name (that matches the QName of the EDL)
                  beb.setEventName(eventName);
                  // payload element as dom
                  beb.setBody(createElementFromInput(input));
                  UUID uuid = UUID.randomUUID();
                  beb.setProperty(BusinessEvent.EVENT_ID, uuid);
                  // the conversation id can help to find the composite instance later via conv id.
                  beb.setProperty(BusinessEvent.PROPERTY_CONVERSATION_ID, uuid);
              return beb.createEvent();
          }
      

      Thanks Rich for developing this really usable Live Writer Plug-in for WordPress!

      Implement Domain Value Maps (DVM) with Oracle Service Bus (OSB) 10R3

      December 25, 2009 gschmutz Leave a comment

      Domain Value Maps (DVM) are an interesting feature of Oracle SOA Suite for supporting Canonical Data Models. They help to map from one vocabulary, used in a given domain, to another vocabulary used in a different domain. For example, one domain might represent a country with a numeric code while another domain may represent a country with the ISO-standard alphanumeric country code. In SOA Suite 10g there were part of the “old” Oracle ESB and in SOA Suite 11g they can be used from a Mediator component.

      Unfortunately this feature is not yet available in Oracle Service Bus (OSB). It will be added in the future, as the statement of direction states.

      This might be less of a problem when using both the Oracle SOA Suite together with the Oracle Service Bus in a larger architecture. In this case, the responsibility for mapping these values can be delegated to the SOA Suite 11g Mediator component, where the DVM functionality is available.

      But if only the OSB is used standalone, then such value mappings would be nice in the OSB as well. With the help of XQuery the DVM functionality can be implemented in a similar way, so that if the feature is later available in a new version of OSB, it can be replaced by that with minimal work involved. This blog entry shows the custom DVM functionality implemented for the Oracle Service Bus.

      Custom DVM functionality implemented using XQuery function in OSB

      In order to show the custom DVM functionality a simple OSB service has been implemented. It only consists of a simple Proxy Service, which accepts a request message with two static code values (country and currency), translates the message into the canonical format and returns (echo) it to the caller. A sample request and the corresponding response can be seen in the window below taken from soapUI.

      soapui-call 

      The message flow of the Proxy Service below uses a stage (TransformationToCanonicalState), which is responsible to map from the source to the canonical format. First the value maps are assigned to variables (Assign 1 for country map and Assign 2 for currency amp) and then the message is transformed using an XQuery function (Assign 3).

      pipeline

      For the definition of the Domain Value Maps the same format known from the SOA Suite is used. The picture below shows the map for the currency code mapping. The <columns> element defines the number of value domains and assigns a name to each domain, in our case Source and Canonical. The <rows> element defines the value mappings, i.e. the value 10 in the Source domain should be mapped to to the value CHF in the Canonical domain.

      currency-dvm

      The format is based on a XML Schema which can be found in the Oracle SOA Suite documentation here. An XSD file with the schema is also part of the example OSB project which can be downloaded from here.

      The next window shows the definition of the 3rd Assign action in the XQuery Expression Editor. The first parameter holds the source message to be translated and the next two parameters hold the content of the two value maps for country and currency mapping.

      xquery-editor

      The XQuery script (transform.xq) implements the transformation. The next figure shows it in the graphical (design) view. The translation of the countryCode to isoCountry and from currencyCode to isoCountry are both using the corresponding parameters holding the content of the domain value maps. 

      transform-xq

      The source of the transform() function is shown below

      transform-source-xq

      The custom DVM functionality is wrapped by the lookupValue() function, matching the DVM implementation of the Oracle SOA Suite, where a function with the same name is available.  The only difference is the first parameter, which in our case is an element holding the contents of the domain value map, whereas in the SOA Suite version the first parameter only holds the name (reference) of the DVM file.

      The source of the lookupValue() function can be seen below

      lookupValue-function

      The function looks up the necessary source value and translates it to corresponding target value.

      Unfortunately the Oracle Service Bus does not support the XQuery Modules feature, which would allow the creation of function libraries to be reused. Therefore the lookupValue() function needs to be copied into the transform.xq script. This copy-paste reuse is not optimal, I hope that OSB will fully support XQuery 1.0 and especially the Module functionality in the future.

      This finishes the custom implementation of the DVM functionality in Oracle Service Bus. It closely matches the DVM functionality of the Oracle SOA Suite, which Oracle will offer in a future version of OSB as well. The solution shown in this blog can help in the meantime and will allow for an easy migration to the built-in function in the future. It’s only a proof-of-concept and has not yet been used in production!

      The example project can be downloaded form here.

      Use comments on actions to increase maintainability of your Oracle Service Bus (OSB) flows

      December 22, 2009 gschmutz 1 comment

      Ever wondered how you can increase the understandability and the maintainability of your OSB message flows in a Proxy Service?

      As you know, a message flow in OSB consists of different actions. Unfortunately these actions are just labeled according to the action type, so for example you can have many Assign, Validate, Service Callout, … actions, like shown in the flow below when using Oracle Workshop for WebLogic:

      message-flow

      These actions can be wrapped inside the Stage, to show a group of actions belonging together. Unfortunately the actions itself can not have custom labels. This is different in BPEL, where the readability of a BPEL flow can be easily increased by using some good names for the different BPEL activities.

      OSB does not allow that. But each OSB action can have a comment, which is then shown as a tooltip in the Oracle Workshop for WebLogic, like shown below:

      message-flow-with-comment

      By just hovering with the mouse over the icon of one action, the comment is shown in the tooltip and can help to better understand about the responsibility of each single action in the flow.

      A comment can be added via the Properties tab of each action, like shown below:

      message-flow-properties

      The comments are also visible when viewing the message flow in the OSB console

      message-flow-in-console. 

      I just found out about that “feature” a couple of weeks ago and will now definitely use more comments in my message flows!

      ODTUG Kaleidoscope 2010 – Abstract Accepted

      December 11, 2009 gschmutz Leave a comment

      Good news for me today! I received an email telling that my abstract on Testing SOA Suite 11g Systems has been accepted. I’m honoured and looking forward to present at the ODTUG Kaleidoscope 2010 conference.

      Here is the abstract I submitted:

      Best Practices for testing SOA Suite 11g based systems
      The purpose of testing in general is to assess applications quality. Many approaches existing for traditional software systems can be adapted or even reused for service-oriented systems. Service-oriented testing has many similarities with component-based testing.
      Oracle SOA Suite 11g offers out of the box support for testing BPEL and Mediator services. But is this enough? How can we test services which are dependent on external services not available at testing time? Is there an efficient way to mock these services? This session we will present solutions and best practices for testing service-oriented systems based on SOA Suite 11g platform and demonstrate how testing can be improved by adding some 3rd party products to Oracle SOA Suite, like soapUI.

      See you in Washington D.C. next year!

       

      My two DOAG presentations now available in English

      December 3, 2009 gschmutz Leave a comment

      I got asked for a translated version of the DOAG presentations (which are in german) announced here couple of days ago. Today I finished the translation and uploaded both of them to my slideshare profile:

      I will upload some more presentations to slideshare in the future.

      I’m in hospital

      December 3, 2009 gschmutz 1 comment

      Last Sunday I had an accident playing icehockey. Now I’m in hospital with a broken foot :-(   Because of that, I had to cancel the SOA bootcamp in Geneva of next week. A new date will be announced soon.

      My injury also means, that I have to stay at home for the coming weeks. So I will have some time to do what I always had in mind but never had the time, like reading some books, writing articles or blog entries :-) . So stay tuned!

      Categories: Private