BES Aggregation

From OPeNDAP Documentation
Revision as of 22:03, 8 March 2009 by PatrickWest (talk | contribs)

By default there are no aggregation engines installed with the BES. But there is a mechanism to register your own aggregation engine. This page will discuss how to go about doing that.

1 How does aggregation work in the BES?

A request comes into the BES that references some containers, creates a definition using those containers adding constraints and specifying an aggregation engine to use and an aggregation command, and then a get command to grab the containers, constrain them, and then aggregate. The command would look something like this:

<?xml version="1.0" encoding="UTF-8"?>
<request reqID="some_unique_value" >
    <setContainer name="c1" space="catalog">/data/nc/</setContainer>
    <setContainer name="c2" space="catalog">/data/nc/</setContainer>
    <setContainer name="c3" space="catalog">/data/nc/</setContainer>
    <setContainer name="c4" space="catalog">/data/nc/</setContainer>
    <define name="d">
	<container name="c1">
	<container name="c2">
	<container name="c3">
	<container name="c4">
        <aggregate handler="someHandler" cmd="someCommand" />
    <get type="dods" definition="d" />

In order to the BES to perform the specified aggregation there must be an aggregation engine registered with the BES call someHandler. The command cmd is passed to the aggregation engine and is parsed by the engine. This command can be different from engine to engine, there are no requirements for the command.

2 Creating your Aggregation Handler

The first step is to create an aggregation class that inherits from BESAggregationServer. The minimum that must be defined in this new class is the following:

class MyAggregationServer : public BESAggregationServer
                       MyAggregationServer( string handler_name )
                              : BESAggregationServer( handler_name ) {} ;
    virtual            ~MyAggregationServer() {} ;

    virtual void       aggregate( BESDataHandlerInterface &dhi ) ;

    static BESAggregationServer *AggBuilder( string handler_name );

The value of the handler_name parameter will be someHandler. When a request comes in to aggregate, the BES takes that name and looks up a function in the aggregation factory with that name (someHandler) and calls that function. That function will return a new instance of BESAggregationServer. The function called will be AggBuilder. The function AggBuilder would look something liket his:

BESAggregationServer *
MyAggregationServer::AggBuilder( string handler_name )
    return new MyAggregationServer( handler_name ) ;

The only real method that you have to implement is the aggregate method. More on that later.

3 Registering your Aggregation Handler

You register your new aggregation handler with the Aggregation Factory BESAggFactory giving it the name that you want it to be referenced by in the define command (someHandler). What you are actually registering with the factory is a function that knows how to instantiate the new aggregation server. In the example above, MyAggregationServer::AggBuilder function is registered with the BESAggFactory. This should be done in your Module class' initialize method.

For example:

    BESDEBUG( "mydebug", "    adding " << modname << " aggregation" << endl )
    BESAggFactory::TheFactory()->add_handler( modname, MyAggregationServer::AggBuilder ) ;

Typically, the name of the aggregation engine is the same as the name of your module. In this example, modname would be "someHandler".

4 Writing your aggregate method