Developing a Catalog Plugin

Developing a Catalog Plugin

Prerequisites

  1. Understand the desired component for development as described in the DDF Catalog section.
  2. Have an IDE and the ability to create OSGi bundles.
  3. Understand the Use of the Whiteboard Design Pattern section and how to publish services to the OSGi service registry.

Overview

Plugins extend the functionality of the Catalog Framework by performing actions at specified times during a transaction.  Plugins can be Pre-Ingest, Post-Ingest, Pre-Query, Post-Query, Pre-Subscription, Pre-Delivery, Pre-Resource, or Post-Resource.  By implementing these interfaces, actions can be performed at the desired time.

View the Catalog Framework section of the Integrator's Guide for more information on how these plugins fit in the ingest and query flows.

 

Creating New Plugins

Implement Plugin Interface

The following types of plugins can be created:

Plugin TypePlugin InterfaceDescriptionExample
Pre-Ingestddf.catalog.plugin.PreIngestPlugin

Runs prior to the Create/Update/Delete method is

sent to the CatalogProvider

metadata validation services
Post-Ingestddf.catalog.plugin.PostIngestPlugin

Runs after the Create/Update/Delete method being

sent to the CatalogProvider

EventProcessor for processing and

publishing event notifications to subscribers

Pre-Query ddf.catalog.plugin.PreQueryPlugin

Runs prior to the Query/Read method being

sent to the Source

An example is not included with DDF
Post-Query ddf.catalog.plugin.PostQueryPlugin

Runs after results have been retrieved from the query

but before they are posted to the Endpoint

An example is not included with DDF
Pre-Subscription ddf.catalog.plugin.PreSubscriptionRuns prior to a Subscription being created or updatedModify a query prior to creating a subscription
Pre-Delivery ddf.catalog.plugin.PreDeliveryPlugin

Runs prior to the delivery of a Metacard when an

event is posted

Inspect a Metacard prior to delivering it to the Event Consumer
Pre-Resourceddf.catalog.plugin.PreResourceRuns prior to a Resource being retrievedAn example is not included with DDF
Post-Resource ddf.catalog.plugin.PostResource

Runs after a Resource is retrieved, but before it is

sent to the Endpoint

Verification of a resource prior to returning to a client

Implementing any of the plugins follows a similar format:

  1. Create a new class that implements the specified plugin interface.
  2. Implement the required methods.
  3. Create OSGi descriptor file to communicate with the OSGi registry (described in the Working with OSGi  section).
    1. Import DDF packages
    2. Register plugin class as service to OSGi registry
  4. Deploy to DDF

Please view the Javadoc for more information on all Requests and Responses in the ddf.catalog.operation and ddf.catalog.event packages.

Pre-Ingest

  1. Create java class that implements PreIngestPlugin

    public class SamplePreIngestPlugin implements ddf.catalog.plugin.PreIngestPlugin
    
  2. Implement the required methods

    public CreateRequest process(CreateRequest input) throws PluginExecutionException;
    
    public UpdateRequest process(UpdateRequest input) throws PluginExecutionException;
    
    public DeleteRequest process(DeleteRequest input) throws PluginExecutionException;
    
  3. Import the DDF interface packages to the bundle manifest (in addition to any other required packages):

    Import-Package: ddf.catalog,ddf.catalog.plugin
    
  4. Export the service to the OSGi registry:

    Blueprint descriptor example
    <service ref="[[SamplePreIngestPlugin ]]" interface="ddf.catalog.plugin.PreIngestPlugin" />

Post-Ingest

  1. Create java class that implements PostIngestPlugin

    public class SamplePostIngestPlugin implements ddf.catalog.plugin.PostIngestPlugin
    
  2. Implement the required methods

    public CreateResponse process(CreateResponse input) throws PluginExecutionException; 
    
    public UpdateResponse process(UpdateResponse input) throws PluginExecutionException; 
    
    public DeleteResponse process(DeleteResponse input) throws PluginExecutionException;
    
  3. Import the DDF interface packages to the bundle manifest (in addition to any other required packages):

    Import-Package: ddf.catalog,ddf.catalog.plugin
    
  4. Export the service to the OSGi registry:

    Blueprint descriptor example
    <service ref="[[SamplePostIngestPlugin ]]" interface="ddf.catalog.plugin.PostIngestPlugin" />
    

 

