Contents
- Overview
- Policies, Filters, and Message Attributes
- Oracle API Gateway SDK Overview
- Tutorial Prerequisites
- Oracle API 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
Oracle API 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 the API Gateway's pluggable and extensible architecture to enhance the message processing capabilities of the API Gateway core processing engine.
This tutorial walks you through a step-by-step example of how to build a custom message filter using 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, it is important to explain exactly what are Oracle API Gateway filters, and how you can wire them together to create message processing policies.
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.
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.
For example, 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, see the API 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.
The Oracle API Gateway Software Development Kit (SDK) comprises three Java packages that provide programmatic access to Oracle API 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 API 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 API 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. |
You should read Oracle API Gateway Concepts to make sure you understand the concepts of policies and filters before continuing.
The Oracle API Gateway SDK requires a JDK 1.6, and is supported for the Windows, Linux, and Solaris packages.
The Oracle API Gateway SDK ships with a working example of a message
filter, called the SimpleFilter
, which 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 are written, you must build them, and add them to the server and client classpaths. The Oracle API Gateway SDK provides example classes. |
Step 6: Load TypeDocs | You must register the TypeDoc created for the filter in Step 1 with the Entity Store. |
Step 7: Construct a Policy | Construct a policy that echoes messages back to the client, and then adds the newly created filter to it. |
Step 8: Configure the SimpleFilter | Use the GUI component of the newly added filter to specify its configuration. Then test the functionality of the filter (and its configuration) using the Oracle API Gateway Explorer testing tool. |
All configuration data is stored as entities in the Oracle API 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
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 occur only once in 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.
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.
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.
Note | |
---|---|
This is the server runtime component of the filter that is returned by the
|
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
andb
), 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 policy 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.
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.
The next step involves writing two GUI classes that enable the fields
defined in the SimpleFilter
type definition to be
configured. When the GUI classes and resources are 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 for the
SimpleFilter
:
Class or Resource | Description |
---|---|
SimpleFilterUI.java |
This class lists 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 type definition.
|
resources.properties |
This file contains all text 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 needing to change code. |
simple.gif |
This image file is the icon that identifies 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's 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 policy 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-HTML page mapping is maintained in the following file: * <policy_studio_build>/plugins/ * com.vordel.client.rcp.common.resources_version/contexts.xml. */ 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, 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 include 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.
The following shows an example mapping in this file:
<context id="simple_help">
|
|||
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.
|
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 easy
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 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.
You must perform the following steps to build the Java classes and resources described in the previous sections.
Important | |
---|---|
The classes must be built against a 1.6 JDK because this is used to build the API Gateway, which contains the JAR files for the API Gateway SDK API.
|
Example Build File
For an example of building the SimpleFilter
classes, see the Apache Ant build.xml
file
supplied in the SDK_HOME/example/filter/src
directory, where SDK_HOME
points to the
root of your Oracle API Gateway SDK installation. For
more details, see the instructions in
SDK_HOME/example/readme.html
.
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 INSTALL_DIR/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. The remaining steps of this tutorial describe
how to configure a policy that includes the SimpleFilter
,
and then test its functionality.
You must now register the type definition for the SimpleFilter
with the Entity Store using the Policy Studio. When the entity type is registered,
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 using the Policy Studio, perform the following steps:
-
Start the Policy Studio, and connect to the API Gateway.
-
Select Window -> Show View -> Tag/Profile Manager from the main menu to display the Tag/Profile Manager tab.
-
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 Core 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.
-
Browse to the
sampleTypeSet.xml
file, which is located in theSDK_HOME/example/src/com/vordel/example/filter
directory. A TypeSet file is used to group together one or more TypeDocs. This enables multiple TypeDocs to be added to the Entity Store in batch mode. ThesampleTypeSet.xml
file includes the following:<typeSet> <!-- SimpleFilter TypeDoc --> <typedoc file="SimpleFilter.xml"/> </typeSet>
-
After selecting the TypeSet, the workspace refreshes. To verify that the filter is available, select an existing policy in the Policy Studio tree, and you should see the Example Filters category in the palette, which contains the new custom filters.
-
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 custom filter types.
-
Click the Deploy button in the toolbar to deploy the new
Custom Filter Config
with the latest version containing the new filter types.
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 theesexplorer
startup script. The Entity Explorer is displayed as follows: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 API Gateway. Right-click the Entity Stores node in the Entity Hierarchy tree:
The Connect to an Entity Store dialog is displayed as follows:
-
The API 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 API Gateway (which connects to the Entity Store), and point the Entity Explorer at the management service exposed by the API Gateway. Start the API 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 API 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 API 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 passwordchangeme
. Otherwise, specify the alternative username and password in the fields provided. -
Click OK to connect to the management service on the API 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 API 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:
-
Click the Types tab, and expand the node representing the API Gateway's management interface, (for example,
http://HOST:8090/configuration/policies
). -
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 are displayed under the Details tab on the right.
-
To view the type definition for this entity, click the XML tab. These details should match the filter that has just been added.
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.
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 Paths or Failure Paths to create a network of filters. The following screenshot shows the policy editor screen in the Policy Studio:
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 | |
---|---|
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 the Policies node in the tree view on 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 canvas.
-
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. Under the Listeners node in Policy Studio, select the Process (for example API 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 API Gateway Explorer testing tool (distributed separately):
-
Assuming your HTTP interface is listening on port 8080, you can configure API Gateway Explorer to send a request to:
http://HOST:8080/
, whereHOST
is the hostname or IP address of the machine on which the server is running.Note 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 API Gateway 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 API Gateway 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.
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:
The SimpleFilter is found in the Example Filters category of the Filter Palette on the Policy Studio.
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:
-
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 theSimpleFilter
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:
-
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 API Gateway 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 the presence of the |
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 API Gateway 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.
This tutorial described a working example of how to write a message processing filter using the Oracle API 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 Oracle Support Team with your questions (see Oracle Contact Details).