/* **************************************************************************** * * 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); } } } } }
/* **************************************************************************** * * 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; }