Pre-Query

  1. Create java class that implements PreQueryPlugin

    public class SamplePreQueryPlugin implements ddf.catalog.plugin.PreQueryPlugin
    
  2. Implement the required method

    public QueryRequest process(QueryRequest input) throws PluginExecutionException, StopProcessingException;
    

    An example of an implementation of a PreQueryPlugin.process() method's business logic is shown below and can be found in the DDF SDK in the sample-plugins project.

    How to build PreQueryPlugin filter
    FilterDelegate<Filter> delegate = new CopyFilterDelegate(filterBuilder);
    try {
        // Make a defensive copy of the original filter (just in case anyone else expects
        // it to remain unmodified)
        Filter copiedFilter = filterAdapter.adapt(query, delegate);
                        
        // Define the extra query clause(s) to add to the copied filter
        // This will create a filter with a search phrase of:
        //     ((("schematypesearch") and ("test" and ({/ddms:Resource/ddms:security/@ICISM:releasableTo}:"ISAF" or {/ddms:Resource/ddms:security/@ICISM:releasableTo}:"CAN")))
        Filter contextualFilter = filterBuilder.attribute(Metacard.ANY_TEXT).like().text("test");
        Filter releasableToFilter1 = filterBuilder.attribute("/ddms:Resource/ddms:security/@ICISM:releasableTo").like().text("ISAF");
        Filter releasableToFilter2 = filterBuilder.attribute("/ddms:Resource/ddms:security/@ICISM:releasableTo").like().text("CAN");
        Filter orFilter = filterBuilder.anyOf(releasableToFilter1, releasableToFilter2);
        Filter extraFilter = filterBuilder.allOf(contextualFilter, orFilter);
                        
        // AND this PreQueryPlugin's extra query clause(s) to the copied filter
        Filter modifiedFilter = filterBuilder.allOf(copiedFilter, extraFilter);
                        
        // Create a new QueryRequest using the modified filter and the attributes from the original query
        QueryImpl newQuery = new QueryImpl(modifiedFilter, query.getStartIndex(), 
            query.getPageSize(), query.getSortBy(), 
            query.requestsTotalResultsCount(), query.getTimeoutMillis());
        newQueryRequest = new QueryRequestImpl(newQuery, input.isEnterprise(), input.getSourceIds(), input.getProperties());
    } 
    catch (UnsupportedQueryException e) 
    {
        throw new PluginExecutionException(e);
    }
  3. Import the DDF interface packages to the bundle manifest (in addition to any other required packages):

    Import-Package: ddf.catalog,ddf.catalog.plugin
    
  4. Export the service to the OSGi registry:

    Blueprint descriptor example
    <service ref="[[SamplePreQueryPlugin]]" interface="ddf.catalog.plugin.PreQueryPlugin" />
    

Post-Query

  1. Create java class that implements PostQueryPlugin

    public class SamplePostQueryPlugin implements ddf.catalog.plugin.PostQueryPlugin
    
  2. Implement the required method

    public QueryResponse process(QueryResponse input) throws PluginExecutionException, StopProcessingException;
    
  3. Import the DDF interface packages to the bundle manifest (in addition to any other required packages):

    Import-Package: ddf.catalog,ddf.catalog.plugin
    
  4. Export the service to the OSGi registry:

    Blueprint descriptor example
    <service ref="[[SamplePostQueryPlugin]]" interface="ddf.catalog.plugin.PostQueryPlugin" />
    

