annotate soap.cpp @ 307:d1b8b2dec37e

Added reporters radius search via Web Services. The ordering for radius search is degenerate if usingQueryPoint, because the query point can only be counted once. This behaviour is changed by specifying -n 1 to emulate the trackAveragingReporter ordering behaviour
author mas01mc
date Wed, 06 Aug 2008 21:23:14 +0000
parents 2cc06e5b05a5
children 896679d8cc39
rev   line source
mas01cr@239 1 #include "audioDB.h"
mas01cr@239 2 #include "adb.nsmap"
mas01cr@239 3
mas01cr@239 4 /* Command-line client definitions */
mas01cr@239 5
mas01cr@239 6 // FIXME: this can't propagate the sequence length argument (used for
mas01cr@239 7 // dudCount). See adb__status() definition for the other half of
mas01cr@239 8 // this. -- CSR, 2007-10-01
mas01cr@239 9 void audioDB::ws_status(const char*dbName, char* hostport){
mas01cr@239 10 struct soap soap;
mas01cr@239 11 adb__statusResponse adbStatusResponse;
mas01cr@239 12
mas01cr@239 13 // Query an existing adb database
mas01cr@239 14 soap_init(&soap);
mas01cr@239 15 if(soap_call_adb__status(&soap,hostport,NULL,(char*)dbName,adbStatusResponse)==SOAP_OK) {
mas01cr@239 16 std::cout << "numFiles = " << adbStatusResponse.result.numFiles << std::endl;
mas01cr@239 17 std::cout << "dim = " << adbStatusResponse.result.dim << std::endl;
mas01cr@239 18 std::cout << "length = " << adbStatusResponse.result.length << std::endl;
mas01cr@239 19 std::cout << "dudCount = " << adbStatusResponse.result.dudCount << std::endl;
mas01cr@239 20 std::cout << "nullCount = " << adbStatusResponse.result.nullCount << std::endl;
mas01cr@239 21 std::cout << "flags = " << adbStatusResponse.result.flags << std::endl;
mas01cr@239 22 } else {
mas01cr@239 23 soap_print_fault(&soap,stderr);
mas01cr@239 24 }
mas01cr@239 25
mas01cr@239 26 soap_destroy(&soap);
mas01cr@239 27 soap_end(&soap);
mas01cr@239 28 soap_done(&soap);
mas01cr@239 29 }
mas01cr@239 30
mas01mc@307 31 void audioDB::ws_query(const char*dbName, const char *featureFileName, const char* hostport){
mas01cr@239 32 struct soap soap;
mas01cr@239 33 adb__queryResponse adbQueryResponse;
mas01cr@239 34
mas01cr@239 35 soap_init(&soap);
mas01cr@239 36 if(soap_call_adb__query(&soap,hostport,NULL,
mas01mc@307 37 (char*)dbName,(char*)featureFileName,(char*)trackFileName,(char*)timesFileName,
mas01cr@239 38 queryType, queryPoint, pointNN, trackNN, sequenceLength, adbQueryResponse)==SOAP_OK){
mas01cr@239 39 //std::std::cerr << "result list length:" << adbQueryResponse.result.__sizeRlist << std::std::endl;
mas01cr@239 40 for(int i=0; i<adbQueryResponse.result.__sizeRlist; i++)
mas01cr@239 41 std::cout << adbQueryResponse.result.Rlist[i] << " " << adbQueryResponse.result.Dist[i]
mas01cr@239 42 << " " << adbQueryResponse.result.Qpos[i] << " " << adbQueryResponse.result.Spos[i] << std::endl;
mas01cr@239 43 }
mas01cr@239 44 else
mas01cr@239 45 soap_print_fault(&soap,stderr);
mas01cr@239 46
mas01cr@239 47 soap_destroy(&soap);
mas01cr@239 48 soap_end(&soap);
mas01cr@239 49 soap_done(&soap);
mas01cr@239 50 }
mas01mc@307 51
mas01mc@307 52 void audioDB::ws_query_by_key(const char*dbName, const char *trackKey, const char* hostport){
mas01mc@307 53 struct soap soap;
mas01mc@307 54 adb__queryResponse adbQueryResponse;
mas01mc@307 55 adb__sequenceQueryParms asqp;
mas01mc@307 56
mas01mc@307 57 asqp.keyList = (char*)trackFileName;
mas01mc@307 58 asqp.timesFileName = (char*)timesFileName;
mas01mc@307 59 asqp.queryPoint = queryPoint;
mas01mc@307 60 asqp.pointNN = pointNN;
mas01mc@307 61 asqp.trackNN = trackNN;
mas01mc@307 62 asqp.sequenceLength = sequenceLength;
mas01mc@307 63 asqp.radius = radius;
mas01mc@307 64 asqp.relative_threshold = relative_threshold;
mas01mc@307 65 asqp.absolute_threshold = absolute_threshold;
mas01mc@307 66
mas01mc@307 67 soap_init(&soap);
mas01mc@307 68 if(queryType==O2_SEQUENCE_QUERY || queryType==O2_N_SEQUENCE_QUERY){
mas01mc@307 69 if(soap_call_adb__sequenceQuery_by_key(&soap,hostport,NULL,(char*)dbName,(char*)trackKey,queryType,&asqp,adbQueryResponse)==SOAP_OK){
mas01mc@307 70 //std::std::cerr << "result list length:" << adbQueryResponse.result.__sizeRlist << std::std::endl;
mas01mc@307 71 for(int i=0; i<adbQueryResponse.result.__sizeRlist; i++)
mas01mc@307 72 std::cout << adbQueryResponse.result.Rlist[i] << " " << adbQueryResponse.result.Dist[i]
mas01mc@307 73 << " " << adbQueryResponse.result.Qpos[i] << " " << adbQueryResponse.result.Spos[i] << std::endl;
mas01mc@307 74 }
mas01mc@307 75 else
mas01mc@307 76 soap_print_fault(&soap,stderr);
mas01mc@307 77 }else
mas01mc@307 78 ;// FIX ME: WRITE NON-SEQUENCE QUERY BY KEY ?
mas01mc@307 79
mas01mc@307 80 soap_destroy(&soap);
mas01mc@307 81 soap_end(&soap);
mas01mc@307 82 soap_done(&soap);
mas01mc@307 83 }
mas01mc@307 84
mas01cr@239 85
mas01cr@239 86 /* Server definitions */
mas01cr@239 87 int adb__status(struct soap* soap, xsd__string dbName, adb__statusResponse &adbStatusResponse){
mas01mc@307 88 char* const argv[]={"./audioDB",COM_STATUS,"-d",dbName};
mas01cr@239 89 const unsigned argc = 4;
mas01cr@239 90 try {
mas01cr@239 91 audioDB(argc, argv, &adbStatusResponse);
mas01cr@239 92 return SOAP_OK;
mas01cr@239 93 } catch(char *err) {
mas01cr@239 94 soap_receiver_fault(soap, err, "");
mas01cr@239 95 return SOAP_FAULT;
mas01cr@239 96 }
mas01cr@239 97 }
mas01cr@239 98
mas01cr@239 99 // Literal translation of command line to web service
mas01cr@239 100
mas01cr@239 101 int adb__query(struct soap* soap, xsd__string dbName, xsd__string qKey, xsd__string keyList, xsd__string timesFileName, xsd__int qType, xsd__int qPos, xsd__int pointNN, xsd__int trackNN, xsd__int seqLen, adb__queryResponse &adbQueryResponse){
mas01cr@239 102 char queryType[256];
mas01cr@239 103 for(int k=0; k<256; k++)
mas01cr@239 104 queryType[k]='\0';
mas01cr@239 105 if(qType == O2_POINT_QUERY)
mas01cr@239 106 strncpy(queryType, "point", strlen("point"));
mas01cr@239 107 else if (qType == O2_SEQUENCE_QUERY)
mas01cr@239 108 strncpy(queryType, "sequence", strlen("sequence"));
mas01cr@239 109 else if(qType == O2_TRACK_QUERY)
mas01cr@239 110 strncpy(queryType,"track", strlen("track"));
mas01cr@239 111 else
mas01cr@239 112 strncpy(queryType, "", strlen(""));
mas01cr@239 113
mas01cr@239 114 if(pointNN==0)
mas01cr@239 115 pointNN=10;
mas01cr@239 116 if(trackNN==0)
mas01cr@239 117 trackNN=10;
mas01cr@239 118 if(seqLen==0)
mas01cr@239 119 seqLen=16;
mas01cr@239 120
mas01cr@239 121 char qPosStr[256];
mas01cr@239 122 sprintf(qPosStr, "%d", qPos);
mas01cr@239 123 char pointNNStr[256];
mas01cr@239 124 sprintf(pointNNStr,"%d",pointNN);
mas01cr@239 125 char trackNNStr[256];
mas01cr@239 126 sprintf(trackNNStr,"%d",trackNN);
mas01cr@239 127 char seqLenStr[256];
mas01cr@239 128 sprintf(seqLenStr,"%d",seqLen);
mas01cr@239 129
mas01cr@239 130 const char* argv[] ={
mas01cr@239 131 "./audioDB",
mas01cr@239 132 COM_QUERY,
mas01cr@239 133 queryType, // Need to pass a parameter
mas01cr@239 134 COM_DATABASE,
mas01cr@239 135 ENSURE_STRING(dbName),
mas01cr@239 136 COM_FEATURES,
mas01cr@239 137 ENSURE_STRING(qKey),
mas01cr@239 138 COM_KEYLIST,
mas01cr@239 139 ENSURE_STRING(keyList),
mas01cr@239 140 COM_TIMES,
mas01cr@239 141 ENSURE_STRING(timesFileName),
mas01cr@239 142 COM_QPOINT,
mas01cr@239 143 qPosStr,
mas01cr@239 144 COM_POINTNN,
mas01cr@239 145 pointNNStr,
mas01cr@239 146 COM_TRACKNN,
mas01cr@239 147 trackNNStr, // Need to pass a parameter
mas01cr@239 148 COM_SEQLEN,
mas01cr@239 149 seqLenStr
mas01cr@239 150 };
mas01cr@239 151
mas01cr@239 152 const unsigned argc = 19;
mas01cr@239 153 try {
mas01cr@239 154 audioDB(argc, (char* const*)argv, &adbQueryResponse);
mas01cr@239 155 return SOAP_OK;
mas01cr@239 156 } catch (char *err) {
mas01cr@239 157 soap_receiver_fault(soap, err, "");
mas01cr@239 158 return SOAP_FAULT;
mas01cr@239 159 }
mas01cr@239 160 }
mas01cr@239 161
mas01mc@307 162 // A sequence query using radius and a query key
mas01mc@307 163 int adb__sequenceQuery_by_key(struct soap* soap, xsd__string dbName, xsd__string qKey, int qType,
mas01mc@307 164 adb__sequenceQueryParms* parms,
mas01mc@307 165 adb__queryResponse& adbQueryResponse) {
mas01cr@239 166
mas01mc@307 167 char radiusStr[256];
mas01cr@239 168 char qPosStr[256];
mas01cr@239 169 char pointNNStr[256];
mas01cr@239 170 char trackNNStr[256];
mas01cr@239 171 char seqLenStr[256];
mas01cr@239 172 char relative_thresholdStr[256];
mas01cr@239 173 char absolute_thresholdStr[256];
mas01mc@307 174 char qtypeStr[256];
mas01cr@239 175
mas01cr@239 176 /* When the branch is merged, move this to a header and use it
mas01cr@239 177 elsewhere */
mas01cr@239 178 #define INTSTRINGIFY(val, str) \
mas01cr@239 179 snprintf(str, 256, "%d", val);
mas01cr@239 180 #define DOUBLESTRINGIFY(val, str) \
mas01cr@239 181 snprintf(str, 256, "%f", val);
mas01cr@239 182
mas01mc@307 183 INTSTRINGIFY(parms->queryPoint, qPosStr);
mas01cr@239 184 INTSTRINGIFY(parms->pointNN, pointNNStr);
mas01mc@307 185 INTSTRINGIFY(parms->trackNN, trackNNStr);
mas01mc@307 186 INTSTRINGIFY(parms->sequenceLength, seqLenStr);
mas01cr@239 187
mas01cr@239 188 DOUBLESTRINGIFY(parms->relative_threshold, relative_thresholdStr);
mas01cr@239 189 DOUBLESTRINGIFY(parms->absolute_threshold, absolute_thresholdStr);
mas01mc@307 190 DOUBLESTRINGIFY(parms->radius, radiusStr);
mas01mc@307 191
mas01mc@307 192 // WS queries only support 1-nearest neighbour point reporting
mas01mc@307 193 // at the moment, until we figure out how to better serve results
mas01mc@307 194 snprintf(qtypeStr, 256, "nsequence");
mas01mc@307 195
mas01cr@239 196 const char *argv[] = {
mas01cr@239 197 "./audioDB",
mas01cr@239 198 COM_QUERY,
mas01mc@307 199 qtypeStr,
mas01cr@239 200 COM_DATABASE,
mas01cr@239 201 dbName,
mas01mc@307 202 COM_QUERYKEY,
mas01mc@307 203 ENSURE_STRING(qKey),
mas01cr@239 204 COM_KEYLIST,
mas01mc@307 205 ENSURE_STRING(parms->keyList),
mas01cr@239 206 COM_QPOINT,
mas01cr@239 207 qPosStr,
mas01cr@239 208 COM_POINTNN,
mas01cr@239 209 pointNNStr,
mas01cr@239 210 COM_TRACKNN,
mas01cr@239 211 trackNNStr,
mas01mc@307 212 COM_RADIUS,
mas01mc@307 213 radiusStr,
mas01cr@239 214 COM_SEQLEN,
mas01cr@239 215 seqLenStr,
mas01cr@239 216 COM_ABSOLUTE_THRESH,
mas01cr@239 217 absolute_thresholdStr
mas01cr@239 218 };
mas01cr@239 219
mas01mc@307 220 const unsigned argc = 21;
mas01cr@239 221
mas01cr@239 222 try {
mas01cr@239 223 audioDB(argc, (char* const*)argv, &adbQueryResponse);
mas01cr@239 224 return SOAP_OK;
mas01cr@239 225 } catch (char *err) {
mas01cr@239 226 soap_receiver_fault(soap, err, "");
mas01cr@239 227 return SOAP_FAULT;
mas01cr@239 228 }
mas01cr@239 229 }
mas01cr@239 230
mas01cr@239 231 /* Server loop */
mas01cr@239 232 void audioDB::startServer(){
mas01cr@239 233 struct soap soap;
mas01cr@239 234 int m, s; // master and slave sockets
mas01cr@239 235 soap_init(&soap);
mas01cr@239 236 // FIXME: largely this use of SO_REUSEADDR is to make writing (and
mas01cr@239 237 // running) test cases more convenient, so that multiple test runs
mas01cr@239 238 // in close succession don't fail because of a bin() error.
mas01cr@239 239 // Investigate whether there are any potential drawbacks in this,
mas01cr@239 240 // and also whether there's a better way to write the tests. --
mas01cr@239 241 // CSR, 2007-10-03
mas01cr@239 242 soap.bind_flags |= SO_REUSEADDR;
mas01cr@239 243 m = soap_bind(&soap, NULL, port, 100);
mas01cr@239 244 if (m < 0)
mas01cr@239 245 soap_print_fault(&soap, stderr);
mas01cr@239 246 else
mas01cr@239 247 {
mas01cr@239 248 fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
mas01cr@239 249 for (int i = 1; ; i++)
mas01cr@239 250 {
mas01cr@239 251 s = soap_accept(&soap);
mas01cr@239 252 if (s < 0)
mas01cr@239 253 {
mas01cr@239 254 soap_print_fault(&soap, stderr);
mas01cr@239 255 break;
mas01cr@239 256 }
mas01cr@239 257 /* FIXME: find a way to play nice with logging when run from
mas01cr@239 258 /etc/init.d scripts: at present this just goes nowhere */
mas01cr@239 259 fprintf(stderr, "%d: accepted connection from IP=%lu.%lu.%lu.%lu socket=%d\n", i,
mas01cr@239 260 (soap.ip >> 24)&0xFF, (soap.ip >> 16)&0xFF, (soap.ip >> 8)&0xFF, soap.ip&0xFF, s);
mas01cr@239 261 if (soap_serve(&soap) != SOAP_OK) // process RPC request
mas01cr@239 262 soap_print_fault(&soap, stderr); // print error
mas01cr@239 263 fprintf(stderr, "request served\n");
mas01cr@239 264 soap_destroy(&soap); // clean up class instances
mas01cr@239 265 soap_end(&soap); // clean up everything and close socket
mas01cr@239 266 }
mas01cr@239 267 }
mas01cr@239 268 soap_done(&soap); // close master socket and detach environment
mas01cr@239 269 }