2 Extend Adapters and Event Beans

You can use an XML schema definition (XSD) or Java Architecture for XML Binding (JAXB) annotations to extend the default configuration for adapters and event beans.

This chapter includes the following sections:

2.1 Annotations

The simplest and most efficient way to extend component configuration is to annotate your custom adapter or event bean JavaBean class with the annotations provided in the JAXB javax.xml.bind.annotation package. For more information, see http://docs.oracle.com/javaee/7/api/javax/xml/bind/annotation/package-summary.html and https://jaxb.java.net/.

Extend Component Configuration with Annotations

  1. Implement your custom adapter or event bean JavaBean class.
  2. Annotate the attributes of your custom adapter or event bean to specify the component configuration with the applicable annotations from the javax.xml.bind.annotation package.

    Important annotations from the javax.xml.bind.annotation package include the following. A property without an annotation defaults to the optional configuration property (@XmlElement).

    • @XmlElement: Property is an optional part of the component configuration.

    • @XmlElement(required=true): Property is a required part of the component configuration.

    • @XmlTransient: Property is not part of the component configuration.

    • @XmlJavaTypeAdapter: Property elements annotated with this can specify custom handling to accommodate most Java data types.

      Note:

      If you extensively use of @XmlJavaTypeAdapter, consider defining your own custom schema. See XSD File.

    The following example shows a custom adapter implementation annotated with javax.xml.bind.annotation annotations to specify:

    • count: Not part of the component configuration.

    • doit: Required part of the component configuration.

    • size: Required part of the component configuration. Maps to howBig instance property.

    @XmlType(name="SampleAdapterConfig", namespace="http://www.oracle.com/ns/cep/config/sample/")
    public class SampleAdapterImpl implements Adapter {
      @XmlTransient
      private int count;
    
      @XmlElement(name="size")
      private int howBig;
    
      @XmlElement(required=true)
      private boolean doit;
      
      ...
    
      public void setDoit(boolean doit) {
        this.doit = doit;
      }
    
      public boolean getDoit() {
        return doit;
      }
    }
    
  3. Within your custom adapter or event bean code, access the extended configuration as Access to the Component Configuration describes.
  4. Modify the component configuration XML file that describes the custom components of your application.

    For more information, see Configure a Custom Adapter.

  5. When you create the component configuration XML file that describes the components of your application, be sure to use the extended XSD file as its description. Also be sure to identify the name space for this schema rather than use the default schema.

    The following example shows a component configuration file for the SampleAdapterImpl custom adapter in step 2.

    <?xml version="1.0" encoding="UTF-8"?>
    <app:config
      xmlns:app="http://www.bea.com/ns/wlevs/config/application"
      xmlns:sample="http://www.oracle.com/ns/cep/config/sample/"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="
        http://www.bea.com/ns/wlevs/config/application
        http://www.bea.com/ns/wlevs/config/application/wlevs_application_config.xsd
        http://www.oracle.com/ns/cep/config/sample
        http://www.oracle.com/ns/cep/config/sample/ocep_sample_config.xsd">
      <processor>
        <name>clusterProcessor</name>
        <rules>
          <query id="clusterRule"><![CDATA[ select * from clusterInstream [Now] >
          </query>
        </rules>
      </processor>
        <sample:adapter>
          <name>myadapter</name>
          <config>
            <size>15</size>      <!-- optional -->
            <doit>true</doit>    <!-- required -->
          </config>
        </sample:adapter>
    </app:config>
    

    Note:

    The extended component configuration schema requires a nested config element.

  6. Package and deploy your application.

2.2 XSD File

You can extend an adapter or an event bean configuration with an XML Schema Definition (XSD) file. Add as many custom elements to the XSD file as you need with few restrictions other than each new element must have a name attribute.

When you set up the name spaces, Oracle recommends that you use elementFormDefault="unqualified" so that locally defined elements do not have a names pace, but global elements leverage the targetNamespace. This avoids name clashes across schemas without requiring excessive prefixing. For more information, see http://www.xfront.com/HideVersusExpose.html.

You can also manually generate a custom schema that does not extend the application schema. This allows you to create custom configuration in your own name space without having to define all of the other elements. This mechanism functions like the annotation approach after you generate the schema.

2.2.1 Extend the Component Configuration with an XSD File

  1. Create the new XSD Schema file that describes the extended adapter or event bean configuration.

    This XSD file must also include the description of the other components in your application (processors and streams), although you typically use built-in XSD types, defined by Oracle Stream Analytics, to describe them.

    See Create an XSD File.

  2. As part of your application build process, generate the Java representation of the XSD schema types using a JAXB binding compiler, such as the com.sun.tools.xjc.XJCTask Ant task from the GlassFish reference implementation. This Ant task is included in the Oracle Stream Analytics distribution for your convenience.

    The following sample build.xml file shows how to do this:

    <property name="base.dir" value="." />
    <property name="output.dir" value="output" />
    <property name="sharedlib.dir" value="${base.dir}/../../../../../modules" />
    <property name="wlrtlib.dir" value="${base.dir}/../../../../modules"/>
    <path id="classpath">
            <pathelement location="${output.dir}" />
            <fileset dir="${sharedlib.dir}">
                    <include name="*.jar" />
            </fileset>
            <fileset dir="${wlrtlib.dir}">
                   <include name="*.jar"/>
            </fileset>
    </path>
    <taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask">
          <classpath refid="classpath" />
    </taskdef>
    <target name="generate" depends="clean, init">
       <copy file="../../../../xsd/wlevs_base_config.xsd"
             todir="src/main/resources/extension" />
       <copy file="../../../../xsd/wlevs_application_config.xsd"
              todir="src/main/resources/extension" />
       <xjc extension="true" destdir="${generated.dir}">
          <schema dir="src/main/resources/extension" 
                  includes="helloworld.xsd"/>
          <produces dir="${generated.dir}" includes="**/*.java" />
       </xjc>
    </target>
    

    In the example, the extended XSD file is called helloworld.xsd. The build process copies the Oracle Stream Analytics XSD files (wlevs_base_config.xsd and wlevs_application_config.xsd) to the same directory as the helloworld.xsd file because helloworld.xsd imports the Oracle Stream Analytics XSD files.

    For more information, see https://jaxb.java.net/nonav/2.0.2/docs/xjcTask.html.

  3. Compile these generated Java files into classes.
  4. Package the compiled Java class files in your application bundle.
  5. Program your custom adapter or event bean.

    For more information, see: Implementation Basics.

  6. Within your custom adapter or event bean code, access the extended configuration as Access to the Component Configuration describes.
  7. When you create the component configuration XML file that describes the components of your application, be sure to use the extended XSD file as its description. In addition, be sure you identify the names pace for this schema rather than the default schema.

    The following example shows a component configuration file for the XSD you created in Create an XSD File.

    <?xml version="1.0" encoding="UTF-8"?>
    <helloworld:config
      xmlns:helloworld="http://www.bea.com/xml/ns/wlevs/example/helloworld">
      <adapter>
        <name>helloworldAdapter</name>
        <message>HelloWorld - the current time is:</message>
      </adapter>
    </helloworld:config>
    

2.2.2 Create an XSD File

The new XSD file extends the wlevs_application_config.xsd XSD and adds new custom information, such as new configuration elements for an adapter. Use standard XSD syntax for your custom information.

Oracle recommends that you use the XSD in Complete Example of an XSD Schema File as a basic template, and modify the content to suit your needs. In addition to adding new configuration elements, other modifications include changing the package name of the generated Java code and the element name for the custom adapter. You can control whether the schema allows just your custom adapter or other components like processors.

Create a New XSD File

  1. Create the basic XSD file with the required names paces, in particular those for JAXB. For example:
    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema targetNamespace="http://www.bea.com/xml/ns/wlevs/example/helloworld"
      xmlns="http://www.bea.com/xml/ns/wlevs/example/helloworld"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
      xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
      xmlns:wlevs="http://www.bea.com/ns/wlevs/config/application"
      jxb:extensionBindingPrefixes="xjc" jxb:version="1.0"
      elementFormDefault="unqualified" attributeFormDefault="unqualified">
    ...
    </xs:schema>
    
  2. Import the wlevs_application_config.xsd file:
    <xs:import 
       namespace="http://www.bea.com/ns/wlevs/config/application"
       schemaLocation="wlevs_application_config.xsd"/>
    

    The wlevs_application_config.xsd file imports the wlevs_base_config.xsd file.

  3. Use the complexType XSD element to describe the extended adapter configuration XML type.

    The new type must extend the AdapterConfig type, which is defined in wlevs_application_config.xsd. AdapterConfig extends ConfigurationObject. You can add new elements or attributes to the basic adapter configuration as needed. For example, the following type called HelloWorldAdapterConfig adds a message element to the basic adapter configuration:

    <xs:complexType name="HelloWorldAdapterConfig">
        <xs:complexContent>
            <xs:extension base="wlevs:AdapterConfig">
                <xs:sequence>
                    <xs:element name="message" type="xs:string"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    
  4. Define a top-level element that must be named config.

    In the definition of the config element, define a sequence of child elements that correspond to the components in your application. Typically the name of the elements indicate what component they configure (adapter, processor, channel) although you can name then anything you want.

    Each element must extend the ConfigurationObject XML type, either explicitly using the xs:extension element with base attribute value base:ConfigurationObject or by specifying an XML type that extends ConfigurationObject. The ConfigurationObject XML type, defined in wlevs_base_config.xsd, defines a single attribute: name.

    The type of your adapter element is the custom adapter you created in a preceding step of this procedure.

    You can use the following built-in XML types that wlevs_application_config.xsd describes for the child elements of config that correspond to processors or streams:

    • DefaultProcessorConfig: For a description of the default processor configuration, see Java API Reference for Oracle Stream Analytics

    • DefaultStreamConfig: For a description of the default channel configuration, see Oracle Fusion Middleware Developing Applications with Oracle Stream Analytics.

    For example:

    <xs:element name="config">
      <xs:complexType>
        <xs:choice maxOccurs="unbounded">
          <xs:element name="adapter" type="HelloWorldAdapterConfig"/>
            <xs:element name="processor" type="wlevs:DefaultProcessorConfig"/>
        </xs:choice>
      </xs:complexType>
    </xs:element>
    
  5. Optionally use the jxb:package child element of jxb:schemaBindings to specify the package name of the generated Java code:
    <xs:annotation>
      <xs:appinfo>
         <jxb:schemaBindings>
             <jxb:package name="com.bea.adapter.wlevs.example.helloworld"/>
         </jxb:schemaBindings>
      </xs:appinfo>
    </xs:annotation> 
    

2.2.3 Complete Example of an XSD Schema File

Use the following extended XSD file as a template:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.bea.com/xml/ns/wlevs/example/helloworld"
  xmlns="http://www.bea.com/xml/ns/wlevs/example/helloworld"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
  xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
  xmlns:wlevs="http://www.bea.com/ns/wlevs/config/application"
  jxb:extensionBindingPrefixes="xjc" jxb:version="1.0"
       elementFormDefault="unqualified" attributeFormDefault="unqualified">
  <xs:annotation>
    <xs:appinfo>
      <jxb:schemaBindings>
        <jxb:package name="com.bea.adapter.wlevs.example.helloworld"/>
      </jxb:schemaBindings>
    </xs:appinfo>
  </xs:annotation>
  <xs:import namespace="http://www.bea.com/ns/wlevs/config/application" 
       schemaLocation="wlevs_application_config.xsd"/>
  <xs:element name="config">
    <xs:complexType>
      <xs:choice maxOccurs="unbounded">
        <xs:element name="adapter" type="HelloWorldAdapterConfig"/>
        <xs:element name="processor" type="wlevs:DefaultProcessorConfig"/>
        <xs:element name="channel" type="wlevs:DefaultStreamConfig"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="HelloWorldAdapterConfig">
    <xs:complexContent>
      <xs:extension base="wlevs:AdapterConfig">
        <xs:sequence>
          <xs:element name="message" type="xs:string"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:schema>

2.3 Access to the Component Configuration

When you deploy your application, Oracle Stream Analytics maps the configuration of each component specified in the component configuration files into Java objects that adhere to the JAXB standard. Because there is a single XML element that contains the configuration data for each component, JAXB also produces a single Java class that represents the configuration data. Oracle Stream Analytics passes an instance of this Java class to the component (processor, channel, or adapter) at runtime when the component initializes and whenever a dynamic change to the component configuration occurs.

You can access this component configuration at run time in the following ways:

  • With resource injection as Resource Injection describes.

    This is the simplest and most efficient way to access component configuration at runtime.

  • With callbacks as Life Cycle Callbacks.

    This is the most flexible way to access component configuration at run time. Consider this option if resource injection does not meet your needs.

Note:

Clients that need to use a schema from a provider must import the appropriate package from the provider bundle so the provider's ObjectFactory is visible to the client bundle.

2.3.1 Resource Injection

By default Oracle Stream Analytics configures adapters and event beans by direct injection of their JavaBean properties followed by configuration callbacks.

Consider the annotated custom adapter implementation.

@XmlType(name="SampleAdapterConfig", namespace="http://www.oracle.com/ns/cep/config/sample/")
public class SampleAdapterImpl implements Adapter {
    private boolean doit;

    public void setDoit(boolean doit) {
        this.doit = doit;
    }

    public boolean getDoit() {
        return doit;
    }
}

Consider the configuration file for an instance of this custom adapter.

<?xml version="1.0" encoding="UTF-8"?>
<app:config
      xmlns:app="http://www.bea.com/ns/wlevs/config/application"
      xmlns:sample="http://www.oracle.com/ns/cep/config/sample/"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="
            http://www.bea.com/ns/wlevs/config/application
            http://www.bea.com/ns/wlevs/config/application/wlevs_application_config.xsd
            http://www.oracle.com/ns/cep/config/sample
            http://www.oracle.com/ns/cep/config/sample/ocep_sample_config.xsd">
  <processor>
    <name>clusterProcessor</name>
    <rules>
      <query id="clusterRule"><![CDATA[ select * from clusterInstream [Now] ></query>
    </rules>
  </processor>
    <sample:adapter>
        <name>myadapter</name>
        <config>
            <doit>true</doit>
        </config>
    </sample:adapter>
</app:config>

At runtime Oracle Stream Analytics calls the setDoIt method of the adapter instance and passes the value true as the argument value.

Note:

The extended component configuration schema requires a nested config element.

2.3.2 Life Cycle Callbacks

In your adapter or event bean implementation, you can use metadata annotations to specify the Java methods to be invoked by Oracle Stream Analytics at runtime. Oracle Stream Analytics passes an instance of the configuration Java class to these specified methods. You can program these methods to get specific run time configuration information about the adapter or event bean.

The following example shows how to annotate the activateAdapter method with the @Activate annotation to specify the method invoked when the adapter configuration is first activated:

@Activate
public void activateAdapter(HelloWorldAdapterConfig adapterConfig) {
    this.message = adapterConfig.getMessage();
}

By default, the data type of the adapter configuration Java class is com.bea.wlevs.configuration.application.DefaultAdapterConfig. If you have extended the configuration of the adapter (or event bean) by creating your own XSD file that describes the configuration XML file, then you specify the type in the XSD file. In the preceding example, the data type of the Java configuration object is com.bea.wlevs.example.helloworld.HelloWorldAdapterConfig.

2.3.3 Life Cycle Callback Annotations

You can use the following metadata annotations to specify life cycle callback methods:

  • com.bea.wlevs.management.Activate: Specifies the method invoked when the configuration is activated.

  • com.bea.wlevs.management.Prepare: Specifies the method invoked when the configuration is prepared. See Getting Started with Event Processing for Oracle Stream Analytics for additional details about using this annotation in your adapter code.

  • com.bea.wlevs.management.Rollback: Specifies the method invoked when the adapter is terminated due to an exception.

2.3.4 Life Cycle for Adapters and Event Beans

Oracle Stream Analytics uses the following life cycle to create adapter and event beans.

  1. Create the adapter or event bean instance.

  2. Inject static properties.

  3. Call the afterPropertiesSet method.

  4. Prepare phase:

    1. If @Prepare with one or more configuration arguments is present, call it. Otherwise, directly inject configuration properties.

    2. If @Prepare without arguments is present, call it.

  5. Activate phase:

    1. If @Activate with one or more configuration arguments is present, call it.

    2. If @Activate without arguments is present, call it.

  6. Call afterConfigurationActive.

  7. Continue with other configuration.