Previous Menu Next
Receiving Annotation requests and sending responses

To create an annotation server you derive a class from ECS_Annotater and override its receiveRequest() method. The work of receiving a request, dissassembling it, and constructing a response is all done within this method.

Requests are received by receiveRequest() as instances of the ECS_AnnoRequest class. Methods are provided to determine the source of the request, its expiry time, to obtain the request details, and for responding to the request.

The request details are encapsulated in an instance of the ECS_AnnoData class, which contains the list of data sent by the Annotation node. The list of data is in turn enclosed in an instance of the class ECS_AttrValueList.

Values are extracted from the ECS_AttrValueList using the methods getInteger(), getReal(), getBool(), and so on. Since you must know the type of an attribute before you can extract it, you call the method typeOfNthItem() to find out the data type of a specified element in the list (list elements are numbered from 1).

Repeated calls to the various get... methods on the ECS_AttrValueList are used to extract all the values needed to construct a response. After computing a result from the request, which may involve calling other processes such as querying a database, a response can then be assembled.

The response can be assembled in a variety of ways:

  • from a string containing an ECDL-like representation of the response
  • from an attribute value list of type EV_AttrValue
  • or from an instance of ECS_AttrValueList constructed using the appropriate set methods (setValue(), setList(), etc).

The constructed ECS_AnnoData response is then sent using the respond() method of the corresponding request instance, and the receiveRequest() method returns.

Source code sample:

.
.
.
class myServer : public ECS_Annotater
{
  public:
    myServer() { n = 0; m = 0; };
    int32 receiveRequest(ECS_AnnoRequest request);

  private:
    int32	n;
    int32	m;
};


int32 myServer::receiveRequest(ECS_AnnoRequest request)
{
    const ECS_AnnoData& data = request.getData();

    if ((data.size() == 2)
      && (data.typeOfNthItem(1) == EV_INTEGER)
      && (data.typeOfNthItem(2) == EV_INTEGER))
    {
        const int32* int1 = data.getInteger(1);
        const int32* int2 = data.getInteger(2);
	
	cout << "Server 1: - Received annotation request from "
	     << request.getAnnoNodeName() << " in circuit "
	     << request.getCircuitName()
	     << " (seq # = "
	     << request.getSequenceNumber()
	     << ", exp time = "
	     << request.getExpiryTime()
	     <<endl;
	cout << "\twith int1 = "
	     << *int1
	     << ", int2 = "
	     << *int2
	     << endl;

	int32 reply = *int1 + *int2;;

	ECS_AnnoData response;
	
	response.setValue(2, reply);

	request.respond(response);
    }
    else 
    {
	cout << "Server 1: Request data not matched" << endl;
	// Invalid request - ignore
	request.reject();
    }

    return 0;
}


// --------- The main program ---------

int
main(int argc, char* argv[])
{
    int32 instance = 1;
	.
	.
	.
	    
    signal(SIGTERM, exitHandler);
    signal(SIGINT, exitHandler);
    

// Create a handle for engine instance 1
    ECS_Engine           engine(instance);

// Create an instance of the event output handler class
    myServer server;
    ECS_AnnoFilter filter(0, "anno1");
    server.setFilter(filter);
    
// Register the output handler instance with the engine
    engine.addAnnotater(server);

// Enter the main loop. This call will block until
// ECS::shutdown is called; use ECS::poll() for a
// non-blocking call.

    ECS::mainloop();

    return 0;
}