# Writing a Custom Filter using the Oracle Enterprise Gateway SDK

## Contents
Tutorial Overview Policies, Filters, and Message Attributes Oracle Enterprise Gateway SDK Overview Tutorial Prerequisites Oracle Enterprise Gateway SDK Sample Overview Step 1: Create the Typedocs Step 2: Create the Filter Class Step 3: Create Processor Class Step 4: Create Policy Studio Classes Step 5: Build Classes Step 6: Load TypeDocs Step 7: Construct a Policy Step 8: Configure the SimpleFilter Conclusion

## Tutorial Overview
Oracle Enterprise Gateway exposes several powerful APIs as part of its Software Development Kit (SDK) to enable users to build their own bespoke message filters. Users can leverage Oracle Enterprise Gateway's pluggable and extensible architecture to enhance the message processing capabilities of the Oracle Enterprise Gateway core processing engine. This tutorial walks you through a step-by-step example of how to build a custom-built message filter with the SDK, and integrate it into a policy. This tutorial shows how to build the two main aspects of an Addition filter: the server runtime component, and the Policy Studio configuration component. It then integrates these components into a policy, and shows how the filter adds the values of two parameters of a SOAP message together, and returns the result to the client. By the end of this tutorial, you should be able to write and test your own message filters by following a similar procedure. Before going any further, however, it is important to explain exactly what are Oracle Enterprise Gateway filters and to see exactly how they can be wired together to create message processing policies.
## Policies, Filters, and Message Attributes
A policy consists of a network of message filters where each filter is a modular executable unit that performs a specific type of processing on a message. The policy arranges these filters into sequences called paths. The filters then act as decision-making points along these paths, determining which filters are run on the message, and in what order. The following four-node policy contains a single path with four message filters. The filter marked as Start (AuthN: WS-Security Username Token) is executed first. If this filter runs successfully, the next filter in the path (getQuotes Operation Name) is run, and so on until the last filter (Echo Web Service) in the path is executed.
Simple Circuit
When an HTTP request is received, it is converted into a set of message attributes. Each message attribute represents a specific characteristic of the HTTP request, such as the HTTP headers, HTTP body, and MIME parts, amongst others. Every Filter declares the message attributes that it requires, generates, and consumes from the attributes blackboard. The blackboard contains all the available message attributes. When a filter generates message attributes it puts them up on the blackboard so that when another Filter requires them it can pull them off the blackboard. If a filter consumes a message attribute, it is wiped from the blackboard so that no other filter in the policy can use it. The following table summarizes the attributes required and generated by the Operation Name resolver, which filters incoming requests based on their SOAP operation and namespace:
Filter Name: | Operation Name
Description: | Filters incoming SOAP requests based on their SOAP operation and namespace.
Required Attributes: | `content.body` `http.request.uri`
Generated Attributes: | `soap.request.method`
For more information on policy, policy building, filters, please refer to your Enterprise Gateway documentation. The following list summarizes the important concepts introduced in this section: Policy: A network of interconnected message filters. Message Filters: An executable unit that performs a specific type of processing on message attributes. Message Attributes: Message attributes represent specific characteristics of a message.
## Oracle Enterprise Gateway SDK Overview
The Oracle Enterprise Gateway Software Development Kit (SDK) comprises three Java packages that provide programmatic access to Oracle Enterprise Gateway policies, message objects, and the Entity Store. The following table describes these packages:
Package | Description
com.vordel.circuit | This package is responsible for implementing the core Oracle Enterprise Gateway policy. It includes the base classes for all message filters and their associated classes.
com.vordel.mime | Includes classes that encapsulate the message as it passes through the Oracle Enterprise Gateway policy. It also provides programmatic access to HTTP headers, HTTP body, request query string (if present), and MIME parts.
com.vordel.es | These classes provide access to the underlying Entity Store where all configuration data is stored.
## Tutorial Prerequisites
You should read Getting Started to make sure you understand the concepts of policies and filters before continuing. The Oracle Enterprise Gateway SDK requires a JDK 1.6, and is supported for the Windows, Linux, and Solaris packages.
## Oracle Enterprise Gateway SDK Sample Overview
The Oracle Enterprise Gateway SDK ships with a working example of a message filter, called the `SimpleFilter`, that demonstrates how to use the SDK to build a filter. The filter extracts two integer parameters from a SOAP message, adds the integers, and returns the result of the addition in a SOAP response to the client. This tutorial documents the steps required to build, integrate, configure, and test the supplied `SimpleFilter` and `SimpleProcessor` classes. The steps are as follows:
Step | Description
Step 1: Create TypeDocs | Every filter has an associated XML-based TypeDoc that contains the entity's type definition. It defines the configuration field names for that filter and their corresponding data types.
Step 2: Create Filter Class | Every message filter has an associated Filter class that encapsulates the configuration data for a particular instance of the filter. It also returns the corresponding Processor and Policy Studio classes.
Step 3: Create Processor Class | The Processor class is the server runtime component that is responsible for processing the message. Every message filter has an associated Processor and Filter class.
Step 4: Create Policy Studio Classes | All Filters are configured using the Policy Studio. Every Filter has a configuration wizard that enables you to set each of the fields defined in the entity that corresponds to that Filter. You can then add the filter to a policy to process messages.
Step 5: Build Classes | When the classes have been written, they must be built and added to the server and client classpaths.
Step 6: Load TypeDocs | The TypeDoc that is created for the filter in Step 1 must be registered with the Entity Store.
Step 7: Construct a Policy | This step constructs a policy that echoes messages back to the client, and then adds the newly created filter to it.
Step 8: Configure the SimpleFilter | This step uses the GUI component of the newly added filter to configure its configuration fields. It then tests the functionality of the filter (and its configuration) using the Oracle Service Explorer testing tool.
## Step 1: Create the Typedocs
All configuration data is stored as entities in the Oracle Enterprise Gateway Entity Store. The Entity Store is an XML-based store that holds all configuration data required to run the Oracle core processing engine. Each configurable item has an entity type definition. The entity type definition is defined in an XML file known as the TypeDoc. Entity types are analogous to class definitions in an object-oriented programming language. In the same way that instances of a class can be created in the form of objects, an instance of an entity type can also be created. Therefore it is useful to think of the entity type defined in a TypeDoc as a header file, and the entity itself as a class instance. All entities and their entity type definitions are stored in the Entity Store. Every filter requires specific configuration data to perform its processing on the message. For example, the `SimpleFilter`, which extracts the values of two elements from a SOAP message, and adds them together, must be primed with the names and namespaces of those two elements. Because a filter is a configurable item, it requires a new XML typedoc to be written containing an entity type definition for it. The entity type for a filter contains a set of configuration parameters and their associated data types and default values. When an instance of the filter is added to a policy using the Policy Studio, a corresponding entity instance is created and stored in the Entity Store. Whenever the filter instance is invoked, its configuration data is read from the entity instance in the Entity Store. TypeDoc Syntax The following example XML shows how the TypeDoc lists the various fields that form the configuration data for the Filter.
    <entityStoreData>
      <entityType name="SimpleFilter" extends="Filter">
        <!-- Name of filter class that encapsulates the config data -->
        <constant name="class" type="string"
                     value="com.vordel.example.filter.SimpleFilter"/>
        <!-- List of config fields, their types, and their default values -->
        <field ... />
        <field ... />
        <field ... />
      </entityType>
    <entityStoreData>
