/* **************************************************************************** * * check_json - */ TEST(AppendContextElementResponse, check_json) { AppendContextElementResponse acer; ContextAttributeResponse car; ContextAttribute ca("", "TYPE", "VALUE"); // empty name, thus provoking error std::string out; const char* outfile1 = "ngsi10.appendContextElementRequest.check1.postponed.json"; const char* outfile2 = "ngsi10.appendContextElementRequest.check2.postponed.json"; ConnectionInfo ci; utInit(); // 1. predetected error ci.outMimeType = JSON; out = acer.check(&ci, IndividualContextEntity, "", "PRE ERR", 0); EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'"; EXPECT_STREQ(expectedBuf, out.c_str()); // 2. bad contextAttributeResponseVector car.contextAttributeVector.push_back(&ca); acer.contextAttributeResponseVector.push_back(&car); out = acer.check(&ci, IndividualContextEntity, "", "", 0); EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'"; EXPECT_STREQ(expectedBuf, out.c_str()); // 3. OK ca.name = "NAME"; out = acer.check(&ci, IndividualContextEntity, "", "", 0); EXPECT_EQ("OK", out); utExit(); }
/* **************************************************************************** * * render_json - */ TEST(AppendContextElementResponse, render_json) { AppendContextElementResponse acer; ContextAttributeResponse car; std::string out; const char* outfile1 = "ngsi10.appendContextElementResponse.empty.valid.json"; const char* outfile2 = "ngsi10.appendContextElementResponse.badRequest.valid.json"; ConnectionInfo ci; utInit(); // 1. empty acer ci.outMimeType = JSON; out = acer.render(&ci, AppendContextElement, ""); EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'"; EXPECT_STREQ(expectedBuf, out.c_str()); // 2. errorCode 'active' acer.errorCode.fill(SccBadRequest, "very bad request"); out = acer.render(&ci, AppendContextElement, ""); EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'"; EXPECT_STREQ(expectedBuf, out.c_str()); utExit(); }
/* **************************************************************************** * * check - * * FIXME P3: once (if ever) AttributeDomainName::check stops to always return "OK", put back this piece of code * in its place: - * else if ((res = attributeDomainName.check(AppendContextElement, format, indent, predetectedError, counter)) != "OK") * { * response.errorCode.fill(SccBadRequest, res): * } * */ std::string AppendContextElementRequest::check ( ConnectionInfo* ciP, RequestType requestType, std::string indent, std::string predetectedError, // Predetected Error, normally during parsing int counter ) { AppendContextElementResponse response; std::string res; Format fmt = ciP->outFormat; if (predetectedError != "") { response.errorCode.fill(SccBadRequest, predetectedError); } else if ((res = contextAttributeVector.check(ciP, AppendContextElement, fmt, indent, predetectedError, counter)) != "OK") { response.errorCode.fill(SccBadRequest, res); } else if ((res = domainMetadataVector.check(ciP, AppendContextElement, fmt, indent, predetectedError, counter)) != "OK") { response.errorCode.fill(SccBadRequest, res); } else { return "OK"; } return response.render(ciP, requestType, indent); }
/* **************************************************************************** * * release - */ TEST(AppendContextElementResponse, release) { AppendContextElementResponse acer; ContextAttributeResponse* carP = new ContextAttributeResponse(); ContextAttribute* caP = new ContextAttribute("NAME", "TYPE", "VALUE"); utInit(); carP->contextAttributeVector.push_back(caP); acer.contextAttributeResponseVector.push_back(carP); EXPECT_EQ(1, carP->contextAttributeVector.size()); EXPECT_EQ(1, acer.contextAttributeResponseVector.size()); acer.release(); EXPECT_EQ(0, acer.contextAttributeResponseVector.size()); utExit(); }
/* **************************************************************************** * * postIndividualContextEntityAttributes - */ std::string postIndividualContextEntityAttributes ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string answer; std::string entityId = compV[2]; AppendContextElementResponse* responseP = new AppendContextElementResponse(); LM_T(LmtConvenience, ("CONVENIENCE: got a 'POST' request for entityId '%s'", entityId.c_str())); ciP->httpStatusCode = mapPostIndividualContextEntityAttributes(entityId, &parseDataP->acer.res, responseP, ciP); answer = responseP->render(ciP, IndividualContextEntityAttributes, ""); responseP->release(); delete responseP; return answer; }
/* **************************************************************************** * * postIndividualContextEntity - * * Corresponding Standard Operation: UpdateContext/APPEND * * NOTE * This function is used for two different URLs: * o /v1/contextEntities * o /v1/contextEntities/{entityId::id} * * In the longer URL (with entityId::id), the payload (AppendContextElementRequest) cannot contain any * entityId data (id, type, isPattern). * In the first case, the entityId data of the payload is mandatory. * entityId::type can be empty, as always, but entityId::id MUST be filled in. * * POST /v1/contextEntities * POST /ngsi10/contextEntities * POST /v1/contextEntities/{entityId::id} * POST /ngsi10/contextEntities/{entityId::id} * * Payload In: AppendContextElementRequest * Payload Out: AppendContextElementResponse * * URI parameters: * - attributesFormat=object * - entity::type=TYPE * - note that '!exist=entity::type' and 'exist=entity::type' are not supported by convenience operations * that use the standard operation UpdateContext as there is no restriction within UpdateContext. * * 00. Take care of URI params * 01. Check that total input in consistent and correct * 02. Fill in UpdateContextRequest from AppendContextElementRequest + URL-data + URI params * 03. Call postUpdateContext standard service routine * 04. Translate UpdateContextResponse to AppendContextElementResponse * 05. Cleanup and return result */ std::string postIndividualContextEntity ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { AppendContextElementRequest* reqP = &parseDataP->acer.res; AppendContextElementResponse response; std::string entityIdFromPayload = reqP->entity.id; std::string entityIdFromURL = ((compV.size() == 3) || (compV.size() == 4))? compV[2] : ""; std::string entityId; std::string entityTypeFromPayload = reqP->entity.type; std::string entityTypeFromURL = ciP->uriParam[URI_PARAM_ENTITY_TYPE]; std::string entityType; std::string answer; std::string out; // // 01. Check that total input in consistent and correct // // 01.01. entityId::id if ((entityIdFromPayload != "") && (entityIdFromURL != "") && (entityIdFromPayload != entityIdFromURL)) { std::string error = "entityId::id differs in URL and payload"; alarmMgr.badInput(clientIp, error); response.errorCode.fill(SccBadRequest, error); TIMED_RENDER(out = response.render(ciP, IndividualContextEntity, "")); return out; } entityId = (entityIdFromPayload != "")? entityIdFromPayload : entityIdFromURL; // 01.02. entityId::type if ((entityTypeFromPayload != "") && (entityTypeFromURL != "") && (entityTypeFromPayload != entityTypeFromURL)) { std::string error = "entityId::type differs in URL and payload"; alarmMgr.badInput(clientIp, error); response.errorCode.fill(SccBadRequest, error); TIMED_RENDER(out = response.render(ciP, IndividualContextEntity, "")); return out; } entityType = (entityTypeFromPayload != "")? entityTypeFromPayload :entityTypeFromURL; // 01.03. entityId::isPattern if (reqP->entity.isPattern == "true") { std::string error = "entityId::isPattern set to true in contextUpdate convenience operation"; alarmMgr.badInput(clientIp, error); response.errorCode.fill(SccBadRequest, error); TIMED_RENDER(out = response.render(ciP, IndividualContextEntity, "")); return out; } // 01.04. Entity::id must be present, somewhere ... if (entityId == "") { std::string error = "invalid request: mandatory entityId::id missing"; alarmMgr.badInput(clientIp, error); response.errorCode.fill(SccBadRequest, error); TIMED_RENDER(out = response.render(ciP, IndividualContextEntity, "")); return out; } // Now, forward Entity to response response.entity.fill(entityId, entityType, "false"); // // 02. Fill in UpdateContextRequest from AppendContextElementRequest + URL-data + URI params // parseDataP->upcr.res.fill(&parseDataP->acer.res, entityId, entityType); // 03. Call postUpdateContext standard service routine postUpdateContext(ciP, components, compV, parseDataP); // 04. Translate UpdateContextResponse to AppendContextElementResponse response.fill(&parseDataP->upcrs.res); // 05. Cleanup and return result TIMED_RENDER(answer = response.render(ciP, IndividualContextEntity, "")); response.release(); parseDataP->upcr.res.release(); return answer; }