LCOV - code coverage report
Current view: top level - coll_communicator_mgr/rank_graph/rank_table_info - address_info.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 96.4 % 138 133
Test Date: 2026-08-25 19:18:03 Functions: 100.0 % 10 10

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "address_info.h"
      12              : 
      13              : #include <sstream>
      14              : #include <vector>
      15              : #include <string>
      16              : #include <unordered_map>
      17              : #include "json_parser.h"
      18              : #include "invalid_params_exception.h"
      19              : #include "exception_util.h"
      20              : #include "adapter_error_manager_pub.h"
      21              : 
      22              : namespace Hccl {
      23              : using namespace std;
      24              : 
      25              : const unordered_map<string, AddrType> AddressInfo::strToAddrType
      26              :     = (unordered_map<string, AddrType>{{"EID", AddrType::EID}, {"IPV4", AddrType::IPV4}, {"IPV6", AddrType::IPV6}});
      27              : 
      28          331 : void AddressInfo::Deserialize(const nlohmann::json& addressInfoJson)
      29              : {
      30          331 :     std::string addrTypeStr;
      31          331 :     std::string msgAddrtype = "error occurs when parser object of propName \"addr_type\"";
      32          331 :     TRY_CATCH_THROW(InvalidParamsException, msgAddrtype, addrTypeStr = GetJsonProperty(addressInfoJson, "addr_type"););
      33              : 
      34          331 :     if (!IsStringInAddrType(addrTypeStr)) {
      35            2 :         THROW<InvalidParamsException>(StringFormat("[AddressInfo::%s] failed with Invalid addrType. ", __func__));
      36              :     }
      37          330 :     addrType = strToAddrType.at(addrTypeStr);
      38              : 
      39          330 :     std::string address;
      40          330 :     std::string msgAddr = "error occurs when parser object of propName \"addr\"";
      41          330 :     TRY_CATCH_THROW(InvalidParamsException, msgAddr, address = GetJsonProperty(addressInfoJson, "addr"););
      42              : 
      43          330 :     if (address.length() < MIN_VALUE_ADDR_LENGRH || address.length() > MAX_VALUE_ADDR_LENGRH) {
      44            2 :         if (address.empty()) {
      45           34 :             RPT_INPUT_ERR(
      46              :                 true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
      47              :                 std::vector<std::string>({"N/A", "addr", "addr is required and should not be empty"}));
      48              :         } else {
      49            0 :             RPT_INPUT_ERR(
      50              :                 true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
      51              :                 std::vector<std::string>({address, "addr", "A ip address"}));
      52              :         }
      53            4 :         THROW<InvalidParamsException>(StringFormat(
      54              :             "addr [%.*s] length is out of range [%u] to [%u]", MAX_DISPLAY_LEN, address.c_str(), MIN_VALUE_ADDR_LENGRH,
      55              :             MAX_VALUE_ADDR_LENGRH));
      56              :     }
      57              : 
      58          824 :     HCCL_INFO("[AddressInfo::%s] addrTypeStr is[%s]", __func__, addrTypeStr.c_str());
      59          328 :     if (addrTypeStr == "IPV4") {
      60          323 :         IPV4ToAddr(address);
      61            9 :     } else if (addrTypeStr == "IPV6") {
      62            8 :         IPV6ToAddr(address);
      63            4 :     } else if (addrTypeStr == "EID") {
      64            6 :         EidToAddr(address);
      65              :     }
      66              :     // 先解析主地址以确定 addrType,再使用同一类型校验可选的 backup_addr。
      67          319 :     const std::string msgBackupAddr = "deserialize backup_addr failed";
      68          324 :     TRY_CATCH_THROW(InvalidParamsException, msgBackupAddr, DeserializeBackupAddrs(addressInfoJson, addrTypeStr););
      69              : 
      70          314 :     planeId = addressInfoJson.value<std::string>("plane_id", "0");
      71          314 :     if (planeId.length() > MAX_VALUE_PLANEID) {
      72            0 :         THROW<InvalidParamsException>(StringFormat(
      73              :             "plane_id [%s] length is out of range [%u] to [%u]", planeId.c_str(), MIN_VALUE_PLANEID,
      74              :             MAX_VALUE_PLANEID));
      75              :     }
      76              : 
      77          314 :     nlohmann::json portsJsons;
      78          314 :     std::string msgPortlist = "error occurs when parser object of propName \"ports\"";
      79          314 :     TRY_CATCH_THROW(InvalidParamsException, msgPortlist, GetJsonPropertyList(addressInfoJson, "ports", portsJsons););
      80          741 :     for (auto& portsJson : portsJsons) {
      81          428 :         if (portsJson.get<std::string>().size() < MIN_VALUE_PORT_LENGTH
      82          428 :             || portsJson.get<std::string>().size() > MAX_VALUE_PORT_LENGTH) {
      83            2 :             THROW<InvalidParamsException>(StringFormat(
      84            3 :                 "portsString [%u] length is out of range [%u] to [%u]", portsJson.get<std::string>().size(),
      85              :                 MIN_VALUE_PORT_LENGTH, MAX_VALUE_PORT_LENGTH));
      86              :         }
      87          427 :         ports.emplace(portsJson);
      88              :     }
      89          313 :     if (ports.size() < MIN_VALUE_PORT || ports.size() > MAX_VALUE_PORT) {
      90            2 :         THROW<InvalidParamsException>(StringFormat(
      91              :             "ports [%u] length is out of range [%u] to [%u]", ports.size(), MIN_VALUE_PORT, MAX_VALUE_PORT));
      92              :     }
      93          397 : }
      94              : 
      95           75 : void AddressInfo::ParseAddrByType(const std::string& addrType, const std::string& address, IpAddress& ipAddress)
      96              : {
      97           75 :     if (addrType == "IPV4") {
      98           75 :         CHK_PRT_THROW(
      99              :             !IpAddress::IsIPv4(address),
     100              :             HCCL_ERROR("[%s] invalid IPV4 backup_addr[%.*s].", __func__, MAX_DISPLAY_LEN, address.c_str()),
     101              :             InvalidParamsException, "invalid IPV4 backup_addr");
     102           66 :         ipAddress = IpAddress(address, AF_INET);
     103            6 :     } else if (addrType == "IPV6") {
     104            5 :         CHK_PRT_THROW(
     105              :             !IpAddress::IsIPv6(address),
     106              :             HCCL_ERROR("[%s] invalid IPV6 backup_addr[%.*s].", __func__, MAX_DISPLAY_LEN, address.c_str()),
     107              :             InvalidParamsException, "invalid IPV6 backup_addr");
     108            5 :         ipAddress = IpAddress(address, AF_INET6);
     109              :     } else {
     110            1 :         THROW<InvalidParamsException>(
     111            2 :             StringFormat("[%s] backup_addr does not support addrType[%s].", __func__, addrType.c_str()));
     112              :     }
     113           71 : }
     114              : 
     115           25 : void AddressInfo::ParseBackupAddrs(
     116              :     const nlohmann::json& backupAddrJson, const std::string& addrType, std::vector<IpAddress>& backupAddrs)
     117              : {
     118           25 :     backupAddrs.clear();
     119           29 :     CHK_PRT_THROW(
     120              :         !backupAddrJson.is_array(), HCCL_ERROR("[%s] backup_addr should be an array.", __func__),
     121              :         InvalidParamsException, "backup_addr should be an array");
     122           27 :     CHK_PRT_THROW(
     123              :         backupAddrJson.size() > MAX_VALUE_BACKUP_ADDR_SIZE,
     124              :         HCCL_ERROR(
     125              :             "[%s] backup_addr size[%zu] exceeds max[%u].", __func__, backupAddrJson.size(), MAX_VALUE_BACKUP_ADDR_SIZE),
     126              :         InvalidParamsException, "backup_addr size exceeds max");
     127              : 
     128           75 :     for (const auto& backupAddr : backupAddrJson) {
     129           63 :         CHK_PRT_THROW(
     130              :             !backupAddr.is_string(), HCCL_ERROR("[%s] backup_addr element should be string.", __func__),
     131              :             InvalidParamsException, "backup_addr element should be string");
     132           57 :         const std::string backupAddrStr = backupAddr.get<std::string>();
     133           57 :         CHK_PRT_THROW(
     134              :             backupAddrStr.length() < MIN_VALUE_ADDR_LENGRH || backupAddrStr.length() > MAX_VALUE_ADDR_LENGRH,
     135              :             HCCL_ERROR(
     136              :                 "[%s] backup_addr[%.*s] length is out of range [%u] to [%u].", __func__, MAX_DISPLAY_LEN,
     137              :                 backupAddrStr.c_str(), MIN_VALUE_ADDR_LENGRH, MAX_VALUE_ADDR_LENGRH),
     138              :             InvalidParamsException,
     139              :             StringFormat(
     140              :                 "[%s] backup_addr [%.*s] length is out of range [%u] to [%u]", __func__, MAX_DISPLAY_LEN,
     141              :                 backupAddrStr.c_str(), MIN_VALUE_ADDR_LENGRH, MAX_VALUE_ADDR_LENGRH));
     142           57 :         IpAddress backupIpAddress;
     143           57 :         const std::string msgParseBackupAddr = "parse backup_addr failed";
     144           60 :         TRY_CATCH_THROW(InvalidParamsException, msgParseBackupAddr,
     145              :                         ParseAddrByType(addrType, backupAddrStr, backupIpAddress););
     146           54 :         backupAddrs.emplace_back(backupIpAddress);
     147           60 :     }
     148           16 : }
     149              : 
     150          319 : void AddressInfo::DeserializeBackupAddrs(const nlohmann::json& addressInfoJson, const std::string& addrTypeStr)
     151              : {
     152          319 :     backupAddrs.clear();
     153              :     // backup_addr 为可选字段,缺失时兼容未配置主备地址的 RankTable。
     154          319 :     if (!addressInfoJson.contains("backup_addr")) {
     155          807 :         HCCL_WARNING("[%s] backup_addr is not configured.", __func__);
     156          311 :         return;
     157              :     }
     158            8 :     ParseBackupAddrs(addressInfoJson.at("backup_addr"), addrTypeStr, backupAddrs);
     159              : }
     160              : 
     161            4 : void AddressInfo::EidToAddr(std::string address)
     162              : {
     163            4 :     if (address.length() != URMA_EID_LEN * URMA_EID_NUM_TWO) {
     164            1 :         THROW<InvalidParamsException>(
     165            3 :             StringFormat("[AddressInfo::%s] failed with rankAddrs : error in length. ", __func__));
     166            3 :     } else if (!IpAddress::IsEID(address)) {
     167            1 :         THROW<InvalidParamsException>(
     168            3 :             StringFormat("[AddressInfo::%s] failed with rankAddrs : error in format. ", __func__));
     169              :     }
     170            2 :     Eid eid = IpAddress::StrToEID(address);
     171            2 :     IpAddress ipAddress0(eid);
     172            2 :     addr = ipAddress0;
     173            2 : }
     174              : 
     175          319 : void AddressInfo::IPV4ToAddr(std::string address)
     176              : {
     177          319 :     s32 ipFamily = AF_INET;
     178              : 
     179          319 :     if (IpAddress::IsIPv4(address)) {
     180          315 :         ipFamily = AF_INET;
     181              :     } else {
     182            8 :         THROW<InvalidParamsException>(StringFormat("[AddressInfo::%s] failed with addrs is error. ", __func__));
     183              :     }
     184          315 :     IpAddress ipAddress0(address, ipFamily);
     185          315 :     addr = ipAddress0;
     186          811 :     HCCL_INFO("[AddressInfo::%s] IpAddress is[%s]", __func__, ipAddress0.Describe().c_str());
     187          315 : }
     188              : 
     189            5 : void AddressInfo::IPV6ToAddr(std::string address)
     190              : {
     191            5 :     s32 ipFamily = AF_INET6;
     192              : 
     193            5 :     if (IpAddress::IsIPv6(address)) {
     194            2 :         ipFamily = AF_INET6;
     195              :     } else {
     196            6 :         THROW<InvalidParamsException>(StringFormat("[AddressInfo::%s] failed with addr is error. ", __func__));
     197              :     }
     198            2 :     IpAddress ipAddress0(address, ipFamily);
     199            2 :     addr = ipAddress0;
     200            2 : }
     201              : 
     202            1 : std::string AddressInfo::Describe() const
     203              : {
     204              :     return StringFormat(
     205              :         "AddressInfo[addrType=%s, addr=%s, backupAddrSize=%u, planeId=%s, portsize=%u socketPort_=%u]",
     206            3 :         addrType.Describe().c_str(), addr.Describe().c_str(), static_cast<u32>(backupAddrs.size()), planeId.c_str(),
     207            4 :         static_cast<u32>(ports.size()), socketPort_);
     208              : }
     209              : 
     210           28 : AddressInfo::AddressInfo(BinaryStream& binStream)
     211              : {
     212           14 :     IpAddress address(binStream);
     213           14 :     addr = address;
     214           14 :     u32 addrTypeInt{0};
     215           14 :     binStream >> addrTypeInt;
     216           14 :     addrType = static_cast<AddrType::Value>(addrTypeInt);
     217           14 :     size_t portsSize{0};
     218           14 :     binStream >> portsSize;
     219           41 :     for (u32 i = 0; i < portsSize; i++) {
     220           27 :         string port;
     221           27 :         binStream >> port;
     222           27 :         ports.emplace(port);
     223           27 :     }
     224           14 :     binStream >> planeId;
     225           14 :     binStream >> socketPort_;
     226           14 :     size_t backupAddrSize{0};
     227           14 :     binStream >> backupAddrSize;
     228           16 :     CHK_PRT_THROW(
     229              :         backupAddrSize > MAX_VALUE_BACKUP_ADDR_SIZE,
     230              :         HCCL_ERROR("[%s] backup_addr size[%zu] exceeds max[%u].", __func__, backupAddrSize, MAX_VALUE_BACKUP_ADDR_SIZE),
     231              :         InvalidParamsException, "backup_addr size exceeds limit");
     232           16 :     for (size_t i = 0; i < backupAddrSize; i++) {
     233            3 :         IpAddress backupAddr(binStream);
     234            3 :         backupAddrs.emplace_back(backupAddr);
     235              :     }
     236           16 : }
     237              : 
     238          114 : void AddressInfo::GetBinStream(BinaryStream& binStream) const
     239              : {
     240          114 :     if (ports.size() == 0) {
     241            0 :         std::string msg = StringFormat("ports size is zero.");
     242            0 :         THROW<InvalidParamsException>(msg);
     243            0 :     }
     244          114 :     addr.GetBinStream(binStream);
     245          114 :     binStream << static_cast<u32>(addrType);
     246          114 :     binStream << ports.size();
     247          283 :     for (auto& it : ports) {
     248          169 :         binStream << it;
     249              :     }
     250          114 :     binStream << planeId;
     251          114 :     binStream << socketPort_;
     252          114 :     binStream << backupAddrs.size();
     253          117 :     for (const auto& backupAddr : backupAddrs) {
     254            3 :         backupAddr.GetBinStream(binStream);
     255              :     }
     256          114 : }
     257              : 
     258              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1