Exemplo n.º 1
0
/* ****************************************************************************
*
* 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;
}