26 Extending Component Configuration

This chapter describes how to use an XML schema to extend the default configuration for adapters and event beans used with Oracle Event Processing, including information on using Java annotations to generate the configuration XML.

This chapter includes the following sections:

26.1 Overview of Extending Component Configuration

Adapters and event beans have default configuration data. This default configuration is typically adequate for simple and basic applications.

However, you can also extend this configuration by using a XML Schema Definition (XSD) schema to specify a new XML format of an adapter configuration file that extends the built-in XML type provided by Oracle Event Processing. By extending the XSD Schema, you can add as many new elements to the adapter configuration as you want, with few restrictions other than each new element must have a name attribute.

This feature is based on standard technologies, such as XSD and Java Architecture for XML Binding (JAXB).

You can extend component configuration by:

For more information, see:

26.1.1 Extending Component Configuration Using Annotations

The simplest and most efficient way to extend component configuration is to annotate your adapter or event bean Java class using the annotations that javax.xml.bind.annotation specifies.

Oracle Event Processing supports the inclusion of multiple namespaces in an EPN configuration file as well as supporting sourcing configuration information from the providing bundle rather than the client bundle. Oracle Event Processing scans for multiple ObjectFactories in the accessible class-space and each of these will be initialized through createConfig.

The schema search takes into account the wlevs:factory element provider-schema child element in adapter bundles. So if you are defining an adapter in its own bundle you can put the schema in that bundle as long as you define the provider-bundle property.

Oracle recommends that you use elementFormDefault="unqualified" so that locally defined elements will not have a namespace, but global elements will leverage the targetNamespace. This will avoid name clashes across schemas without requiring excessive prefixing.

For more information, see http://www.xfront.com/HideVersusExpose.html.

For more information, see:

26.1.2 Extending Component Configuration Using an XSD

If you require more detailed control over your custom component configuration, you can extend your component configuration by creating your own XSD.

For more information, see:

26.2 Extending Component Configuration

You can extend component configuration in either of the following ways:

For more information, see Section 26.1, "Overview of Extending Component Configuration".

26.2.1 How to Extend Component Configuration Using Annotations

The simplest and most efficient way to extend component configuration is to annotate your adapter or event bean Java class.

Alternatively, you can extend component configuration by creating your own XSD as Section 26.2.2, "How to Extend Component Configuration Using an XSD" describes.

For more information, see Section 26.1.1, "Extending Component Configuration Using Annotations".

To extend component configuration using annotations:

  1. Implement your custom adapter or event bean Java class.

    For more information, see:

  2. Annotate the attributes of your custom adapter or event bean to specify the component configuration using the annotations that javax.xml.bind.annotation specifies.

    Important javax.xml.bind.annotation annotations include:

    • @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 require extensive use of @XmlJavaTypeAdapter, consider defining your own custom schema as Section 26.2.2, "How to Extend Component Configuration Using an XSD" describes.

    Note:

    A property without an annotation is assumed to be an optional configuration property (default: @XmlElement).

    Example 26-1 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 instance property howBig.

    Example 26-1 Annotated Custom Adapter Implementation

    @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 Section 26.3, "Programming Access to the Configuration of a Custom Adapter or Event Bean" describes.

  4. Modify the component configuration XML file that describes the custom components of your application.

    For more information, see Section 15.5.2, "Configuring a Custom Adapter in a Component Configuration File".

  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. In addition, be sure you identify the namespace for this schema rather than the default schema.

    Example 26-2 shows a component configuration file for the custom adapter in Example 26-1.

    Example 26-2 Extended Component Configuration: Annotations

    <?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 as Example 26-5 shows.

  6. Package and deploy your application.

    For more information, see Chapter 23, "Assembling and Deploying Oracle Event Processing Applications".

26.2.2 How to Extend Component Configuration Using an XSD

You can extend the component configuration of a custom adapter or event bean using your own XSD.

Alternatively, you can extend component configuration by annotating your adapter or event bean Java class as Section 26.2.1, "How to Extend Component Configuration Using Annotations" describes.

For more information, see Section 26.1.2, "Extending Component Configuration Using an XSD".

