Developing Apama Applications > Developing Clients > The C Client Software Development Kit > The complete C example
The complete C example
This is the C example, samples\engine_client\c\engine_client.c, in its entirety, complete with all exception and error handling. The reader is invited to peruse the alternative example, samples\engine_client\cpp\engine_client_c.cpp, for how to write an identically functional sample in the context of a C++ compiler, yet still using the C SDK.
/*
* engine_client.c
*
* This simple example illustrates how to use the C SDK to
* interface with Apama. The example connects to a remote Event Correlator
* (also known as a Correlation Engine), creates an event consumer and connects
* it to Apama's supplier interface, creates some MonitorScript code and injects it,
* injects some sample events, and receives some back from the Engine when the
* monitor triggers. It then disconnects from the Engine and exits.
*
* Copyright(c) 2002, 2004-2005 Software AG. All rights
* reserved. Use, reproduction, transfer, publication or disclosure is
* prohibited except as specifically provided for in your License Agreement
* with PSC.
*
* $RCSfile: engine_client.c,v $ $Revision: 1.5.6.1 $ $Date: 2006/04/03 12:31:20 $
*/

#include <engine_client_c.h>
#include <stddef.h>
#include <stdlib.h>
#ifdef __unix__
#include <unistd.h>
#endif
#ifdef __WIN32__
#include <windows.h>
#endif
#include <stdio.h>

#define STATUS_BUFFER_SIZE 8192

/**
* Receive a batch of events, log to stdout.
*/
static void AP_ENGINE_CLIENT_CALL receiveConsumer_sendEvents(
AP_EventConsumer* consumer, AP_Event** events) {
AP_Event** event;
for (event = events; *event; event++) {
printf("%s\n", (*event)->functions->getText(*event));
}
}

/**
* Function table for our event consumer.
*/
static struct AP_EventConsumer_Functions receiveConsumer_Functions = {
receiveConsumer_sendEvents
};


