sai_status_t SaiPlayer::handle_bulk_generic()

in saiplayer/SaiPlayer.cpp [1437:1608]


sai_status_t SaiPlayer::handle_bulk_generic(
        _In_ sai_object_type_t objectType,
        _In_ const std::vector<std::string>& strObjectIds,
        _In_ sai_common_api_t api,
        _In_ const std::vector<std::shared_ptr<SaiAttributeList>>& attributes,
        _In_ const std::vector<sai_status_t>& expectedStatuses)
{
    SWSS_LOG_ENTER();

    std::vector<sai_object_id_t> objectIds;

    for (const auto& oid: strObjectIds)
    {
        sai_object_id_t objectId;
        sai_deserialize_object_id(oid, objectId);

        if (api != SAI_COMMON_API_BULK_CREATE)
        {
            // when creating OID objects, ID don't exists yet, it needs to be created
            // and after success create, it should be matched to local redis db
            objectId = translate_local_to_redis(objectId);
        }

        objectIds.push_back(objectId);
    }

    std::vector<sai_status_t> statuses;

    statuses.resize(expectedStatuses.size());

    if (api == SAI_COMMON_API_BULK_CREATE)
    {
        std::vector<sai_object_id_t> oids;

        oids.resize(expectedStatuses.size());

        std::vector<uint32_t> attr_count;

        std::vector<const sai_attribute_t*> attr_list;

        // object can have multiple attributes, so we need to handle them all
        for (const auto &alist: attributes)
        {
            attr_list.push_back(alist->get_attr_list());
            attr_count.push_back(alist->get_attr_count());
        }

        SWSS_LOG_INFO("executing BULK create %s with %zu entries",
                sai_serialize_object_type(objectType).c_str(),
                objectIds.size());

        // get switch ID from first local object
        sai_object_id_t localSwitchId = m_sai->switchIdQuery(objectIds[0]);
        sai_object_id_t switchId = translate_local_to_redis(localSwitchId);

        sai_status_t status = m_sai->bulkCreate(
                objectType,
                switchId,
                (uint32_t)oids.size(),
                attr_count.data(),
                attr_list.data(),
                SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, // TODO we need to get that from recording
                oids.data(),
                statuses.data());

        for (size_t i = 0; i < statuses.size(); ++i)
        {
            if (statuses[i] != expectedStatuses[i])
            {
                /*
                 * If recorded statuses are different than received, throw
                 * exception since data don't match.
                 */

                SWSS_LOG_THROW("recorded status is %s but returned is %s on %s",
                        sai_serialize_status(expectedStatuses[i]).c_str(),
                        sai_serialize_status(statuses[i]).c_str(),
                        strObjectIds[i].c_str());
            }

            if (statuses[i] == SAI_STATUS_SUCCESS)
            {
                // object was created, we need to match local id and redis id
                match_redis_with_rec(oids[i], objectIds[i]);
            }
        }

        return status;
    }
    else if (api == SAI_COMMON_API_BULK_REMOVE)
    {
        SWSS_LOG_INFO("executing BULK remove %s with %zu entries",
                sai_serialize_object_type(objectType).c_str(),
                objectIds.size());

        sai_status_t status = m_sai->bulkRemove(
                objectType,
                (uint32_t)objectIds.size(),
                objectIds.data(),
                SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, // TODO we need to get that from recording
                statuses.data());

        // even if API will fail, we swill need to compare all statuses for each entry

        for (size_t i = 0; i < statuses.size(); ++i)
        {
            if (statuses[i] != expectedStatuses[i])
            {
                /*
                 * If recorded statuses are different than received, throw
                 * exception since data don't match.
                 */

                SWSS_LOG_THROW("recorded status is %s but returned is %s on %s",
                        sai_serialize_status(expectedStatuses[i]).c_str(),
                        sai_serialize_status(statuses[i]).c_str(),
                        strObjectIds[i].c_str());
            }
        }

        return status;
    }
    else if (api == SAI_COMMON_API_BULK_SET)
    {
        std::vector<sai_attribute_t> attrs;

        for (const auto &a: attributes)
        {
            // set has only 1 attribute, so we can just join them nicely here.

            attrs.push_back(a->get_attr_list()[0]);
        }

        SWSS_LOG_INFO("executing BULK set %s with %zu entries",
                sai_serialize_object_type(objectType).c_str(),
                objectIds.size());

        sai_status_t status = m_sai->bulkSet(
                objectType,
                (uint32_t)objectIds.size(),
                objectIds.data(),
                attrs.data(),
                SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, // TODO we need to get that from recording
                statuses.data());

        // even if API will fail, we swill need to compare all statuses for each entry

        for (size_t i = 0; i < statuses.size(); ++i)
        {
            if (statuses[i] != expectedStatuses[i])
            {
                /*
                 * If recorded statuses are different than received, throw
                 * exception since data don't match.
                 */

                SWSS_LOG_THROW("recorded status is %s but returned is %s on %s",
                        sai_serialize_status(expectedStatuses[i]).c_str(),
                        sai_serialize_status(statuses[i]).c_str(),
                        strObjectIds[i].c_str());
            }
        }

        return status;
    }
    else
    {
        SWSS_LOG_THROW("api %s is not supported in bulk %s",
                sai_serialize_common_api(api).c_str(),
                sai_serialize_object_type(objectType).c_str());
    }
}