All TypeDocs must obey the following simple rules: Extend the Filter type Define a constant Filter class List the configuration fields for the entity SimpleFilter Elements and Attributes The following table describes the important elements and attributes from the `SimpleFilter` TypeDoc listed above:
Element | Attribute | Description
`<entityStoreData>` |  | The topmost wrapper element for the entire type definition.
`<entityType>` |  | Contains the type definition, including all its fields and their types.
`<entityType>` | `name` | The unique name for this type.
`<entityType>` | `extends` | Entity definitions are hierarchical and can inherit from other higher level types. All filters must extend the `Filter` type.
`<constant>` |  | A `<constant>` element is used to represent a read-only immutable property of the type.
`<constant>` | `name` | This attribute contains the name of the read-only property. In the example above, the named property is `class`, indicating that the value of this constant is the Java class that encapsulates the defined type. The name of this class must be specified as a `<constant>`.
`<constant>` | `type` | Specifies the type of the `value` attribute. In this case, the value is the name of a Java class, which is just a string.
`<constant>` | `value` | Contains the value of the named property, which is the name of the Java class that encapsulates this type (`com.vordel.example.filter.SimpleFilter`).
`<field>` |  | Contains the definition of a single configuration field for this filter.
`<field>` | `name` | The name of the configuration field. You can see later in this tutorial how this name is used to get and set this property.
`<field>` | `type` | Specifies the data type of the named configuration field. For example, supported types include `string`, `boolean`, `encrypted`, and `integer`.
`<field>` | `cardinality` | Stipulates how many times this field can appear in an instance of the entity. For example, a cardinality of `1` means that this field can only occur once within an entity.
`<field>` | `default` | Specifies a default value for the configuration field, if appropriate.
SimpleFilter TypeDoc The TypeDoc for the `SimpleFilter` is as follows:
    <entityStoreData>
      <entityType name="SimpleFilter" extends="Filter">

        <!-- Name of Filter class that encapsulates this config entity -->
        <constant name="class" type="string"
                     value="com.vordel.example.filter.SimpleFilter"/>

        <!-- List of config params, their types, and their default values -->
        <field name="param1" type="string" cardinality="1" default="a"/>
        <field name="param1Namespace" type="string"
                  cardinality="1" default="http://startvbdotnet.com/web/"/>
        <field name="param2" type="string" cardinality="1" default="b"/>
        <field name="param2Namespace" type="string"
                  cardinality="1" default="http://startvbdotnet.com/web/"/>
      </entityType>
    </entityStoreData>
