sai_status_t SaiPlayer::handle_bulk_object()

in saiplayer/SaiPlayer.cpp [2233:2395]


sai_status_t SaiPlayer::handle_bulk_object(
        _In_ sai_object_type_t object_type,
        _In_ const std::vector<std::string> &object_ids,
        _In_ sai_common_api_t api,
        _In_ const std::vector<std::shared_ptr<SaiAttributeList>> &attributes,
        _Out_ std::vector<sai_status_t> &statuses)
{
    SWSS_LOG_ENTER();

    if (!object_ids.size())
    {
        SWSS_LOG_ERROR("Object ids is empty in handle bulk generic");
        return SAI_STATUS_FAILURE;
    }

    sai_status_t status;

    uint32_t object_count = (uint32_t) object_ids.size();

    std::vector<sai_object_id_t> local_ids(object_count);

    sai_bulk_op_error_mode_t mode = SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR; // TODO we need to get that from recording

    SWSS_LOG_DEBUG("generic %s for %s:%s",
            sai_serialize_common_api(api).c_str(),
            sai_serialize_object_type(object_type).c_str(),
            object_ids[0].c_str());

    for (uint32_t it = 0; it < object_count; it++)
    {
        sai_deserialize_object_id(object_ids[it], local_ids[it]);
    }

    switch (api)
    {
        case SAI_COMMON_API_BULK_CREATE:

        {
            sai_object_id_t switch_id = m_sai->switchIdQuery(local_ids[0]);
            std::vector<sai_object_id_t> ids(object_count);

            for (uint32_t it = 0; it < object_count; it++)
            {
                if (m_sai->switchIdQuery(local_ids[it]) != switch_id ||
                    switch_id == SAI_NULL_OBJECT_ID)
                {
                    SWSS_LOG_THROW("invalid switch_id translated from VID %s",
                            sai_serialize_object_id(local_ids[it]).c_str());
                }
            }

            std::vector<uint32_t> attr_counts(object_count);

            std::vector<const sai_attribute_t*> attr_lists(object_count);

            for (uint32_t idx = 0; idx < object_count; idx++)
            {
                attr_counts[idx] = attributes[idx]->get_attr_count();
                attr_lists[idx] = attributes[idx]->get_attr_list();
            }

            switch_id = translate_local_to_redis(switch_id);

            status = m_sai->bulkCreate(object_type,
                                            switch_id,
                                            object_count,
                                            attr_counts.data(),
                                            attr_lists.data(),
                                            mode,
                                            ids.data(),
                                            statuses.data());

            if (status == SAI_STATUS_SUCCESS)
            {
                for (uint32_t it = 0; it < object_count; it++)
                {
                    match_redis_with_rec(ids[it], local_ids[it]);

                    SWSS_LOG_INFO("saved VID %s to RID %s",
                            sai_serialize_object_id(local_ids[it]).c_str(),
                            sai_serialize_object_id(ids[it]).c_str());
                }
            }

            return status;
        }
        break;

        case SAI_COMMON_API_BULK_REMOVE:

        {
            std::vector<sai_object_id_t> ids(object_count);

            for (uint32_t it = 0; it < object_count; it++)
            {
                ids[it] = translate_local_to_redis(local_ids[it]);
            }

            status = m_sai->bulkRemove(object_type, object_count, ids.data(), mode, statuses.data());
        }
        break;

        case SAI_COMMON_API_BULK_SET:

        {
            std::vector<sai_object_id_t> ids(object_count);

            for (uint32_t it = 0; it < object_count; it++)
            {
                ids[it] = translate_local_to_redis(local_ids[it]);
            }

            std::vector<sai_attribute_t> attr_list;

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

            status = m_sai->bulkSet(object_type, object_count, ids.data(), attr_list.data(), mode, statuses.data());
        }
        break;

        case SAI_COMMON_API_BULK_GET:

        {
            std::vector<sai_object_id_t> ids(object_count);

            for (uint32_t it = 0; it < object_count; it++)
            {
                ids[it] = translate_local_to_redis(local_ids[it]);
            }

            std::vector<uint32_t> attr_counts(object_count);

            std::vector<sai_attribute_t*> attr_lists(object_count);

            for (uint32_t idx = 0; idx < object_count; idx++)
            {
                attr_counts[idx] = attributes[idx]->get_attr_count();
                attr_lists[idx] = attributes[idx]->get_attr_list();
            }

            status = m_sai->bulkGet(object_type,
                                            object_count,
                                            ids.data(),
                                            attr_counts.data(),
                                            attr_lists.data(),
                                            mode,
                                            statuses.data());

            return status;
        }
        break;


        default:
            SWSS_LOG_THROW("generic other apis not implemented");
    }

    return status;
}