Pre-Delivery

  1. Create java class that implements PreDeliveryPlugin

    public class SamplePreDeliveryPlugin implements ddf.catalog.plugin.PreDeliveryPlugin
    
  2. Implement the required methods

    public Metacard processCreate(Metacard metacard) throws PluginExecutionException, StopProcessingException;
    
    public Update processUpdateMiss(Update update) throws PluginExecutionException, StopProcessingException;
    
    public Update processUpdateHit(Update update) throws PluginExecutionException, StopProcessingException;
    
    public Metacard processCreate(Metacard metacard) throws PluginExecutionException, StopProcessingException;
  3. Import the DDF interface packages to the bundle manifest (in addition to any other required packages):

    Import-Package: ddf.catalog,ddf.catalog.plugin,ddf.catalog.operation,ddf.catalog.event
    
  4. Export the service to the OSGi registry:

    Blueprint descriptor example
    <service ref="[[SamplePreDeliveryPlugin]]" interface="ddf.catalog.plugin.PreDeliveryPlugin" />
    

Pre-Subscription

  1. Create java class that implements PreSubscriptionPlugin

    public class SamplePreSubscriptionPlugin implements ddf.catalog.plugin.PreSubscriptionPlugin
    
  2. Implement the required method

    public Subscription process(Subscription input) throws PluginExecutionException, StopProcessingException;
    

    An example of an implementation of a PreSubscriptionPlugin.process() method's business logic is shown below and can be found in the DDF SDK in the sample-plugins project.

    PreSubscriptionPlugin example
    FilterDelegate<Filter> delegate = new CopyFilterDelegate(filterBuilder);
    try {
        // Make a defensive copy of the original filter (just in case anyone else expects
        // it to remain unmodified)
        Filter copiedFilter = filterAdapter.adapt(input, delegate);
                    
        // Define the extra query clause(s) to add to the copied filter
        Filter extraFilter = filterBuilder.attribute("/ddms:Resource/ddms:security/@ICISM:releasableTo").like().text("CAN");
                    
        // AND the extra query clause(s) to the copied filter
        Filter modifiedFilter = filterBuilder.allOf(copiedFilter, extraFilter);
        		
        // Create a new subscription with the modified filter
         newSubscription = new SubscriptionImpl(modifiedFilter, input.getDeliveryMethod(),
            	input.getSourceIds(), input.isEnterprise());
    } 
    catch (UnsupportedQueryException e) 
    {
       throw new PluginExecutionException(e);
    }
  3. Import the DDF interface packages to the bundle manifest (in addition to any other required packages):

    Import-Package: ddf.catalog,ddf.catalog.plugin,ddf.catalog.event
    
  4. Export the service to the OSGi registry:

    Blueprint descriptor example
    <service ref="[[SamplePreSubscriptionPlugin]]" interface="ddf.catalog.plugin.PreSubscriptionPlugin" />
    

Pre-Resource

  1. Create java class that implements PreResourcePlugin

    public class SamplePreResourcePlugin implements ddf.catalog.plugin.PreResourcePlugin
    
  2. Implement the required method

    public ResourceRequest process(ResourceRequest input) throws PluginExecutionException, StopProcessingException;
    
  3. Import the DDF interface packages to the bundle manifest (in addition to any other required packages):

    Import-Package: ddf.catalog,ddf.catalog.plugin,ddf.catalog.operation
    
  4. Export the service to the OSGi registry:

    Blueprint descriptor example
    <service ref="[[SamplePreResourcePlugin]]" interface="ddf.catalog.plugin.PreResourcePlugin" />
    

Post-Resource

  1. Create java class that implements PostResourcePlugin

    public class SamplePostResourcePlugin implements ddf.catalog.plugin.PostResourcePlugin
    
  2. Implement the required method

    public ResourceResponse process(ResourceResponse input) throws PluginExecutionException, StopProcessingException;
    
  3. Import the DDF interface packages to the bundle manifest (in addition to any other required packages):

    Import-Package: ddf.catalog,ddf.catalog.plugin,ddf.catalog.operation
    
  4. Export the service to the OSGi registry:

    Blueprint descriptor example
    <service ref="[[SamplePostResourcePlugin]]" interface="ddf.catalog.plugin.PostResourcePlugin" />