/* **************************************************************************** * * putEntityAttributeValue - * * PUT /v2/entities/<id>/attrs/<attrName>/value * * Payload In: AttributeValue * Payload Out: None * * * 01. Fill in UpdateContextRequest with data from URI and payload * 02. Call standard op postUpdateContext * 03. Check output from mongoBackend - any errors? * 04. Prepare HTTP headers * 05. Cleanup and return result */ std::string putEntityAttributeValue ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string entityId = compV[2]; std::string attributeName = compV[4]; std::string type = ciP->uriParam["type"]; if (forbiddenIdChars(ciP->apiVersion, entityId.c_str(), NULL) || forbiddenIdChars(ciP->apiVersion, attributeName.c_str(), NULL)) { OrionError oe(SccBadRequest, ERROR_DESC_BAD_REQUEST_INVALID_CHAR_URI, ERROR_BAD_REQUEST); ciP->httpStatusCode = oe.code; return oe.toJson(); } // 01. Fill in UpdateContextRequest with data from URI and payload parseDataP->av.attribute.name = attributeName; parseDataP->av.attribute.type = ""; // Overwrite 'none', as no type can be given in 'value' payload parseDataP->av.attribute.onlyValue = true; std::string err = parseDataP->av.attribute.check(ciP->apiVersion, ciP->requestType); if (err != "OK") { OrionError oe(SccBadRequest, err, "BadRequest"); ciP->httpStatusCode = oe.code; return oe.toJson(); } parseDataP->upcr.res.fill(entityId, &parseDataP->av.attribute, ActionTypeUpdate, type); // 02. Call standard op postUpdateContext postUpdateContext(ciP, components, compV, parseDataP); // 03. Check output from mongoBackend std::string answer = ""; if (parseDataP->upcrs.res.oe.code != SccNone) { TIMED_RENDER(answer = parseDataP->upcrs.res.oe.toJson()); ciP->httpStatusCode = parseDataP->upcrs.res.oe.code; } else { ciP->httpStatusCode = SccNoContent; } // 05. Cleanup and return result parseDataP->upcr.res.release(); return answer; }
/* **************************************************************************** * * getEntityAttribute - * * GET /v2/entities/:id:/attrs/:attrName: * * Payload In: None * Payload Out: Entity Attribute * * * 01. Fill in QueryContextRequest * 02. Call standard op postQueryContext * 03. Render Entity Attribute response * 04. Cleanup and return result */ std::string getEntityAttribute ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string type = ciP->uriParam["type"]; std::string answer; Attribute attribute; if (forbiddenIdChars(ciP->apiVersion, compV[2].c_str() , NULL) || (forbiddenIdChars(ciP->apiVersion, compV[4].c_str() , NULL))) { OrionError oe(SccBadRequest, INVAL_CHAR_URI, "BadRequest"); ciP->httpStatusCode = oe.code; return oe.toJson(); } // 01. Fill in QueryContextRequest parseDataP->qcr.res.fill(compV[2], type, "false", EntityTypeEmptyOrNotEmpty, ""); parseDataP->qcr.res.metadataList.fill(ciP->uriParam[URI_PARAM_METADATA]); // 02. Call standard op postQueryContext postQueryContext(ciP, components, compV, parseDataP); // 03. Render entity attribute response attribute.fill(&parseDataP->qcrs.res, compV[4]); TIMED_RENDER(answer = attribute.render(ciP, EntityAttributeResponse)); if (attribute.oe.reasonPhrase == "TooManyResults") { ciP->httpStatusCode = SccConflict; } else if (attribute.oe.reasonPhrase == "NotFound") { ciP->httpStatusCode = SccContextElementNotFound; // Attribute to be precise! } else { // the same of the wrapped operation ciP->httpStatusCode = parseDataP->qcrs.res.errorCode.code; } // 04. Cleanup and return result parseDataP->qcr.res.release(); return answer; }
/* **************************************************************************** * * Entity::check - */ std::string Entity::check(ConnectionInfo* ciP, RequestType requestType) { ssize_t len; char errorMsg[128]; if ((requestType == EntitiesRequest) && (id == "")) { return "No Entity ID"; } if ( (len = strlen(id.c_str())) > MAX_ID_LEN) { snprintf(errorMsg, sizeof errorMsg, "entity id length: %zd, max length supported: %d", len, MAX_ID_LEN); alarmMgr.badInput(clientIp, errorMsg); return std::string(errorMsg); } if (forbiddenIdChars(ciP->apiVersion, id.c_str())) { alarmMgr.badInput(clientIp, "found a forbidden character in the id of an entity"); return "Invalid characters in entity id"; } if ( (len = strlen(type.c_str())) > MAX_ID_LEN) { snprintf(errorMsg, sizeof errorMsg, "entity type length: %zd, max length supported: %d", len, MAX_ID_LEN); alarmMgr.badInput(clientIp, errorMsg); return std::string(errorMsg); } if (ciP->apiVersion == "v2" && (len = strlen(type.c_str())) < MIN_ID_LEN) { snprintf(errorMsg, sizeof errorMsg, "entity type length: %zd, min length supported: %d", len, MIN_ID_LEN); alarmMgr.badInput(clientIp, errorMsg); return std::string(errorMsg); } if (forbiddenIdChars(ciP->apiVersion, type.c_str())) { alarmMgr.badInput(clientIp, "found a forbidden character in the type of an entity"); return "Invalid characters in entity type"; } if (forbiddenChars(isPattern.c_str())) { alarmMgr.badInput(clientIp, "found a forbidden character in the pattern of an entity"); return "Invalid characters in entity isPattern"; } return attributeVector.check(ciP, requestType, "", "", 0); }
/* **************************************************************************** * * putEntity - * * PUT /v2/entities * * Payload In: Entity * Payload Out: None * * URI parameters: * - * * 01. Fill in UpdateContextRequest * 02. Call standard op putUpdateContext * 03. Check output from mongoBackend - any errors? * 04. Prepare HTTP headers * 05. Cleanup and return result */ std::string putEntity ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { Entity* eP = &parseDataP->ent.res; eP->id = compV[2]; eP->type = ciP->uriParam["type"]; if (forbiddenIdChars(ciP->apiVersion, compV[2].c_str() , NULL)) { OrionError oe(SccBadRequest, ERROR_DESC_BAD_REQUEST_INVALID_CHAR_URI, ERROR_BAD_REQUEST); ciP->httpStatusCode = oe.code; return oe.toJson(); } // 01. Fill in UpdateContextRequest parseDataP->upcr.res.fill(eP, ActionTypeReplace); // 02. Call standard op postUpdateContext postUpdateContext(ciP, components, compV, parseDataP); // 03. Check error std::string answer = ""; if (parseDataP->upcrs.res.oe.code != SccNone ) { TIMED_RENDER(answer = parseDataP->upcrs.res.oe.toJson()); ciP->httpStatusCode = parseDataP->upcrs.res.oe.code; } else { ciP->httpStatusCode = SccNoContent; } // 04. Cleanup and return result eP->release(); return answer; }
/* **************************************************************************** * * getEntity - * * GET /v2/entities/:id:[?attrs=:list:] * * Payload In: None * Payload Out: Entity * * * Fill in QueryContextRequest * Call standard op postQueryContext * Render Entity response * Cleanup and return result */ std::string getEntity ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string attrs = ciP->uriParam["attrs"]; std::string type = ciP->uriParam["type"]; if (forbiddenIdChars(ciP->apiVersion, compV[2].c_str() , NULL)) { OrionError oe(SccBadRequest, INVAL_CHAR_URI); return oe.render(ciP, ""); } // Fill in QueryContextRequest parseDataP->qcr.res.fill(compV[2], type, "false", EntityTypeEmptyOrNotEmpty, ""); if (attrs != "") { std::vector<std::string> attrsV; stringSplit(attrs, ',', attrsV); for (std::vector<std::string>::const_iterator it = attrsV.begin(); it != attrsV.end(); ++it) { parseDataP->qcr.res.attributeList.push_back_if_absent(*it); } } // Call standard op postQueryContext postQueryContext(ciP, components, compV, parseDataP); // Render entity response Entity entity; // If request was for /entities/<<id>>/attrs, type and id should not be shown if (compV.size() == 4 && compV[3] == "attrs") { entity.hideIdAndType(); } entity.fill(&parseDataP->qcrs.res); std::string answer; TIMED_RENDER(answer = entity.render(ciP, EntityResponse)); if (parseDataP->qcrs.res.errorCode.code == SccOk && parseDataP->qcrs.res.contextElementResponseVector.size() > 1) { // No problem found, but we expect only one entity ciP->httpStatusCode = SccConflict; } else { // the same of the wrapped operation ciP->httpStatusCode = parseDataP->qcrs.res.errorCode.code; } // 04. Cleanup and return result entity.release(); parseDataP->qcr.res.release(); return answer; }