/**
* Main program.
*
* Return codes:
* 0 = Everything OK
* 1 = Couldn't connect to engine
* 2 = Something else went wrong
*/
int main(int argc, const char** argv) {
/* Return code */
int rc = 2;

/* Error message to display if anything goes wrong. Update this */
/* appropriately before each operation that might break. */
const char* emsg;

/* Buffer for stringified status reports */
AP_char8 statusBuf[STATUS_BUFFER_SIZE];

if (argc == 3 && atoi(argv[2]) > 0) {

/* Set to true once the engine library has been initialised */
AP_bool initDone = 0;

/* Set to true to drop out of the loop with a pending exception */
AP_bool exThrown = 0;

/* The engine */
AP_EngineManagement* engine = NULL;

do {
/* The event consumer */
AP_EventConsumer* consumer = NULL;

/* The (remote) event supplier reference */
AP_EventSupplier* supplier = NULL;

/* Monitorscript to be injected into engine */
AP_MonitorScript* script = NULL;

/* Engine status report */
AP_EngineStatus* status = NULL;

/* Events to be sent */
AP_Event* events[3];

/* Initialise Apama SDK client-side library */
rc = 1;
emsg = "Failed to initialise Apama SDK library";
AP_EngineInit();
if (AP_CheckException()) {
exThrown = 1;
break;
}
initDone = 1;

/* Attempt to connect to a remote Engine */
emsg = "Failed to connect to engine";
engine = AP_ConnectToEngine(argv[1], (AP_uint16) atoi(argv[2]));
if (AP_CheckException() || !engine) {
exThrown = 1;
break;
}

/* Create an event consumer */
emsg = "Event sink connection failed";
consumer = (AP_EventConsumer*)malloc(sizeof(AP_EventConsumer));
consumer->functions = &receiveConsumer_Functions;
supplier = engine->functions->connectEventConsumer(engine, consumer, NULL);
if (AP_CheckException() || !supplier) {
exThrown = 1;
break;
}

/* Inject some MonitorScript (don't forget to delete it when done) */
emsg = "MonitorScript injection failed";
script = AP_CreateMonitorScript(
"event TestEvent {"
"string text;"
"}"
""
"monitor Echo {"
""
"TestEvent test;"
""
"action onload {"
"on all TestEvent(*):test {"
"emit TestEvent(test.text);"
"}"
"}"
"}");
engine->functions->injectMonitorScript(engine, script);
if (AP_CheckException()) {
exThrown = 1;
break;
}
AP_DeleteMonitorScript(script);
if (AP_CheckException()) {
exThrown = 1;
break;
}

/* Wait a few seconds to be sure the injection event has been processed */
#ifdef __unix__
sleep(3);
#endif
#ifdef __WIN32__
Sleep(3000);
#endif

/* Get & display status (have to delete it when done) */
emsg = "Status gathering failed";
printf("\n");
status = engine->functions->getStatus(engine);
if (AP_CheckException() || !status) {
exThrown = 1;
break;
}
if (status->functions->print(status, statusBuf, STATUS_BUFFER_SIZE)) {
printf("%s", statusBuf);
}
else {
printf("Status buffer too small!");
}
printf("\n");
AP_DeleteEngineStatus(status);

/* Send some events (again, remember to delete Event objects when done) */
emsg = "Event sending failed";
events[0] = AP_CreateEvent("TestEvent(\"Hello, World\")");
events[1] = AP_CreateEvent("TestEvent(\"Welcome to Apama\")");
events[2] = NULL;
engine->s_EventConsumer->functions->sendEvents(engine->s_EventConsumer, events);
AP_DeleteEvent(events[0]);
AP_DeleteEvent(events[1]);
if (AP_CheckException()) {
exThrown = 1;
break;
}

/* Delete the event type and monitor we added */
emsg = "Name deletion failed";
engine->functions->deleteName(engine, "Echo");
if (AP_CheckException()) {
exThrown = 1;
break;
}
engine->functions->deleteName(engine, "TestEvent");
if (AP_CheckException()) {
exThrown = 1;
break;
}

/* Wait a few seconds for the output event to be received and
the deletions processed */
#ifdef __unix__
sleep(3);
#endif
#ifdef __WIN32__
Sleep(3000);
#endif

/* Display status again */
emsg = "Status gathering failed";
printf("\n");
status = engine->functions->getStatus(engine);
if (AP_CheckException() || !status) {
exThrown = 1;
break;
}
if (status->functions->print(status, statusBuf, STATUS_BUFFER_SIZE)) {
printf("%s", statusBuf);
}
else {
printf("Status buffer too small!");
}
printf("\n");
AP_DeleteEngineStatus(status);

/* Disconnect and destroy the event consumer */
emsg = "Event sink disconnection failed";
supplier->functions->disconnect(supplier);
if (AP_CheckException()) {
exThrown = 1;
break;
}
free((void*)consumer);

/* If we got this far, everything succeeded! */
rc = 0;
} while (0);

if (exThrown) {
if (AP_CheckException()) {
printf("%s: %s\n", emsg, AP_GetExceptionMessage());
}
else {
printf("%s\n", emsg);
}
exThrown = 0;
AP_ClearException();
}

do {
/* Shutdown cleanly */
if (engine) {
/* Disconnect from the engine */
emsg = "Failed to disconnect from Engine";
AP_DisconnectFromEngine(engine);
if (AP_CheckException()) {
exThrown = 1;
}
}
if (initDone) {
/* Shutdown the engine library */
emsg = "Failed to shutdown Apama SDK library";
AP_EngineShutdown();
if (AP_CheckException()) {
exThrown = 1;
}
}
} while (0);

if (exThrown) {
if (AP_CheckException()) {
printf("%s: %s\n", emsg, AP_GetExceptionMessage());
}
else {
printf("%s\n", emsg);
}
exThrown = 0;
AP_ClearException();
}
}
else {
/* Bad command line given */
fprintf(stderr, "Usage: %s <host> <port>\n", argv[0]);
}

/* Done! */
return rc;
}
Copyright © 2013 Software AG, Darmstadt, Germany and/or Software AG USA Inc., Reston, VA, USA, and/or Terracotta Inc., San Francisco, CA, USA, and/or Software AG (Canada) Inc., Cambridge, Ontario, Canada, and/or, Software AG (UK) Ltd., Derby, United Kingdom, and/or Software A.G. (Israel) Ltd., Or-Yehuda, Israel and/or their licensors.