in saiplayer/SaiPlayer.cpp [2615:2897]
int SaiPlayer::replay()
{
//swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_DEBUG);
SWSS_LOG_ENTER();
if (m_commandLineOptions->m_files.size() == 0)
{
fprintf(stderr, "ERR: need to specify filename\n");
return -1;
}
auto filename = m_commandLineOptions->m_files.at(0);
SWSS_LOG_NOTICE("using file: %s", filename.c_str());
m_infile = std::ifstream{filename};
if (!m_infile.is_open())
{
SWSS_LOG_ERROR("failed to open file %s", filename.c_str());
return -1;
}
std::string line;
while (std::getline(m_infile, line))
{
// std::cout << "processing " << line << std::endl;
sai_common_api_t api = SAI_COMMON_API_CREATE;
auto p = line.find_first_of("|");
char op = line[p+1];
switch (op)
{
case 'a':
{
std::string response;
do
{
// this line may be notification, we need to skip
if (!std::getline(m_infile, response))
{
SWSS_LOG_THROW("failed to read next file from file, previous: %s", line.c_str());
}
}
while (response[response.find_first_of("|") + 1] == 'n');
performNotifySyncd(line, response);
}
continue;
case 'f':
{
std::string response;
do
{
// this line may be notification, we need to skip
if (!std::getline(m_infile, response))
{
SWSS_LOG_THROW("failed to read next file from file, previous: %s", line.c_str());
}
}
while (response[response.find_first_of("|") + 1] == 'n');
performFdbFlush(line, response);
}
continue;
case '@':
performSleep(line);
continue;
case 'c':
api = SAI_COMMON_API_CREATE;
break;
case 'r':
api = SAI_COMMON_API_REMOVE;
break;
case 's':
api = SAI_COMMON_API_SET;
break;
case 'B':
processBulk(SAI_COMMON_API_BULK_GET, line);
continue;
case 'S':
processBulk(SAI_COMMON_API_BULK_SET, line);
continue;
case 'C':
processBulk(SAI_COMMON_API_BULK_CREATE, line);
continue;
case 'R':
processBulk(SAI_COMMON_API_BULK_REMOVE, line);
continue;
case 'g':
api = SAI_COMMON_API_GET;
break;
case 'q':
// TODO: implement SAI player support for query commands
continue;
case 'p':
// TODO: implement SAI player support for counter polling commands
continue;
case 'Q':
continue; // skip over query responses
case '#':
case 'n':
SWSS_LOG_INFO("skipping op %c line %s", op, line.c_str());
continue; // skip comment and notification
default:
SWSS_LOG_THROW("unknown op %c on line %s", op, line.c_str());
}
// timestamp|action|objecttype:objectid|attrid=value,...
auto fields = swss::tokenize(line, '|');
// objecttype:objectid (object id may contain ':')
auto start = fields[2].find_first_of(":");
auto str_object_type = fields[2].substr(0, start);
auto str_object_id = fields[2].substr(start + 1);
sai_object_type_t object_type = deserialize_object_type(str_object_type);
auto values = get_values(fields);
SaiAttributeList list(object_type, values, false);
sai_attribute_t *attr_list = list.get_attr_list();
uint32_t attr_count = list.get_attr_count();
SWSS_LOG_DEBUG("attr count: %u", list.get_attr_count());
if (api != SAI_COMMON_API_GET)
{
translate_local_to_redis(object_type, attr_count, attr_list);
}
sai_status_t status;
auto info = sai_metadata_get_object_type_info(object_type);
switch ((int)object_type)
{
case SAI_OBJECT_TYPE_FDB_ENTRY:
status = handle_fdb(str_object_id, api, attr_count, attr_list);
break;
case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:
status = handle_neighbor(str_object_id, api, attr_count, attr_list);
break;
case SAI_OBJECT_TYPE_ROUTE_ENTRY:
status = handle_route(str_object_id, api, attr_count, attr_list);
break;
case SAI_OBJECT_TYPE_INSEG_ENTRY:
status = handle_inseg(str_object_id, api, attr_count, attr_list);
break;
case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:
status = handle_dash_direction_lookup(str_object_id, api, attr_count, attr_list);
break;
case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:
status = handle_dash_eni_ether_address_map(str_object_id, api, attr_count, attr_list);
break;
case SAI_OBJECT_TYPE_VIP_ENTRY:
status = handle_dash_vip(str_object_id, api, attr_count, attr_list);
break;
case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:
status = handle_dash_inbound_routing(str_object_id, api, attr_count, attr_list);
break;
case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:
status = handle_dash_pa_validation(str_object_id, api, attr_count, attr_list);
break;
case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:
status = handle_dash_outbound_routing(str_object_id, api, attr_count, attr_list);
break;
case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:
status = handle_dash_outbound_ca_to_pa(str_object_id, api, attr_count, attr_list);
break;
default:
if (info->isnonobjectid)
{
SWSS_LOG_THROW("object %s:%s is non object id, but not handled, FIXME",
sai_serialize_object_type(object_type).c_str(),
str_object_id.c_str());
}
status = handle_generic(object_type, str_object_id, api, attr_count, attr_list);
break;
}
if (status != SAI_STATUS_SUCCESS)
{
if (api == SAI_COMMON_API_GET)
{
// GET status is checked in handle response
}
else
SWSS_LOG_THROW("failed to execute api: %c: %s", op, sai_serialize_status(status).c_str());
}
if (api == SAI_COMMON_API_GET)
{
std::string response;
do
{
// this line may be notification, we need to skip
std::getline(m_infile, response);
}
while (response[response.find_first_of("|") + 1] == 'n');
try
{
handle_get_response(object_type, attr_count, attr_list, response, status);
}
catch (const std::exception &e)
{
SWSS_LOG_NOTICE("line: %s", line.c_str());
SWSS_LOG_NOTICE("resp (expected): %s", response.c_str());
SWSS_LOG_NOTICE("got: %s", sai_serialize_status(status).c_str());
if (api == SAI_COMMON_API_GET && (status == SAI_STATUS_SUCCESS || status == SAI_STATUS_BUFFER_OVERFLOW))
{
// log each get parameter
for (uint32_t i = 0; i < attr_count; ++i)
{
auto meta = sai_metadata_get_attr_metadata(object_type, attr_list[i].id);
auto val = sai_serialize_attr_value(*meta, attr_list[i]);
SWSS_LOG_NOTICE(" - %s:%s", meta->attridname, val.c_str());
}
}
exit(EXIT_FAILURE);
}
if (api == SAI_COMMON_API_GET && (status == SAI_STATUS_SUCCESS || status == SAI_STATUS_BUFFER_OVERFLOW))
{
// log each get parameter
for (uint32_t i = 0; i < attr_count; ++i)
{
auto meta = sai_metadata_get_attr_metadata(object_type, attr_list[i].id);
auto val = sai_serialize_attr_value(*meta, attr_list[i]);
SWSS_LOG_NOTICE(" - %s:%s", meta->attridname, val.c_str());
}
}
}
}
m_infile.close();
SWSS_LOG_NOTICE("finished replaying %s with SUCCESS", filename.c_str());
if (m_commandLineOptions->m_sleep)
{
fprintf(stderr, "Reply SUCCESS, sleeping, watching for notifications\n");
sleep(-1);
}
return 0;
}