All type and related information for the Filter is contained in the top-level `<entityStoreData>` element. The Filter type declaration together with its field definitions and types are child elements of the `<entityType>` element. Each field name is specified in the `name` attribute of the `<field>` element, while the type and default value for the field are specified in the `type` and `default` attributes, respectively. You can also provide internationalized log messages by specifying an `<entity>` block of type `InternationalizationFilter` within the `<entityStoreData>` elements. Now that you understand how the configuration data for the filter is defined, you can create the filter class.
## Step 2: Create the Filter Class
A filter class encapsulates the type information defined in an entity's type definition. There are class members that correspond to each of the fields in the type definition. At runtime, when the filter is invoked, the filter class is instantiated with the configuration data for the appropriate entity instance. The filter class is responsible for the following tasks: Storing member variables corresponding to fields in the type definition Specifying the message attributes it requires, consumes, and generates Returning the corresponding server runtime class (the Processor) Returning the corresponding Policy Studio class SimpleFilter Class The following code shows the members and methods of the `SimpleFilter.java` example:
    package com.vordel.example.filter;

    import com.vordel.circuit.DefaultFilter;
    import com.vordel.circuit.FilterConfigureContext;
    import com.vordel.circuit.MessageProperties;
    import com.vordel.es.EntityStoreException;

     /**
     SimpleFilter contains the local name of the two
     parameters (a and b) and contains the namespace that
     these elements belong to (http://startvbdotnet.com/web/)
      **/

    public class SimpleFilter extends DefaultFilter {

        // element name of the first parameter
        String param1;
        // namespace of the first element
        String param1Namespace;
        // element name of the second parameter
        String param2;
        // namespace of the second parameter
        String param2Namespace;

        /**
         * Set the message attributes used by this filter
         */
        protected final void setDefaultProperties() {
            requiredProperties.add(MessageProperties.CONTENT_BODY);
        }

        /**
         * This method is called to set the config fields for the filter
         * @param ctx The configuration context for this filter
         * @param entity The entity object
         */
        public void configure(FilterConfigureContext ctx,
                                com.vordel.es.Entity entity)
                                throws EntityStoreException {

            super.configure(ctx, entity);

            // read the settings for the processor
            param1  = entity.getStringValue("param1");
            param1Namespace  = entity.getStringValue("param1Namespace");
            param2  = entity.getStringValue("param2");
            param2Namespace  = entity.getStringValue("param2Namespace");
        }

        /**
         * Returns the server runtime Processor class associated
         * with this Filter class.
         */
        public Class getMessageProcessorClass() {
            return SimpleProcessor.class;
        }

        /**
         * Returns the GUI component for this Filter
         */
        public Class getConfigPanelClass() throws ClassNotFoundException {
            // Avoid any compile or runtime dependencies on SWT and other UI
            // libraries by lazily loading the class when required.
            return
                Class.forName("com.vordel.example.filter.simple.SimpleFilterUI");
        }
    }
SimpleFilter TypeDoc At this point, it is worth revisiting the entity definition for the `SimpleFilter` entity to see how the class members correlate to the defined fields.
    <entityType name="SimpleFilter" extends="Filter">

      <!-- Name of Filter class that encapsulates this config entity -->
      <constant name="class" type="string"
                   value="com.vordel.example.filter.SimpleFilter"/>

      <!-- List of config params, their types, and their default values -->
      <field name="param1" type="string" cardinality="1" default="a"/>
      <field name="param1Namespace" type="string"
                cardinality="1" default="http://startvbdotnet.com/web/"/>
      <field name="param2" type="string" cardinality="1" default="b"/>
      <field name="param2Namespace" type="string"
                cardinality="1" default="http://startvbdotnet.com/web/"/>
    </entityType>
SimpleFilter Methods The Filter class members (`param1`, `param1Namespace`, `param2`, and `param2Namespace`) directly correspond to the field definitions in the type definition. These members are populated in the `configure` method of the Filter class, which is called by the framework when the server is started up initially, and whenever the server is refreshed. The `Entity` class provides getter and setter methods for the different data types (for example, string, boolean, integer, and so on). For more details, see the Entity Javadoc. There are two more important methods implemented in this class: `setDefaultProperties` and `getMessageProcessorClass`. The `setDefaultProperties` method enables the Filter to define the message attributes that it requires, generates, and consumes from the attributes blackboard. The blackboard contains all the available message attributes. When a filter generates message attributes, it puts them up on the blackboard so that when another Filter requires them, it can pull them off the blackboard. If a filter consumes a message attribute, it is wiped from the blackboard so that no other filter in the policy can use it. The attributes are stored in String arrays (`reqProps`, `genProps`, `conProps`), which are inherited from the `VariablePropertiesFilter` class. In the case of the `SimpleFilter` class, the `content.body` attribute is required because the SOAP parameters must be extracted from the body of the HTTP request. The next important method here is the `getMessageProcessorClass` method, which returns the server runtime component (the Processor class) that is associated with this Filter class. Each Filter class has a corresponding Processor class, which is responsible for using the configuration data stored in the Filter class to process the message. The next step looks at the `SimpleProcessor` class to see how it acts on the data stored in the `SimpleFilter` class. Finally, the corresponding Policy Studio configuration class is returned by the `getConfigPanelClass` method, which in this case is the `com.vordel.example.filter.simple.SimpleFilterUI` class. This class is described in detail in Step 4 of this tutorial.
## Step 3: Create Processor Class
The Processor class is responsible for performing the processing on the message. It uses the configuration data stored in the Filter class to determine how to process the message. It is important to note that this is the server runtime component of the filter that is returned by the `getMessageProcessorClass` of the Filter class described in the previous section. Example Skeleton Code The following skeleton code shows how the Processor attaches to the Filter class and uses its data to process the message. The following code is for illustration purposes only, and some of the `SimpleProcessor` code has been omitted.
    package com.vordel.example.filter;

    import java.io.ByteArrayInputStream;
    import java.io.IOException;

    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.NodeList;

    import com.vordel.circuit.Circuit;
    import com.vordel.circuit.CircuitAbortException;
    import com.vordel.circuit.Filter;
    import com.vordel.circuit.Message;
    import com.vordel.circuit.MessageProcessor;
    import com.vordel.circuit.MessageProperties;
    import com.vordel.es.EntityStore;
    import com.vordel.mime.Body;
    import com.vordel.mime.ContentType;
    import com.vordel.mime.HeaderSet;
    import com.vordel.mime.XMLBody;
    import com.vordel.trace.Trace;

    /**
     * This Processor acts as a simple Addition Web Service.
     * It extracts two parameters from a SOAP message and adds them together.
     * The result is then returned to the client.
     * The incoming message is expected in the following format:

    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <Add xmlns="http://startvbdotnet.com/web/">
          <a>1</a>
          <b>1</b>
        </Add>
      </soap:Body>
    </soap:Envelope>

     The SimpleFilter contains the local name of the two parameters (a
     and b), and contains the namespace that these elements belong to
     (http://startvbdotnet.com/web/).
     */
    public class SimpleProcessor extends MessageProcessor {

         /**
         * This method attaches the Filter to the Processor object.
         * This is called at startup and on every refresh.
         * This should contain server-side config/initialization.
         * For example, if this filter is required to establish
         * connections to any 3rd party products/servers, the
         * connection setup should be done here.
         * @param ctx Configuration context for the filter.
         * @param entity The Entity object
         */
        public void filterAttached(FilterConfigureContext ctx,
                                    com.vordel.es.Entity entity)
                                    throws EntityStoreException {
            // nothing to do here for initialisation
            super.filterAttached(ctx, entity);
        }

        /**
         * The invoke method performs the filter processing.
         * @param c The circuit
         * @param message The message
         * @return true or false.
         */
        public boolean invoke(Circuit c, Message message)
          throws CircuitAbortException {

            try {
                // Get the incoming request message as a DOM
                Document doc = getDOM(message);

                // Default result
                String result = "UNKNOWN";

                // Cast the filter member variable to a SimpleFilter so that
                // you may access the values stored in the SimpleFilter's
                // fields (for example, param1, param1Namespace, and so on).
                SimpleFilter f = (SimpleFilter)filter;

                // Look into the DOM to get the two parameters.
                // Get the 1st parameter
                NodeList param1 =
                    doc.getElementsByTagNameNS(f.param1Namespace, f.param1);
                if (param1 == null || param1.getLength() <= 0)
                    throw new CircuitAbortException(
                        "Could not find " + f.param1 + "in message");
                // Get the value passed in the 1st parameter
                String a = getElementContent((Element)param1.item(0));

                // Get the 2nd parameter
                NodeList param2 =
                    doc.getElementsByTagNameNS(f.param2Namespace, f.param2);
                if (param2 == null || param2.getLength() <= 0)
                    throw new CircuitAbortException(
                        "Could not find " + f.param2 + "in message");

                // Get the value of the 2nd parameter
                String b = getElementContent((Element)param2.item(0));

                // Calculate the result by adding the two parameter values
                result =
                    Integer.toString(Integer.parseInt(a) + Integer.parseInt(b));

                // Set the response by setting the content body
                // to be the response
                HeaderSet responseHeaders = new HeaderSet();
                responseHeaders.putString("Content-Type", "text/xml");
                StringBuffer response = new StringBuffer(RESPONSE_START);
                response.append(result);
                response.append(RESPONSE_END);
                Body convertedBody =
                    Body.create(responseHeaders, new ContentType("text/xml"),
                        new ByteArrayInputStream(
                            response.toString().getBytes()));
                message.setProperty(
                    MessageProperties.CONTENT_BODY, convertedBody);

                return true;
            }
            catch (IOException exp) {
                Trace.error("IOException in SimpleProcessor: " + exp.getMessage());
                return false;
            }
        }
    }