To extend component configuration using an XSD:

  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 Event Processing, to describe them.

    See Section 26.2.2.1, "Creating the XSD Schema 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 Sun's GlassFish reference implementation. This Ant task is included in the Oracle Event Processing 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 Event Processing 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 Event Processing XSD files.

    For more information, see http://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.

    See Section 23.2, "Assembling an Oracle Event Processing Application".

  5. Program your custom adapter or event bean.

    For more information, see:

  6. Within your custom adapter or event bean code, access the extended configuration as Section 26.3, "Programming Access to the Configuration of a Custom Adapter or Event Bean" 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 namespace for this schema rather than the default schema.

    Example 26-3 shows a component configuration file for the XSD you created in Section 26.2.2.1, "Creating the XSD Schema File".

    Example 26-3 Extended Component Configuration File: XSD

    <?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>
    

26.2.2.1 Creating the XSD Schema File

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

Oracle recommends that you use the XSD schema in Section 26.2.2.1.1, "Complete Example of an Extended 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.

For more information, see Section B.2, "Component Configuration Schema wlevs_application_config.xsd".

To create a new XSD schema file:

  1. Using your favorite XML Editor, create the basic XSD file with the required namespaces, 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 XSD schema:

    <xs:import 
       namespace="http://www.bea.com/ns/wlevs/config/application"
       schemaLocation="wlevs_application_config.xsd"/>
    

    The wlevs_application_config.xsd in turn imports the wlevs_base_config.xsd XSD file.

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

    The new type must extend the AdapterConfig type, defined in wlevs_application_config.xsd. AdapterConfig extends ConfigurationObject. You can then 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 should 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 itself extends ConfigurationObject. The ConfigurationObject XML type, defined in wlevs_base_config.xsd, defines a single attribute: name.

    The type of your adapter element should be the custom one 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:

    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> 
    
26.2.2.1.1 Complete Example of an Extended 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>

26.3 Programming Access to the Configuration of a Custom Adapter or Event Bean

This section applies to both adapters and event beans. For simplicity the text mentions only adapters.

When you deploy your application, Oracle Event Processing maps the configuration of each component (specified in the component configuration XML files) into Java objects using the Java Architecture for XML Binding (JAXB) standard (for more information, see http://jaxb.java.net/). Because there is a single XML element that contains the configuration data for each component, JAXB in turn also produces a single Java class that represents this configuration data. Oracle Event Processing passes an instance of this Java class to the component (processor, channel, or adapter) at runtime when the component is initialized, and also whenever there is a dynamic change to the component's configuration.

You can access this component configuration at runtime in either of the following ways:

Note:

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

26.3.1 How to Access Component Configuration Using Resource Injection

By default, Oracle Event Processing configures adapters by direct injection of their Java bean properties followed by the usual configuration callbacks.

Consider the annotated custom adapter implementation that Example 26-4 shows.

Example 26-4 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;
    }
}

And consider the component configuration file for an instance of this custom adapter that Example 26-5

Example 26-5 Extended Component Configuration

<?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, by default Oracle Event Processing directly injects the value (true) of the Java bean property doit.

Note:

The extended component configuration schema requires a nested config element as Example 26-5 shows.

For more information, see:

26.3.2 How to Access Component Configuration Using Lifecycle Callbacks

In your adapter implementation, you can use metadata annotations to specify the Java methods that are invoked by Oracle Event Processing at runtime.

Oracle Event Processing passes an instance of the configuration Java class to these specified methods; you can then program these methods to get specific runtime configuration information about the adapter.

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, however, you have extended the configuration of your adapter by creating your own XSD file that describes the configuration XMLfile, 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.

This section describes:

26.3.2.1 Lifecycle Callback Annotations

You can use the following metadata annotations to specify various lifecycle callback methods:

For more information, see Section 26.3.2.2, "Lifecycle".

26.3.2.2 Lifecycle

Oracle Event Processing follows the following lifecycle during custom adapter and event bean instantiation:

  1. Create adapter or event bean instance.

  2. Inject static properties.

  3. Call afterPropertiesSet.

  4. Prepare phase:

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

    2. Otherwise, directly inject configuration properties.

      See Section 26.3.1, "How to Access Component Configuration Using Resource Injection".

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