/* ****************************************************************************
*
* addContextProviders -
*
* This function takes a CRR vector and adds the Context Providers in the CER vector
* (except the ones corresponding to some locally found attribute, i.e. info already in the
* CER vector)
*
* The limitReached parameter is to prevent the addition of new entities, which is needed in the case of the pagination
* limit has been reached with local entities.
*
* The enP parameter is optional. If not NULL, then before adding a CPr the function checks that the
* containting CRR matches the entity (this is used for funcionality related to  "generic queries", see
* processGenericEntities() function)
*
*/
void addContextProviders(ContextElementResponseVector& cerV, ContextRegistrationResponseVector& crrV, bool limitReached, EntityId* enP = NULL)
{
  for (unsigned int ix = 0; ix < crrV.size(); ++ix)
  {
    ContextRegistration cr = crrV.get(ix)->contextRegistration;

    /* In the case a "filtering" entity was provided, check that the current CRR matches or skip to next CRR */
    if (enP != NULL && !matchEntityInCrr(cr, enP)) {
      continue;
    }

    if (cr.contextRegistrationAttributeVector.size() == 0)
    {
      if (!limitReached)
      {
        /* Registration without attributes */
        for (unsigned int eIx = 0; eIx < cr.entityIdVector.size(); ++eIx)
        {
          addContextProviderEntity(cerV, cr.entityIdVector.get(eIx), cr.providingApplication);
        }
      }
    }
    else
    {
      /* Registration with attributes */
      for (unsigned int eIx = 0; eIx < cr.entityIdVector.size(); ++eIx)
      {
        for (unsigned int aIx = 0; aIx < cr.contextRegistrationAttributeVector.size(); ++aIx)
        {
          addContextProviderAttribute(cerV, cr.entityIdVector.get(eIx), cr.contextRegistrationAttributeVector.get(aIx), cr.providingApplication, limitReached);
        }
      }
    }
  }
}
Esempio n. 2
0
/* ****************************************************************************
*
* equalContextRegistrationResponseVector -
*
*/
static bool equalContextRegistrationResponseVector(ContextRegistrationResponseVector crrExpectedV, ContextRegistrationResponseVector crrArgV) {

    /* Check vector size */
    if (crrExpectedV.size() != crrArgV.size()) {
        LM_M(("different sizes: expected %d, actual %d", crrExpectedV.size(), crrArgV.size()));
        return false;
    }

    /* Check that every context registration in 'crrArgV' is in 'crrExpectedV'. Order doesn't matter */
    for (unsigned int ix = 0; ix < crrArgV.size(); ++ix) {
        bool contextRegistrationMatch = false;
        for (unsigned int jx = 0; jx < crrExpectedV.size(); ++jx) {
            ContextRegistration crArg = crrArgV.get(ix)->contextRegistration;
            ContextRegistration crExpected = crrExpectedV.get(jx)->contextRegistration;
            LM_M(("%d == %d?", ix, jx));
            if (!equalEntityIdVector(crExpected.entityIdVector, crArg.entityIdVector)) {
                LM_M(("entity vector doesn't match in ContextRegistrationResponseVector comparison, continue..."));
                continue; /* loop in jx */
            }

            if (!equalContextRegistrationAttributeVector(crExpected.contextRegistrationAttributeVector, crArg.contextRegistrationAttributeVector)) {
                LM_M(("context registration attribute vector doesn't match in ContextRegistrationResponseVector comparison, continue..."));
                continue; /* loop in jx */
            }

            if (crExpected.providingApplication.get() == crArg.providingApplication.get()) {
                contextRegistrationMatch = true;
                LM_M(("context registration match in ContextRegistrationResponseVector comparison, check next one..."));
                break; /* loop in jx */
            }
        }

        if (!contextRegistrationMatch) {
            LM_M(("after looking everyone, context registration doesn't matches in ContextElementResponseVector comparison"));
            return false;
        }
    }

    LM_M(("ContextElementResponseVector comparison ok"));
    return true;

}
/* ****************************************************************************
*
* associationsDiscoverContextAvailability -
*/
static HttpStatusCode associationsDiscoverContextAvailability
(
  DiscoverContextAvailabilityRequest*   requestP,
  DiscoverContextAvailabilityResponse*  responseP,
  const std::string&                    scope,
  const std::string&                    tenant,
  int                                   offset,
  int                                   limit,
  bool                                  details,
  const std::vector<std::string>&       servicePathV
)
{
    if (scope == SCOPE_VALUE_ASSOC_ALL)
    {
        LM_W(("Bad Input (%s scope not supported)", SCOPE_VALUE_ASSOC_ALL));
        responseP->errorCode.fill(SccNotImplemented, std::string("Not supported scope: '") + SCOPE_VALUE_ASSOC_ALL + "'");
        return SccOk;
    }

    MetadataVector mdV;
    std::string err;
    if (!associationsQuery(&requestP->entityIdVector, &requestP->attributeList, scope, &mdV, &err, tenant, offset, limit, details, servicePathV))
    {
        mdV.release();
        responseP->errorCode.fill(SccReceiverInternalError, std::string("Database error: ") + err);
        return SccOk;
    }

    LM_T(LmtPagination, ("Offset: %d, Limit: %d, Details: %s", offset, limit, (details == true)? "true" : "false"));

    /* Query for associated entities */
    for (unsigned int ix = 0; ix < mdV.size(); ++ix) {
        /* Each association involves a registrationsQuery() operation, accumulating the answer in
         * responseP->responseVector */
        Metadata* md = mdV.get(ix);
        EntityIdVector enV;
        AttributeList attrL;

        EntityId en;
        if (scope == SCOPE_VALUE_ASSOC_SOURCE) {
            en = EntityId(md->association.entityAssociation.source.id, md->association.entityAssociation.source.type);
        }
        else {  // SCOPE_VALUE_ASSOC_TARGET
            en = EntityId(md->association.entityAssociation.target.id, md->association.entityAssociation.target.type);
        }
        enV.push_back(&en);

        for (unsigned int jx = 0; jx < md->association.attributeAssociationList.size(); ++jx) {
            if (scope == SCOPE_VALUE_ASSOC_SOURCE) {
                attrL.push_back(md->association.attributeAssociationList.get(jx)->source);
            }
            else {
                attrL.push_back(md->association.attributeAssociationList.get(jx)->target);
            }
        }

        ContextRegistrationResponseVector crrV;
        if (!registrationsQuery(enV, attrL, &crrV, &err, tenant, servicePathV))
        {
            responseP->errorCode.fill(SccReceiverInternalError, err);
            mdV.release();
            return SccOk;
        }

        /* Accumulate in responseP */
        for (unsigned int jx = 0; jx < crrV.size(); ++jx) {
            responseP->responseVector.push_back(crrV.get(jx));
        }
    }

    if (responseP->responseVector.size() == 0)
    {
      mdV.release();
      responseP->errorCode.fill(SccContextElementNotFound, "Could not query association with combination of entity/attribute");
      LM_RE(SccOk, (responseP->errorCode.details.c_str()));
    }

    /* Set association metadata as final ContextRegistrationResponse */
    ContextRegistrationResponse* crrMd = new ContextRegistrationResponse();
    crrMd->contextRegistration.providingApplication.set("http://www.fi-ware.eu/NGSI/association");
    crrMd->contextRegistration.registrationMetadataVector = mdV;
    responseP->responseVector.push_back(crrMd);

    return SccOk;
}