Processor Methods There are two important methods that must be implemented by every Processor: the `filterAttached` method and the `invoke` method. The `filterAttached` method associates an appropriate Filter class with the Processor. The Processor can then access the configuration data stored in the Filter class. In this case, the `SimpleProcessor` attaches to the `SimpleFilter` class. The `filterAttached` method should contain any server-side initialization or configuration that is to be performed by the Filter, such as connecting to third-party products or servers. The `invoke` method is responsible for using the data stored in the attached Filter class to perform the message processing. This method is called by the server as it executes the series of filters in any given policy. In the case of the `SimpleFilter`, the `invoke` method extracts the values of the `<a>` and `<b>` elements from the SOAP message, and adds the two values together. The result is then returned to the client in a templated SOAP response. It is important to note that the `invoke` method can have the following possible results:
Result | Description
`True` | If the filter processed the message successfully (for example, successful authentication, schema validation passed, and so on), the `invoke` method should return a true result, meaning that the next filter on the success path for the filter is invoked.
`False` | If the filter's processing fails (for example, the user was not authenticated, message failed integrity check, and so on), the `invoke` method should return false, meaning that the next filter on the failure path for the filter is invoked.
`CircuitAbortException` | If for some reason the filter cannot process the message at all (for example, if it can not connect to an Identity Management server to authenticate a user), it should throw a `CircuitAbortException`. If a `CircuitAbortException` is thrown in a policy, the designated Fault Processor (if any) is invoked instead of any successive filters on either the success or failure paths.
Now that you have a class to encapsulate the configuration data and another class to act on that data, it is now time to create some GUI classes where the user can configure the fields stored in the Filter class.
## Step 4: Create Policy Studio Classes
The next step involves writing two GUI classes so that the fields defined in the `SimpleFilter` type definition can be configured. When the GUI classes and resources have been built, the visual components can be used in the Policy Studio to configure the Filter and add it to a policy. SimpleFilter GUI Classes and Resources The following table describes the GUI classes and resources that relate to the `SimpleFilter`:
Class or Resource | Description
`SimpleFilterUI.java` | This class is used to list the pages that are involved in a Filter's configuration screen. Each Filter has at least two pages: the main configuration page, and a page where log messages related to the filter can be customized. This class is returned by the `getConfigPanelClass` method of the `SimpleFilter` class.
`SimpleFilterPage.java` | This class defines the layout of the visual fields on the Filter's main configuration screen. For example, there are four text fields on the configuration screen for the `SimpleFilter` corresponding to the four fields defined in the entity's type definition.
`resources.properties` | This file contains all text that is displayed in the GUI configuration screen (for example, dialog titles, field names, and error messages). This means that the text can be customized or internationalized easily without the need for code change.
`simple.gif` | This image file is used as the icon to identify the Filter in the Management Console, and is displayed in the Filter Palette.
This step first looks at the `SimpleFilterUI` class, which is returned by the `getConfigPanelClass` method of the `SimpleFilter` class. It is responsible for the following: Listing the configuration pages that make up the interface for the filter Naming the category of filters to which this filter belongs Specifying the name of the images to use as the icons/images for this filter SimpleFilterUI Class The code for the `SimpleFilterUI` is as follows:
    package com.vordel.example.filter.simple;

    import java.util.Vector;

    import org.eclipse.jface.resource.ImageDescriptor;
    import org.eclipse.swt.graphics.Image;

    import com.vordel.client.manager.Images;
    import com.vordel.client.manager.filter.DefaultGUIFilter;
    import com.vordel.client.manager.wizard.VordelPage;

    /**
     * Filter configuration GUI for 'Simple' example filter.
     * This class shows how to code simple text fields for configuring a
     * custom filter.
     */
    public class SimpleFilterUI
        extends DefaultGUIFilter
    {
        /**
         * Add the pages you want to show in the configuration wizard for the filter.
         */
        public Vector<VordelPage> getPropertyPages() {
            Vector<VordelPage> pages = new Vector<VordelPage>();

            // Add the panel for configuring the specific fields
            pages.add(new SimpleFilterPage());

            // Add the page which allows the user to set the log strings for the
            // audit trail, for the pass/fail/error cases
            pages.add(createLogPage());

            return pages;
        }

        /**
         * Set the categories in which you want to display this Filter. The
         * categories define the sections of the palette in which the Filter
         * appears. The values returned should be the localized name of the
         * palette section, so ensure that the property is defined in the
         * resources.properties in this class' package. You will add this
         * file to the "Example Filters" category.
         */
        public String[] getCategories() {
            return new String[]{_("FILTER_GROUP_EXAMPLE")};
        }

        /*
         *  Register our custom images with the image registry
         */
        private static final String IMAGE_KEY = "simpleFilter";
        static {
            Images.getImageRegistry().put(IMAGE_KEY,
                    Images.createDescriptor(SimpleFilterUI.class, "simple.gif"));
        }

        /**
         *  The icon image needs to be added in images.properties in com.vordel.client.manager
         *  the id used there is used as a reference here.
         *  Use this method to get image id for the small icon image in Images.get(id), etc.
         */
        public String getSmallIconId() {
            return IMAGE_KEY;
        }

        /**
         * Implement this method if you want to display a non-default image
         * for your filter in the circuit editor canvas and navigation tree.
         */
        public Image getSmallImage() {
            return Images.get(IMAGE_KEY);
        }

        /**
         * Implement this method to display a non-default icon for your filter in
         * the palette.
         */
        public ImageDescriptor getSmallIcon() {
            return Images.getImageDescriptor(IMAGE_KEY);
        }
    }
