示例#1
0
/* ****************************************************************************
*
* MetadataVector::fill - 
*/
void MetadataVector::fill(MetadataVector& mV)
{
  for (unsigned int ix = 0; ix < mV.size(); ++ix)
  {
    Metadata* mP = new Metadata(mV.get(ix));

    push_back(mP);
  }
}
/* ****************************************************************************
*
* 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;
}
/*****************************************************************************
*
* processAssociations -
*
*/
static bool processAssociations(MetadataVector mdV, std::string* err, std::string tenant)
{
    // FIXME: first version of associations doesn't support association update

    DBClientBase* connection = NULL;

    for (unsigned int ix = 0; ix < mdV.size(); ++ix) {

        Metadata* md = mdV.get(ix);
        if (md->type != "Association") {
            continue;
        }

        LM_T(LmtMongo, ("Processing association metadata"));

        std::string name      = md->name;
        std::string srcEnId   = md->association.entityAssociation.source.id;
        std::string srcEnType = md->association.entityAssociation.source.type;
        std::string tgtEnId   = md->association.entityAssociation.target.id;
        std::string tgtEnType = md->association.entityAssociation.target.type;

        BSONObj srcEn;
        if (srcEnType == "") {
            srcEn = BSON(ASSOC_ENT_ID << srcEnId);
        }
        else {
            srcEn = BSON(ASSOC_ENT_ID << srcEnId << ASSOC_ENT_TYPE << srcEnType);
        }

        BSONObj tgtEn;
        if (tgtEnType == "") {
            tgtEn = BSON(ASSOC_ENT_ID << tgtEnId);
        }
        else {
            tgtEn = BSON(ASSOC_ENT_ID << tgtEnId << ASSOC_ENT_TYPE << tgtEnType);
        }

        BSONArrayBuilder attrs;
        for (unsigned int jx = 0; jx < md->association.attributeAssociationList.size(); ++jx) {
            std::string srcAtt = md->association.attributeAssociationList.get(jx)->source;
            std::string tgtAtt = md->association.attributeAssociationList.get(jx)->target;
            attrs.append(BSON(ASSOC_ATTRS_SOURCE << srcAtt << ASSOC_ATTRS_TARGET << tgtAtt));
        }

        BSONObj doc = BSON("_id" << name << ASSOC_SOURCE_ENT << srcEn << ASSOC_TARGET_ENT << tgtEn << ASSOC_ATTRS << attrs.arr());
        LM_T(LmtMongo, ("insert() in '%s' collection: '%s'", getAssociationsCollectionName(tenant).c_str(), doc.toString().c_str()));
        try
        {
            connection = getMongoConnection();
            connection->insert(getAssociationsCollectionName(tenant).c_str(), doc);
            releaseMongoConnection(connection);

            LM_I(("Database Operation Successful (%s)", doc.toString().c_str()));
        }
        catch (const DBException &e)
        {
            releaseMongoConnection(connection);

            *err = e.what();
            LM_E(("Database Error ('insert \"%s\" in %s', '%s')", doc.toString().c_str(), getAssociationsCollectionName(tenant).c_str(), e.what()));

            return false;
        }
        catch (...)
        {
            releaseMongoConnection(connection);

            *err = "Generic Exception from mongo";
            LM_E(("Database Error ('insert \"%s\" in %s', '%s')", doc.toString().c_str(), getAssociationsCollectionName(tenant).c_str(), "generic error"));

            return false;
        }
    }

    return true;
}