/* **************************************************************************** * * fill - */ TEST(StatusCode, fill) { StatusCode sc; StatusCode sc2(SccOk, "Details"); StatusCode ec(SccBadRequest, "Very bad request :-)"); std::string out; utInit(); sc.fill(SccForbidden, "D"); EXPECT_EQ(sc.code, SccForbidden); EXPECT_STREQ(sc.reasonPhrase.c_str(), "Forbidden"); EXPECT_STREQ(sc.details.c_str(), "D"); sc.fill(&sc2); EXPECT_EQ(sc.code, SccOk); EXPECT_STREQ(sc.reasonPhrase.c_str(), "OK"); EXPECT_STREQ(sc.details.c_str(), "Details"); sc.fill(&ec); EXPECT_EQ(sc.code, SccBadRequest); EXPECT_STREQ(sc.reasonPhrase.c_str(), "Bad Request"); EXPECT_STREQ(sc.details.c_str(), "Very bad request :-)"); utExit(); }
/* **************************************************************************** * * putAttributeValueInstance - * * PUT /v1/contextEntities/{entity::id}/attributes/{attribute::name}/{metaID} * PUT /ngsi10/contextEntities/{entity::id}/attributes/{attribute::name}/{metaID} * * Payload In: UpdateContextAttributeRequest * Payload Out: StatusCode * * URI parameters * - entity::type=TYPE * - note that '!exist=entity::type' and 'exist=entity::type' are not supported by convenience operations * that don't use the standard operation QueryContext as there is no Restriction otherwise. * Here, entity::type can be empty though, and it is, unless the URI parameter 'entity::type=TYPE' is used. * * 01. Check validity of path components VS payload * 02. Fill in UpdateContextRequest * 03. Call postUpdateContext * 04. Fill in StatusCode from UpdateContextResponse * 05. Render result * 06. Cleanup and return result */ std::string putAttributeValueInstance ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string entityId = compV[2]; std::string attributeName = compV[4]; std::string metaID = compV[5]; std::string entityType = ciP->uriParam[URI_PARAM_ENTITY_TYPE]; std::string answer; StatusCode response; // 01. Check validity of path components VS payload Metadata* mP = parseDataP->upcar.res.metadataVector.lookupByName("ID"); if ((mP != NULL) && (mP->value != metaID)) { std::string details = "unmatching metadata ID value URI/payload: /" + metaID + "/ vs /" + mP->value + "/"; response.fill(SccBadRequest, details); answer = response.render(ciP->outFormat, "", false, false); parseDataP->upcar.res.release(); return answer; } // 02. Fill in UpdateContextRequest parseDataP->upcr.res.fill(&parseDataP->upcar.res, entityId, entityType, attributeName, metaID, "UPDATE"); // 03. Call postUpdateContext postUpdateContext(ciP, components, compV, parseDataP); // 04. Fill in StatusCode from UpdateContextResponse response.fill(parseDataP->upcrs.res); // 05. Render result answer = response.render(ciP->outFormat, "", false, false); // 06. Cleanup and return result response.release(); parseDataP->upcar.res.release(); parseDataP->upcr.res.release(); parseDataP->upcrs.res.release(); return answer; }
/* **************************************************************************** * * deleteAttributeValueInstanceWithTypeAndId - * * DELETE /v1/contextEntities/type/{entity::type}/id/{entity::id}/attributes/{attribute::name}/{metaID} * DELETE /ngsi10/contextEntities/type/{entity::type}/id/{entity::id}/attributes/{attribute::name}/{metaID} * * Mapped Standard Operation: UpdateContextRequest/DELETE * * URI params: * - 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. * * 01. URI parameters * 02. Check validity of URI params * 03. Fill in UpdateContextRequest * 04. Call postUpdateContext standard service routine * 05. Translate UpdateContextResponse to StatusCode * 06. Cleanup and return result */ std::string deleteAttributeValueInstanceWithTypeAndId ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { StatusCode response; std::string answer; std::string entityTypeFromUriParam; std::string entityTypeFromPath = compV[3]; std::string entityId = compV[5]; std::string attributeName = compV[7]; std::string metaId = compV[8]; // 01. URI parameters entityTypeFromUriParam = ciP->uriParam[URI_PARAM_ENTITY_TYPE]; // 02. Check validity of URI params if ((entityTypeFromUriParam != "") && (entityTypeFromUriParam != entityTypeFromPath)) { LM_W(("Bad Input non-matching entity::types in URL")); response.fill(SccBadRequest, "non-matching entity::types in URL"); answer = response.render(ciP->outFormat, "", false, false); return answer; } // 03. Fill in UpdateContextRequest parseDataP->upcr.res.fill(entityId, entityTypeFromPath, "false", attributeName, metaId, "DELETE"); // 04. Call postUpdateContext standard service routine answer = postUpdateContext(ciP, components, compV, parseDataP); // 05. Translate UpdateContextResponse to StatusCode response.fill(parseDataP->upcrs.res); // 06. Cleanup and return result answer = response.render(ciP->outFormat, "", false, false); response.release(); parseDataP->upcr.res.release(); return answer; }
/* **************************************************************************** * * deleteIndividualContextEntityAttribute - * * DELETE /v1/contextEntities/{entityId::id}/attributes/{attributeName} * DELETE /ngsi10/contextEntities/{entityId::id}/attributes/{attributeName} * * Payload In: None * Payload Out: StatusCode * * URI parameters: * - 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. * [ attributesFormat=object: makes no sense for this operation as StatusCode is returned ] * * 0. Take care of URI params * 1. Fill in UpdateContextRequest from URL-path components * 2. Call postUpdateContext standard service routine * 3. Translate UpdateContextResponse to StatusCode * 4. Cleanup and return result */ std::string deleteIndividualContextEntityAttribute ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string answer; std::string entityId = compV[2]; std::string entityType = ciP->uriParam[URI_PARAM_ENTITY_TYPE]; std::string attributeName = compV[4]; StatusCode response; // 1. Fill in UpdateContextRequest from URL-path components parseDataP->upcr.res.fill(entityId, entityType, "false", attributeName, "", "DELETE"); // 2. Call postUpdateContext standard service routine postUpdateContext(ciP, components, compV, parseDataP); // 3. Translate UpdateContextResponse to StatusCode response.fill(parseDataP->upcrs.res); // 4. Cleanup and return result TIMED_RENDER(answer = response.render("", false, false)); response.release(); parseDataP->upcr.res.release(); return answer; }
/* **************************************************************************** * * deleteAttributeValueInstance - * * DELETE /v1/contextEntities/{entity::id}/attributes/{attribute::name}/{metaID} * DELETE /ngsi10/contextEntities/{entity::id}/attributes/{attribute::name}/{metaID} * * Payload In: None * Payload Out: StatusCode * * Mapped Standard Operation: UpdateContextRequest/DELETE * * URI params: * - 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. * * 01. URI parameters * 02. Fill in UpdateContextRequest * 03. Call postUpdateContext standard service routine * 04. Translate UpdateContextResponse to StatusCode * 05. Cleanup and return result * */ std::string deleteAttributeValueInstance ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { StatusCode response; std::string answer; std::string entityId = compV[2]; std::string attributeName = compV[4]; std::string metaId = compV[5]; std::string entityType; // 01. URI parameters entityType = ciP->uriParam[URI_PARAM_ENTITY_TYPE]; // 02. Fill in UpdateContextRequest parseDataP->upcr.res.fill(entityId, entityType, "false", attributeName, metaId, "DELETE"); // 03. Call postUpdateContext standard service routine postUpdateContext(ciP, components, compV, parseDataP); // 04. Translate UpdateContextResponse to StatusCode response.fill(parseDataP->upcrs.res); // 05. Cleanup and return result TIMED_RENDER(answer = response.render("", false, false)); response.release(); parseDataP->upcr.res.release(); return answer; }
/* **************************************************************************** * * deleteIndividualContextEntity - * * Corresponding Standard Operation: UpdateContext/DELETE * * DELETE /v1/contextEntities/{entityId::id} * * Payload In: None * Payload Out: StatusCode * * URI parameters: * - 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. URI params * 01. Fill in UpdateContextRequest from URL-data + URI params * 02. Call postUpdateContext standard service routine * 03. Translate UpdateContextResponse to StatusCode * 04. If not found, put entity info in details * 05. Cleanup and return result */ std::string deleteIndividualContextEntity ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string answer; std::string entityId = compV[2]; std::string entityType = ciP->uriParam[URI_PARAM_ENTITY_TYPE]; StatusCode response; // 01. Fill in UpdateContextRequest fromURL-data + URI params parseDataP->upcr.res.fill(entityId, entityType, "false", "", "", "DELETE"); // 02. Call postUpdateContext standard service routine answer = postUpdateContext(ciP, components, compV, parseDataP); // 03. Translate UpdateContextResponse to StatusCode response.fill(parseDataP->upcrs.res); // 04. If not found, put entity info in details if ((response.code == SccContextElementNotFound) && (response.details == "")) { response.details = entityId; } // 05. Cleanup and return result TIMED_RENDER(answer = response.render(ciP->outFormat, "", false, false)); response.release(); parseDataP->upcr.res.release(); return answer; }
/* **************************************************************************** * * deleteAllEntitiesWithTypeAndId - * * DELETE /v1/contextEntities/type/{entity::type}/id/{entity::id} * * Payload In: None * Payload Out: StatusCode * * URI parameters: * - entity::type=TYPE (must coincide with type in URL-path) * - !exist=entity::type (if set - error -- entity::type cannot be empty) * - exist=entity::type (not supported - ok if present, ok if not present ...) * * 01. Get values from URL (+ entityId::type, exist, !exist) * 02. Check validity of URI params * 03. Fill in UpdateContextRequest * 04. Call Standard Operation * 05. Fill in response from UpdateContextResponse * 06. Cleanup and return result */ std::string deleteAllEntitiesWithTypeAndId ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string entityType = compV[3]; std::string entityId = compV[5]; EntityTypeInfo typeInfo = EntityTypeEmptyOrNotEmpty; std::string typeNameFromUriParam = ciP->uriParam[URI_PARAM_ENTITY_TYPE]; std::string answer; StatusCode response; // 01. Get values from URL (+ entityId::type, exist, !exist) if (ciP->uriParam[URI_PARAM_NOT_EXIST] == URI_PARAM_ENTITY_TYPE) { typeInfo = EntityTypeEmpty; } else if (ciP->uriParam[URI_PARAM_EXIST] == URI_PARAM_ENTITY_TYPE) { typeInfo = EntityTypeNotEmpty; } // 02. Check validity of URI params if (typeInfo == EntityTypeEmpty) { alarmMgr.badInput(clientIp, "entity::type cannot be empty for this request"); response.fill(SccBadRequest, "entity::type cannot be empty for this request"); TIMED_RENDER(answer = response.render("", false, false)); return answer; } else if ((typeNameFromUriParam != entityType) && (typeNameFromUriParam != "")) { alarmMgr.badInput(clientIp, "non-matching entity::types in URL"); response.fill(SccBadRequest, "non-matching entity::types in URL"); TIMED_RENDER(answer = response.render("", false, false)); return answer; } // 03. Fill in UpdateContextRequest parseDataP->upcr.res.fill(entityId, entityType, "", "", "", "DELETE"); // 04. Call Standard Operation postUpdateContext(ciP, components, compV, parseDataP); // 05. Fill in response from UpdateContextResponse response.fill(parseDataP->upcrs.res); // 06. Cleanup and return result TIMED_RENDER(answer = response.render("", false, false)); parseDataP->upcr.res.release(); response.release(); return answer; }
/* **************************************************************************** * * postAttributeValueInstanceWithTypeAndId - * * POST /ngsi10/contextEntities/type/{type}/id/{id}/attributes/{attributeName}/{valueID} * * Payload: UpdateContextAttributeRequest */ std::string postAttributeValueInstanceWithTypeAndId ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { UpdateContextRequest request; UpdateContextResponse response; std::string entityType = compV[3]; std::string entityId = compV[5]; std::string attributeName = compV[7]; std::string valueId = compV[8]; UpdateContextAttributeRequest* upcarP = &parseDataP->upcar.res; bool idFound = false; // // Any metadata ID in the payload? // // If so, the value must be equal to the {valueID} of the URL // for (unsigned int ix = 0; ix < upcarP->metadataVector.size(); ++ix) { Metadata* mP = upcarP->metadataVector.get(ix); if (mP->name == "ID") { if (mP->value != valueId) { std::string out; out = restErrorReplyGet(ciP, ciP->outFormat, "", "StatusCode", SccBadRequest, std::string("unmatching metadata ID value URI/payload: '") + valueId + "' vs '" + mP->value + "'"); return out; } else { idFound = true; } } } ContextAttribute* attributeP = new ContextAttribute(attributeName, "", upcarP->contextValue); ContextElement* ceP = new ContextElement(); // Copy the metadata vector of the input payload attributeP->metadataVector.fill((MetadataVector*) &upcarP->metadataVector); // If no "ID" metadata was in the payload, add it if (idFound == false) { Metadata* mP = new Metadata("ID", "", valueId); attributeP->metadataVector.push_back(mP); } // Filling the rest of the structure for mongoUpdateContext ceP->entityId.fill(entityId, entityType, "false"); ceP->attributeDomainName.set(""); ceP->contextAttributeVector.push_back(attributeP); request.contextElementVector.push_back(ceP); request.updateActionType.set("APPEND"); response.errorCode.code = SccNone; ciP->httpStatusCode = mongoUpdateContext(&request, &response, ciP->tenant, ciP->servicePathV, ciP->uriParam); StatusCode statusCode; if (response.contextElementResponseVector.size() == 0) { statusCode.fill(SccContextElementNotFound, std::string("Entity-Attribute pair: '") + entityId + "-" + attributeName + "'"); } else if (response.contextElementResponseVector.size() == 1) { ContextElementResponse* cerP = response.contextElementResponseVector.get(0); if (response.errorCode.code != SccNone) { statusCode.fill(&response.errorCode); } else if (cerP->statusCode.code != SccNone) { statusCode.fill(&cerP->statusCode); } else { statusCode.fill(SccOk); } } else { statusCode.fill(SccReceiverInternalError, "More than one response from postAttributeValueInstanceWithTypeAndId::mongoUpdateContext"); } request.release(); return statusCode.render(ciP->outFormat, "", false, false); }
/* **************************************************************************** * * postAttributeValueInstanceWithTypeAndId - * * POST /v1/contextEntities/type/{entity::type}/id/{entity::id}/attributes/{attribute::name}/{metaID} * POST /ngsi10/contextEntities/type/{entity::type}/id/{entity::id}/attributes/{attribute::name}/{metaID} * * Payload In: UpdateContextAttributeRequest * Payload Out: StatusCode * * Mapped Standard Operation: UpdateContextRequest/APPEND * * URI parameters * - 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. Get values from URI path * 01. Get values URI parameters * 02. Check validity of URI params VS URI path components * 03. Check validity of path components VS payload * 04. Fill in UpdateContextRequest * 05. Call postUpdateContext * 06. Fill in StatusCode from UpdateContextResponse * 07. Render result * 08. Cleanup and return result */ std::string postAttributeValueInstanceWithTypeAndId ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string entityType = compV[3]; std::string entityId = compV[5]; std::string attributeName = compV[7]; std::string metaID = compV[8]; std::string entityTypeFromUriParam; StatusCode response; std::string answer; // 01. Get values URI parameters entityTypeFromUriParam = ciP->uriParam[URI_PARAM_ENTITY_TYPE]; // 02. Check validity of URI params VS URI path components if ((entityTypeFromUriParam != "") && (entityTypeFromUriParam != entityType)) { LM_W(("Bad Input non-matching entity::types in URL")); response.fill(SccBadRequest, "non-matching entity::types in URL"); answer = response.render(ciP->outFormat, "", false, false); parseDataP->upcar.res.release(); return answer; } // 03. Check validity of path components VS payload Metadata* mP = parseDataP->upcar.res.metadataVector.lookupByName("ID"); if ((mP != NULL) && (mP->value != metaID)) { std::string details = "unmatching metadata ID value URI/payload: /" + metaID + "/ vs /" + mP->value + "/"; response.fill(SccBadRequest, details); answer = response.render(ciP->outFormat, "", false, false); parseDataP->upcar.res.release(); return answer; } // 04. Fill in UpdateContextRequest parseDataP->upcr.res.fill(&parseDataP->upcar.res, entityId, entityType, attributeName, metaID, "APPEND"); // 05. Call postUpdateContext postUpdateContext(ciP, components, compV, parseDataP); // 06. Fill in StatusCode from UpdateContextResponse response.fill(parseDataP->upcrs.res); // 07. Render result answer = response.render(ciP->outFormat, "", false, false); // 08. Cleanup and return result response.release(); parseDataP->upcar.res.release(); parseDataP->upcr.res.release(); parseDataP->upcrs.res.release(); return answer; }
/* **************************************************************************** * * deleteAttributeValueInstanceWithTypeAndId - * * DELETE /ngsi10/contextEntities/type/{type}/id/{id}/attributes/{attributeName}/{valueID} */ std::string deleteAttributeValueInstanceWithTypeAndId ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { UpdateContextRequest request; UpdateContextResponse response; std::string entityType = compV[3]; std::string entityId = compV[5]; std::string attributeName = compV[7]; std::string valueId = compV[8]; ContextAttribute* attributeP = new ContextAttribute(attributeName, "", "false"); Metadata* mP = new Metadata("ID", "", valueId); ContextElement* ceP = new ContextElement(); attributeP->metadataVector.push_back(mP); ceP->entityId.fill(entityId, entityType, "false"); ceP->attributeDomainName.set(""); ceP->contextAttributeVector.push_back(attributeP); request.contextElementVector.push_back(ceP); request.updateActionType.set("DELETE"); response.errorCode.code = SccNone; ciP->httpStatusCode = mongoUpdateContext(&request, &response, ciP->tenant, ciP->servicePathV, ciP->uriParam); StatusCode statusCode; if (response.contextElementResponseVector.size() == 0) { statusCode.fill(SccContextElementNotFound, std::string("Entity-Attribute pair: '") + entityId + "-" + attributeName + "'"); } else if (response.contextElementResponseVector.size() == 1) { ContextElementResponse* cerP = response.contextElementResponseVector.get(0); if (response.errorCode.code != SccNone) { statusCode.fill(&response.errorCode); } else if (cerP->statusCode.code != SccNone) { statusCode.fill(&cerP->statusCode); } else { statusCode.fill(SccOk); } } else { statusCode.fill(SccReceiverInternalError, "More than one response from deleteAttributeValueInstanceWithTypeAndId::mongoUpdateContext"); } request.release(); return statusCode.render(ciP->outFormat, "", false, false); }
/* **************************************************************************** * * postIndividualContextEntityAttributeWithTypeAndId - * * POST /v1/contextEntities/type/{entity::type}/id/{entity::id}/attributes/{attribute::name} * * Payload In: UpdateContextAttributeRequest * Payload Out: StatusCode * * URI parameters: * - entity::type=XXX (must coincide with entity::type in URL) * - !exist=entity::type (if set - error -- entity::type cannot be empty) * - exist=entity::type (not supported - ok if present, ok if not present ...) * x attributesFormat=object (cannot be supported as the response is a StatusCode) * * 01. Get values from URL (entityId::type, esist, !exist) * 02. Check validity of URI params * 03. Fill in UpdateContextRequest * 04. Call standard operation postUpdateContext * 05. Translate UpdateContextResponse to StatusCode * 06. Cleanup and return result */ std::string postIndividualContextEntityAttributeWithTypeAndId ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string entityType = compV[3]; std::string entityId = compV[5]; std::string attributeName = compV[7]; std::string entityTypeFromUriParam = ciP->uriParam[URI_PARAM_ENTITY_TYPE]; EntityTypeInfo typeInfo = EntityTypeEmptyOrNotEmpty; std::string answer; StatusCode response; // 01. Get values from URL (entityId::type, esist, !exist) if (ciP->uriParam[URI_PARAM_NOT_EXIST] == URI_PARAM_ENTITY_TYPE) { typeInfo = EntityTypeEmpty; } else if (ciP->uriParam[URI_PARAM_EXIST] == URI_PARAM_ENTITY_TYPE) { typeInfo = EntityTypeNotEmpty; } // 02. Check validity of URI params ... // And if OK; // 03. Fill in UpdateContextRequest // 04. Call standard operation postUpdateContext // 05. Translate UpdateContextResponse to StatusCode // if (typeInfo == EntityTypeEmpty) { response.fill(SccBadRequest, "entity::type cannot be empty for this request"); alarmMgr.badInput(clientIp, "entity::type cannot be empty for this request"); } else if ((entityTypeFromUriParam != entityType) && (entityTypeFromUriParam != "")) { response.fill(SccBadRequest, "non-matching entity::types in URL"); alarmMgr.badInput(clientIp, "non-matching entity::types in URL"); } else { // 03. Fill in UpdateContextRequest parseDataP->upcr.res.fill(&parseDataP->upcar.res, entityId, entityType, attributeName, "", "APPEND"); // 04. Call standard operation postUpdateContext postUpdateContext(ciP, components, compV, parseDataP); // 05. Translate UpdateContextResponse to StatusCode response.fill(parseDataP->upcrs.res); parseDataP->upcr.res.release(); } // 06. Cleanup and return result TIMED_RENDER(answer = response.render(ciP->outFormat, "", false, false)); parseDataP->upcar.res.release(); parseDataP->upcrs.res.release(); return answer; }