SimpleFilterUI Methods The following table describes the important methods:
Method | Description
public Vector getPropertyPages() | Initializes a Vector of the Pages that makeup the total configuration screens for this Filter. Successive Pages are accessible by clicking the Next button on the Policy Studio configuration screen.
public String[] getCategories() | This method returns the names of the Filter categories that this Filter belongs to. The Filter is displayed under these categories in the Filter Palette in the Policy Studio. The `SimpleFilter` is added to the Example Filters category.
public Image getSmallImage() | The default image for the Filter, which is registered in the static block in the code above, can be overridden by returning a different image here.
public ImageDescriptor getSmallIcon() | The default icon for the Filter can be overridden by returning a different icon here.
A Page only represents a single configuration screen in the Policy Studio. You can chain together several Pages to form a series of configuration screens that together make up the overall configuration for a given Filter. By default, all Filters consist of two pages: one for the configuration fields for the Filter, and the other to allow per-Filter logging. However, there is no reason why more Pages can not be chained together. Successive Pages should be added to the configuration in the `getPropertyPages` method. From looking at the `getPropertyPages` method of the `SimpleFilterUI`, it is clear that the `SimpleFilterPage` class forms one of the configuration screens (or pages) for the `SimpleFilter` filter. The `SimpleFilterPage` class is responsible for the layout of all the input fields that make up the configuration screen for the `SimpleFilter`. SimpleFilterPage Class The code for the `SimpleFilterPage` class is shown below:
    package com.vordel.example.filter.simple;

    import org.eclipse.swt.SWT;
    import org.eclipse.swt.layout.GridLayout;
    import org.eclipse.swt.widgets.Composite;

    import com.vordel.client.manager.wizard.VordelPage;

    public class SimpleFilterPage extends VordelPage
    {
        /**
         * Create the configuration page. Set the title and description
         * here. The title and description are maintained in the
         * resources.properties file for customization and
         * internationalization purposes.
         */
        public SimpleFilterPage() {
            // Call the super constructor with a unique name for this
            // page to bind it with its corresponding wizard.
            super("simplePage");
            setTitle(_("SIMPLE_PAGE"));
            setDescription(_("SIMPLE_PAGE_DESCRIPTION"));
            setPageComplete(false);
        }

        /**
         * Get the unique identifier for the help page for this filter.
         * The id-to-page mapping is maintained in the
         * '/docs/res/help.jhm' file. The URL for the page to describe
         * the filter should be relative to the '/docs' directory.
         */
        public String getHelpID() {
            return "simple.help";
        }

        /**
         * Any post-processing of the configuration values can happen
         * here, before they are persisted to the Entity Store. If the
         * configuration is not complete and valid, notify the user here
         * with a dialog box and return false here, otherwise return true.
         *
         * @see com.vordel.client.manager.util.MsgBox
         */
        public boolean performFinish() {
            // Simple mutually independent values here, no checking required,
            // so return true
            return true;
        }

        /**
         * Create the main control for the Filter configuration dialog.
         * This will house the text fields for setting the particular
         * Field Values in the Entity.
         */
        public void createControl(Composite parent) {
            // Create a Panel with two columns
            GridLayout layout = new GridLayout();
            layout.numColumns = 2;
            Composite container = new Composite(parent, SWT.NULL);
            container.setLayout(layout);

            // Add controls to populate the appropriate Entity Fields
            // You use the localization keys for the field names and
            // descriptions which will map to entries in the
            // resources.properties file.
            createLabel(container, "SF_NAME");
            createTextAttribute(container, "name", "SF_NAME_DESC");

            createLabel(container, "SF_PARAM1");
            createTextAttribute(container, "param1", "SF_PARAM1_DESC");

            createLabel(container, "SF_PARAM1NS");
            createTextAttribute(container, "param1Namespace", "SF_PARAM1NS_DESC");

            createLabel(container, "SF_PARAM2");
            createTextAttribute(container, "param2", "SF_PARAM2_DESC");

            createLabel(container, "SF_PARAM2NS");
            createTextAttribute(container, "param2Namespace", "SF_PARAM2NS_DESC");

            // Finish up the page definition
            setControl(container);
            setPageComplete(true);
        }
    }
