/* ****************************************************************************
*
* 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;
}
Example #3
0
/* ****************************************************************************
*
* 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);
}
Example #4
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;
}