/* **************************************************************************** * * postBatchQuery - * * POST /v2/op/query * * Payload In: BatchQueryRequest * Payload Out: Entities * * URI parameters: * - limit=NUMBER * - offset=NUMBER * - options=count,keyValues */ std::string postBatchQuery ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { BatchQuery* bqP = &parseDataP->bq.res; QueryContextRequest* qcrP = &parseDataP->qcr.res; Entities entities; std::string answer; qcrP->fill(bqP); bqP->release(); // qcrP just 'took over' the data from bqP, bqP no longer needed answer = postQueryContext(ciP, components, compV, parseDataP); if (ciP->httpStatusCode != SccOk) { parseDataP->qcr.res.release(); return answer; } // 03. Render Entities response if (parseDataP->qcrs.res.contextElementResponseVector.size() == 0) { ciP->httpStatusCode = SccOk; answer = "[]"; } else { entities.fill(&parseDataP->qcrs.res); TIMED_RENDER(answer = entities.render(ciP, EntitiesResponse)); } // 04. Cleanup and return result entities.release(); parseDataP->qcr.res.release(); return answer; }
/* **************************************************************************** * * getEntities - * * GET /v2/entities * * Payload In: None * Payload Out: Entities * * URI parameters: * - limit=NUMBER * - offset=NUMBER * - count=true/false * * 01. Fill in QueryContextRequest * 02. Call standard op postQueryContext * 03. Render Entities response * 04. Cleanup and return result */ std::string getEntities ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string answer; Entities entities; // 01. Fill in QueryContextRequest parseDataP->qcr.res.fill(".*", "", "true", EntityTypeEmptyOrNotEmpty, ""); // 02. Call standard op postQueryContext answer = postQueryContext(ciP, components, compV, parseDataP); // 03. Render Entities response if (parseDataP->qcrs.res.contextElementResponseVector.size() == 0) { ciP->httpStatusCode = SccOk; answer = "[]"; } else { entities.fill(&parseDataP->qcrs.res); answer = entities.render(ciP, EntitiesResponse); } // 04. Cleanup and return result entities.release(); parseDataP->qcr.res.release(); return answer; }
/* **************************************************************************** * * postBatchUpdate - * * POST /v2/op/update * * Payload In: BatchUpdateRequest * Payload Out: 201 or error * * URI parameters: * - limit=NUMBER * - offset=NUMBER * - options=keyValues */ std::string postBatchUpdate ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { BatchUpdate* buP = &parseDataP->bu.res; UpdateContextRequest* upcrP = &parseDataP->upcr.res; Entities entities; std::string answer; upcrP->fill(&buP->entities, buP->updateActionType.get()); buP->release(); // upcrP just 'took over' the data from buP, buP is no longer needed parseDataP->upcr.res.present(""); answer = postUpdateContext(ciP, components, compV, parseDataP); for (unsigned int ix = 0; ix < parseDataP->upcrs.res.contextElementResponseVector.size(); ++ix) { ContextElementResponse* cerP = parseDataP->upcrs.res.contextElementResponseVector[ix]; if (cerP->statusCode.code != SccOk) { parseDataP->upcrs.res.errorCode.fill(cerP->statusCode); } } // // If an error is flagged by ciP->httpStatusCode, store it in parseDataP->upcrs.res.errorCode // for later processing (not sure this ever happen ...) // if (ciP->httpStatusCode != SccOk) { parseDataP->upcrs.res.errorCode.code = ciP->httpStatusCode; parseDataP->upcrs.res.errorCode.details = answer; } // If postUpdateContext gives back a parseDataP->upcrs with !200 OK in 'errorCode', transform to HTTP Status error if (parseDataP->upcrs.res.errorCode.code != SccOk) { OrionError oe(parseDataP->upcrs.res.errorCode); ciP->httpStatusCode = parseDataP->upcrs.res.errorCode.code; // If 404 and details empty, assuming 'Entity not found' if ((parseDataP->upcrs.res.errorCode.code == SccContextElementNotFound) && (oe.details == "")) { oe.details = "Entity not found"; } answer = oe.render(ciP, ""); } else { // // NOTE // For simplicity, 204 is always returned, even if entities are created // ciP->httpStatusCode = SccNoContent; answer = ""; } // 04. Cleanup and return result entities.release(); parseDataP->upcr.res.release(); return answer; }
/* **************************************************************************** * * getEntities - * * GET /v2/entities * * Payload In: None * Payload Out: Entities * * URI parameters: * - limit=NUMBER * - offset=NUMBER * - count=true/false * - id * - idPattern * - q * - geometry * - coords * * 01. Fill in QueryContextRequest * 02. Call standard op postQueryContext * 03. Render Entities response * 04. Cleanup and return result */ std::string getEntities ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { Entities entities; std::string answer; std::string pattern = ".*"; // all entities, default value std::string id = ciP->uriParam["id"]; std::string idPattern = ciP->uriParam["idPattern"]; std::string q = ciP->uriParam["q"]; std::string geometry = ciP->uriParam["geometry"]; std::string coords = ciP->uriParam["coords"]; std::string out; if ((idPattern != "") && (id != "")) { OrionError oe(SccBadRequest, "Incompatible parameters: id, IdPattern"); TIMED_RENDER(answer = oe.render(ciP, "")); return answer; } else if (id != "") { // FIXME: a more efficient query could be possible ... std::vector<std::string> idsV; stringSplit(id, ',', idsV); for (unsigned int ix = 0; ix != idsV.size(); ++ix) { if (ix != 0) { pattern += "|"; } pattern += idsV[ix]; } } else if (idPattern != "") { pattern = idPattern; } // Making sure geometry and coords are not used individually if ((coords != "") && (geometry == "")) { OrionError oe(SccBadRequest, "URI param /coords/ used without /geometry/"); TIMED_RENDER(out = oe.render(ciP, "")); return out; } else if ((geometry != "") && (coords == "")) { OrionError oe(SccBadRequest, "URI param /geometry/ used without /coords/"); TIMED_RENDER(out = oe.render(ciP, "")); return out; } // Making sure geometry is valid (if present) orion::Geometry geo; std::vector<std::string> coordsV; if (geometry != "") { std::string errorString; if (geo.parse(geometry.c_str(), &errorString) != 0) { OrionError oe(SccBadRequest, std::string("error parsing geometry: ") + errorString); TIMED_RENDER(out = oe.render(ciP, "")); return out; } if ((geo.areaType != "polygon") && (geo.areaType != "circle")) { OrionError oe(SccBadRequest, "URI param /geometry/ must be either /polygon/ or /circle/"); TIMED_RENDER(out = oe.render(ciP, "")); return out; } // // As 'geometry' is present, so is 'coords' - checking coords // int noOfCoords = stringSplit(coords, ';', coordsV); if (noOfCoords == 0) { OrionError oe(SccBadRequest, "URI param /coords/ has no coordinates"); TIMED_RENDER(out = oe.render(ciP, "")); return out; } if ((geo.areaType == "circle") && (noOfCoords != 1)) { OrionError oe(SccBadRequest, "Too many coordinates for circle"); TIMED_RENDER(out = oe.render(ciP, "")); return out; } if ((geo.areaType == "polygon") && (noOfCoords < 3)) { OrionError oe(SccBadRequest, "Too few coordinates for polygon"); TIMED_RENDER(out = oe.render(ciP, "")); return out; } } // // 01. Fill in QueryContextRequest - type "" is valid for all types // parseDataP->qcr.res.fill(pattern, ciP->uriParam["type"], "true", EntityTypeEmptyOrNotEmpty, ""); // If URI param 'q' is given, its value must be put in a scope if (q != "") { Scope* scopeP = new Scope(SCOPE_TYPE_SIMPLE_QUERY, q); parseDataP->qcr.res.restriction.scopeVector.push_back(scopeP); } // If URI params 'geometry' and 'coords' are given, another scope is to be created for this if ((coords != "") && (geometry != "")) { Scope* scopeP = new Scope(SCOPE_TYPE_LOCATION, ""); std::string errorString; if (scopeP->fill(&geo, coordsV, &errorString) != 0) { OrionError oe(SccBadRequest, errorString); TIMED_RENDER(out = oe.render(ciP, "")); return out; } parseDataP->qcr.res.restriction.scopeVector.push_back(scopeP); } // 02. Call standard op postQueryContext answer = postQueryContext(ciP, components, compV, parseDataP); if (ciP->httpStatusCode != SccOk) { // Something went wrong in the query, an invalid pattern for example parseDataP->qcr.res.release(); return answer; } // 03. Render Entities response if (parseDataP->qcrs.res.contextElementResponseVector.size() == 0) { ciP->httpStatusCode = SccOk; answer = "[]"; } else { entities.fill(&parseDataP->qcrs.res); TIMED_RENDER(answer = entities.render(ciP, EntitiesResponse)); } // 04. Cleanup and return result entities.release(); parseDataP->qcr.res.release(); return answer; }