SimpleFilterPage Methods There are four important interface methods that must be implemented in this class:
Method | Description
`public SimpleFilterPage()` | The constructor performs some basic initialization, such as setting a unique ID for the page and setting the title and description for the page. The text representing the page title and description are kept in the `resources.properties` file so that they can be localized or customized easily, if necessary.
`public String getHelpID()` | This method is called by the Policy Studio help system. There is a Help button on every configuration page in the Policy Studio. When this button is pressed, the help system is invoked. Every page has a help ID (for example, `simple.help`) associated with it, which is mapped to a help page. This mapping is defined in the `/plugins/com.vordel.rcp.policystudio.resources_(version ...)/contexts.xml` file under the directory where you have installed Policy Studio, for example:
                      <context id="simple_help">
                        <description>>Simple filter test</description>
                        <topic label="Simple Filter" href="html/common/tutorials/general_filter.html"/>
                      </context>
Please note a dot in a help ID is replaced by underscore in the `contexts.xml` file as in the example above. All URLs specified in the `contexts.xml` file are relative from the `/plugins/com.vordel.rcp.policystudio.resources_(version ...)` folder of your Policy Studio installation. You can add the lines from the example above to the `contexts.xml` file now, and you will check that the help page works at the end of this tutorial.
`public boolean performFinish()` | This method gives you the chance to process the user-specified data before it is submitted to the Entity Store. For example, any validation on the data should be added to this method.
`public void createControl(Composite parent)` | This method is responsible for creating and ordering the input fields on the configuration page. Again, localization keys from the `resource.properties` file are used to give labels for the input fields. It is important to note that the `createTextAttribute` takes a String as its second parameter, which corresponds to a field defined for an entity (for example, `param`, `param1Namespace`, `param2`, and `param2Namespace` are all defined in the `SimpleFilter` entity type. When the user submits the values entered in these fields, the values are set to the corresponding fields in the entity instance in the Entity Store.
resources.properties File Both the `SimpleFilterUI` and the `SimpleFilterPage` classes use localized keys for all text that is displayed on the configuration screen. This makes it a trivial task to localize or customize all text that is displayed in the Policy Studio. The localization keys and their corresponding strings are stored in the `resources.properties` file, which takes the following format:
    # Palette category for example filters
    FILTER_GROUP_EXAMPLE=Example Filters

    # Title and Description for the SimpleFilter
    SIMPLE_PAGE=Simple Filter Configuration
    SIMPLE_PAGE_DESCRIPTION=Configure parameter values for the Simple Filter

    #
    # Field labels and descriptions
    #
    SF_NAME=Filter Name:
    SF_NAME_DESC=The name of the Simple Filter
    SF_PARAM1=Parameter 1
    SF_PARAM1_DESC=the first parameter
    SF_PARAM1NS=Parameter 1 Namespace
    SF_PARAM1NS_DESC=the first parameter namespace field
    SF_PARAM2=Parameter 2
    SF_PARAM2_DESC=the second parameter
    SF_PARAM2NS=Parameter 2 Namespace
    SF_PARAM2NS_DESC=the second parameter namespace field
The final resource is the `simple.gif` image file, which is displayed as the icon for the `SimpleFilter` in the Policy Studio. You can see this icon a little later in this tutorial when you configure the `SimpleFilter`. Now that all classes and resources have been written, it is now time to build the relevant JAR files and incorporate them into the product.
## Step 5: Build Classes
You must perform the following steps to build the Java classes and resources described in the previous sections. Important Note: The classes must be built against a 1.6 JDK because this is used to build the Enterprise Gateway, which contains the JAR files for the Enterprise Gateway SDK API. Build the classes and associated resources into a JAR file using your chosen build technology. Place the new JAR in the `GW_HOME/ext/lib` directory, where `GW_HOME` refers to the root of your Enterprise Gateway installation. In the Policy Studio main menu, select Window -> Preferences -> Runtime Dependencies, and click Add to browse to the new JAR, and add it to the list (for example, `GW_HOME/ext/lib/VordelExampleFilters.jar`). Place any third-party JAR files used by your classes into the `GW_HOME/ext/lib`, and add them to the list of Runtime Dependencies in the Policy Studio. Restart both the server and the Policy Studio.
Runtime Dependencies
For an example of building the `SimpleFilter` classes, see the Ant `build.xml` file supplied in the `SDK_HOME/example/filter/src` directory, where `SDK_HOME` points to the root of your SDK installation. The Ant file builds the `SimpleFilter` classes and packages all associated resources into the `VordelExampleFilters.jar` file. You must then place this file into the `GW_HOME/ext/lib` folder, and add it to the Runtime Dependencies in the Policy Studio Preferences. When both the server and the Policy Studio boot up, they automatically pick up the new JAR file. In the remaining steps of this tutorial, you can see how to configure a policy that includes the `SimpleFilter` and then test its functionality.
## Step 6: Load TypeDocs
1. You must now register the type definition for the `SimpleFilter` with the Entity Store using the Policy Studio. When the entity type has been registered, it is guaranteed that any time the server needs to create an instance of the `SimpleFilter`, the instance contains the correct fields with the appropriate types. Register using the Policy Studio To register the type definition sing the Policy Studio, perform the following steps: Start the Policy Studio and connect to the Enterprise Gateway. The following screen is displayed:
   Policy Studio Dashboard
2. Select Window -> Show View -> Profile Repository from the main menu, and you should see a screen similar to the following:
   Profile Repository
4. Create a copy of the active configuration. To do this, expand the Core Configurations tree node, and right-click the active configuration (for example, Default Configuration). Select Create via Copy in the context menu, and give the new configuration a meaningful name (for example, `Custom Filter Config`). Right-click the new configuration, and select Edit from the context menu. You are asked to enter a passphrase. If this has not been changed from the default, you can leave the field blank and proceed. This displays the Profile Editor tab with Custom Filter Config as a root node. Right-click this root node, and select Import Custom Filter Types from the menu.
   Import Custom Filter
5. Browse to the location of the `sampleTypeSet.xml` file, which is located in the `/filter` directory of your Oracle Enterprise Gateway installation. A TypeSet file is used to group together one or more TypeDocs so that multiple TypeDocs can be added to the Entity Store in batch mode. The `sampleTypeSet.xml` file is displayed as follows:
       <typeSet>
           <!-- SimpleFilter TypeDoc -->
          <typedoc file="SimpleFilter.xml"/>
       </typeSet>
6. After selecting the TypeSet, the workspace refreshes. To verify that the filter is available, navigate to a pre-existing policy, and you should see the Example Filters category in the palette, with the filters contained inside.
   Verify Filter Install
1. Right click the configuration, and commit this version. From now on, any further revisions of this version, or configurations copied from this configuration contain the new filter types. Click the Deployment Details tab on the Dashboard, and select the running process and the core configuration. You can now deploy the new `Custom Filter Config` with the latest version containing the new types. Click the Deploy button at the bottom right of the screen. Verifying using the Entity Explorer Another way to verify that your new filter has been installed is to use the Entity Explorer. You can use the Entity Explorer tool for browsing the entity types and entity instances that have been registered with the Entity Store. To verify that the filter has been installed, perform the following steps: Start the Entity Explorer from the `/bin` directory of your installation using the `esexplorer` startup script. The Entity Explorer is displayed as follows:
   Entity Explorer
2. There are two main tabs on the Entity Store's interface: Entities and Types. The Types tab lists all currently defined entity types that have been registered with the Entity Store, while the Entities tab lists all the instances of entities that have been committed to the Entity Store (for example, configured filters). You must first point the Entity Explorer at the management interface exposed by a running instance of the Enterprise Gateway. Right-click the Entity Stores node in the Entity Hierarchy tree:
   Connecting to an Entity Store
   The Connect to an Entity Store dialog is displayed as follows:
   Connect to an Entity Store
6. The Enterprise Gateway exposes a management service that interfaces to the underlying Entity Store. This is the preferred method of managing the Entity Store. You can now start the Enterprise Gateway (which connects to the Entity Store), and point the Entity Explorer at the management service exposed by the Enterprise Gateway. Start the Enterprise Gateway from the `/bin` directory of your product installation. You can now configure the Entity Explorer to talk to the management service exposed by the Enterprise Gateway. By default, this service is available at the following URL, where `HOST` refers to the host name or IP address of the machine on which the Enterprise Gateway is running: `http://HOST:8090/configuration/policies`. Enter this address in the URL field of the Connect to an Entity Store dialog. If you have not already changed the default username and password for the entity store, use the default username `admin` with password `changeme`. Otherwise, specify the alternative username and password in the fields provided. Click OK to connect to the management service on the Enterprise Gateway. A log message is displayed in the Log panel at the bottom right corner of the screen to confirm that you are connected to the Enterprise Gateway at the specified URL. Expand the Entity Store filename, and then expand the System Components node to display the list of entity instances stored in the Entity Store:
   Instances of Entities Stored in the Entity Store
7. Click the Types tab, expand the node representing the Enterprise Gateway's management interface, (for example, `http://my_host:8090/configuration/policies`), and expand the Entity node to display the list of registered entity types. Each of these entity types has a corresponding type definition. Expand the Filter node, and click the SimpleFilter entity type in the tree. The names and data types of the fields for this entity type can be seen under the Details tab on the right of the Entity Explorer. To view the type definition for this entity, click the XML tab. These details should match the filter that has just been added.
   SimpleFilter Loaded in the Entity Store
The Entity Store is now aware of the `SimpleFilter` type. You can now create an instance of a Filter class that encapsulates the fields defined in the `SimpleFilter` type. The remaining steps in this tutorial show how to configure a policy that includes the `SimpleFilter`, and then tests its functionality.
## Step 7: Construct a Policy
This section first shows how to build a simple policy that echoes messages back to the client. The next step then adds the SimpleFilter to the policy. You can build policies using the Policy Editor in the Policy Studio. To build a policy, you can drag message filters from the filters palette on the left on to the policy canvas on the right. You can then link these filters using success or failure paths to create a network of filters. The following screenshot shows the Policy Editor screen:
Circuit Editor
7. The policy canvas is the large blank area on the screen, while the filters palette is the area on the right that contains the filters. Message filters are grouped together by category (for example, all the content-based filters are displayed together in one group, while all the authentication filters are displayed in a different group). You can build policies by dragging these filters and dropping them on to the canvas. Important Note: If you have followed the steps outlined above, you can see a new category of filters named Example Filters in the filter palette. The Example Filters category is expanded in the example screenshot. Creating the Policy To create a policy, perform the following steps: Right-click Policies in the tree view to the left of the Policy Studio, and select Add Policy. Enter Circuit 1 as the name of the new policy in the Policy dialog. This example creates a policy containing only one filter: the Reflect filter. This filter simply echoes the client message back to the client. The Reflect filter is found in the Utility filter group. Drag this filter on to the editor. Enter a name for the filter (or use the default) in the field provided. Select the default value (`200`) for the HTTP response status code, and click Finish. The policy needs to have a start filter, so right-click the Reflect filter, and choose Set as Start. You must now configure the Process to invoke the new policy. On the Services tab in Policy Studio, select the Process (for example Enterprise Gateway) -> Default Services. Right-click Path: /, and select Edit. Enter the following values on the Configure Relative Path dialog: Relative Path: Keep `/` in this field, meaning that the Process invokes the policy selected below for all requests received on this path. Policy: Select `Circuit 1` to configure the server to send all requests received on the path configured above to our newly configured policy. To force the server to pick up the new configuration, you must deploy the configuration to the server. Click the Deploy or press F6. To test this, start up the Service Explorer testing tool (distributed separately):
   Test Client
Assuming your HTTP interface is listening on port 8080, you can configure Service Explorer to send a request to: `http://HOST:8080/`, where `HOST` is the hostname or IP address of the machine on which the server is running. Note that you send to `/` because, earlier, you configured the firewall to filter requests received on this relative path. Copy any SOAP message into the Request panel of Service Explorer. Click the triangular green Send button to send the message to the server, which echoes it back to the client using the Reflect filter configured earlier. When the message has been returned to Service Explorer, try changing the message slightly to assure yourself that the correct message is actually being returned. Finally, it is time to add the `SimpleFilter` to the policy, and to test its functionality.
## Step 8: Configure the SimpleFilter
The final section of this tutorial adds the `SimpleFilter` to the policy built in the previous section. Currently, the policy consists of only one filter, the Reflect filter:
Circuit 1 Example
The SimpleFilter is found in the Example Filters category of the Filter Palette on the Policy Studio.
Example Filters Category
1. Configuring the Filter To configure the new filter, perform the following steps: Drag and drop the SimpleFilter on to the policy canvas. The configuration screen is displayed as follows:
   Simple Filter
4. Because the type definition for the `SimpleFilter` entity contained default values, the input fields on the configuration screen are pre-populated with these default values. Before completing the configuration, make sure the help system is working correctly. Remember that in Step 4 of this tutorial, you added a mapping to the `contexts.xml` file (in the `/plugins/com.vordel.rcp.policystudio.resources_(version ...)` folder of your Policy Studio installation.) If you have not done so yet, this is explained in Step 4. After restarting Policy Studio, you can try clicking the Help button while editing the `SimpleFilter` configuration. Right-click the Simple node, and select Set as Start from the context menu. Connect the Simple node to the Reflect node with a success path. You can do this by clicking the Success Path arrow, and then clicking the Simple node, followed by clicking the Reflect node. The policy is now displayed as follows:
   Policy with SimpleFilter and Reflect
6. To force the server to pick up the new configuration, you must refresh the server. Click the Deploy button in Policy Studio (or press F6). You can now test the configuration to make sure that it performs as expected (that it can correctly add the two numbers together). Load the appropriate SOAP message into the Service Explorer by selecting the File -> Samples -> Add two numbers menu option. The following SOAP message is loaded:
       <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                      xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
         <soap:Body>
           <Add xmlns="http://startvbdotnet.com/web/">
             <a>1</a>
             <b>2</b>
           </Add>
         </soap:Body>
       </soap:Envelope>
Important Note: Note the presence of the `<a>` and `<b>` elements in the SOAP message, and the namespace declaration in the `<Add>` element. These elements and their corresponding namespaces match the values configured in the SimpleFilter earlier. Make sure to send the message to the same address as before by entering `http://localhost:8080/` as the URL. The Wsdl field is not needed and can be removed. Press the Run (Send) button when you have done this to send the message to the server. The following response is returned to Service Explorer:
    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance\"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <soap:Body>
        <AddResponse xmlns="http://startvbdotnet.com/web/">
          <AddResult>3</AddResult>
        </AddResponse>
      </soap:Body>
    </soap:Envelope>
The value of the `<AddResult>` element is `3`, which indicates that the newly added filter has worked successfully.
## Conclusion
This tutorial described a working example of how to write a message processing filter using the Oracle Enterprise Gateway and how to integrate it into a policy. You should now try to build your own filter by following a similar sequence of steps to those outlined in this tutorial. If you have any queries on the content of this document, please contact the Support Team with your questions.