LCOV - code coverage report
Current view: top level - bfd/rest_api - bfd_json_config.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 55 172 32.0 %
Date: 2026-08-03 02:19:58 Functions: 8 21 38.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2014 CodiLime, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include <vector>
       6             : #include <boost/foreach.hpp>
       7             : #include <boost/assign/list_of.hpp>
       8             : #include "base/address_util.h"
       9             : 
      10             : #include "rapidjson/document.h"
      11             : #include "rapidjson/writer.h"
      12             : #include "rapidjson/stringbuffer.h"
      13             : 
      14             : #include "bfd/rest_api/bfd_json_config.h"
      15             : 
      16             : namespace BFD {
      17             : namespace REST {
      18             : 
      19           3 : static bool IsIPAddressValid(const char* addr) {
      20           3 :     boost::system::error_code ec;
      21           3 :     AddressFromString(addr, &ec);
      22           3 :     return !ec;
      23             : }
      24             : 
      25          14 : bool JsonData::ParseFromJsonString(const std::string& json) {
      26          14 :     contrail_rapidjson::Document document;
      27          14 :     document.Parse<0>(json.c_str());
      28          28 :     return ParseFromJsonDocument(document);
      29          14 : }
      30             : 
      31           1 : void JsonData::EncodeJsonString(std::string* json) {
      32           1 :     contrail_rapidjson::Document document;
      33           1 :     EncodeJsonDocument(&document, &document.GetAllocator());
      34           1 :     contrail_rapidjson::StringBuffer strbuf;
      35           1 :     contrail_rapidjson::Writer<contrail_rapidjson::StringBuffer> writer(strbuf);
      36           1 :     document.Accept(writer);
      37           1 :     *json = strbuf.GetString();
      38           1 : }
      39             : 
      40          14 : bool JsonData::AreConstraintsMet(const std::vector<Constraint>& constraints,
      41             :                                 const contrail_rapidjson::Value& document) {
      42          14 :     if (!document.IsObject())
      43           2 :         return false;
      44             : 
      45          50 :     BOOST_FOREACH(const struct Constraint& constraint, constraints) {
      46          51 :         if (!document.HasMember(constraint.member_name) ||
      47          23 :             !(document[constraint.member_name].*(constraint.typecheck_func))())
      48           9 :             return false;
      49             :     }
      50           3 :     return true;
      51             : }
      52             : 
      53          14 : JsonConfig::JsonConfig()
      54          14 : {}
      55             : 
      56           0 : JsonConfig::JsonConfig(boost::asio::ip::address address,
      57             :                        TimeInterval desired_min_tx_interval,
      58             :                        TimeInterval required_min_rx_interval,
      59           0 :                        int detection_time_multiplier)
      60           0 :                        : address(address),
      61           0 :                          desired_min_tx_interval(desired_min_tx_interval),
      62           0 :                          required_min_rx_interval(required_min_rx_interval),
      63           0 :                          detection_time_multiplier(detection_time_multiplier)
      64           0 :                        {}
      65             : 
      66          14 : bool JsonConfig::ValidateJsonDocument(const contrail_rapidjson::Value& document) {
      67             :     static const std::vector<Constraint> constraints = boost::assign::list_of
      68           2 :         (Constraint("Address", &contrail_rapidjson::Value::IsString) )
      69           1 :         (Constraint("DesiredMinTxInterval", &contrail_rapidjson::Value::IsInt))
      70           1 :         (Constraint("RequiredMinRxInterval", &contrail_rapidjson::Value::IsInt))
      71          15 :         (Constraint("DetectionMultiplier", &contrail_rapidjson::Value::IsInt));
      72          17 :     return AreConstraintsMet(constraints, document) &&
      73          17 :             IsIPAddressValid(document["Address"].GetString());
      74             : }
      75             : 
      76          14 : bool JsonConfig::ParseFromJsonDocument(const contrail_rapidjson::Value& document) {
      77          14 :     if (ValidateJsonDocument(document)) {
      78             :         using boost::posix_time::microseconds;
      79             : 
      80           2 :         boost::system::error_code ec;
      81           2 :         address = AddressFromString(document["Address"].GetString(), &ec);
      82           2 :         desired_min_tx_interval =
      83           2 :             microseconds(document["DesiredMinTxInterval"].GetInt());
      84           2 :         required_min_rx_interval =
      85           2 :             microseconds(document["RequiredMinRxInterval"].GetInt());
      86           2 :         detection_time_multiplier =
      87           2 :             document["DetectionMultiplier"].GetInt();
      88           2 :         return true;
      89             :     }
      90          12 :     return false;
      91             : }
      92             : 
      93           1 : void JsonConfig::EncodeJsonDocument(contrail_rapidjson::Value* document,
      94             :                                 contrail_rapidjson::Value::AllocatorType *allocator) {
      95           1 :     document->SetObject();
      96           1 :     std::string address_str = address.to_string();
      97           1 :     contrail_rapidjson::Value address_val(address_str.c_str(), *allocator);
      98           1 :     document->AddMember("Address", address_val, *allocator);
      99             : 
     100           1 :     document->AddMember("DesiredMinTxInterval",
     101             :         desired_min_tx_interval.total_microseconds(), *allocator);
     102           1 :     document->AddMember("RequiredMinRxInterval",
     103             :         required_min_rx_interval.total_microseconds(), *allocator);
     104           1 :     document->AddMember("DetectionMultiplier",
     105             :         detection_time_multiplier, *allocator);
     106           1 : }
     107             : 
     108           0 : bool JsonState::ValidateJsonDocument(const contrail_rapidjson::Value& document) {
     109             :     const std::vector<Constraint> constraints = boost::assign::list_of
     110           0 :         (Constraint("LocalSessionState", &contrail_rapidjson::Value::IsString))
     111           0 :         (Constraint("RemoteSessionState", &contrail_rapidjson::Value::IsString))
     112           0 :         (Constraint("RemoteMinRxInterval", &contrail_rapidjson::Value::IsInt))
     113           0 :         (Constraint("LocalDiscriminator", &contrail_rapidjson::Value::IsInt))
     114           0 :         (Constraint("RemoteDiscriminator", &contrail_rapidjson::Value::IsInt));
     115           0 :     return AreConstraintsMet(constraints, document) &&
     116             :         // Check whether these strings are convertible to BFD states.
     117           0 :         BFDStateFromString(document["LocalSessionState"].GetString()) &&
     118           0 :         BFDStateFromString(document["RemoteSessionState"].GetString());
     119           0 : }
     120             : 
     121           0 : bool JsonState::ParseFromJsonDocument(const contrail_rapidjson::Value& document) {
     122           0 :     if (!session_config.ParseFromJsonDocument(document))
     123           0 :         return false;
     124             : 
     125           0 :     if (ValidateJsonDocument(document)) {
     126             :         using boost::posix_time::microseconds;
     127             : 
     128           0 :         remote_min_rx_interval =
     129           0 :             microseconds(document["RemoteMinRxInterval"].GetInt());
     130           0 :         local_discriminator =
     131           0 :             document["LocalDiscriminator"].GetInt();
     132           0 :         remote_discriminator =
     133           0 :             document["RemoteDiscriminator"].GetInt();
     134           0 :         bfd_local_state =
     135           0 :             *BFDStateFromString(document["LocalSessionState"].GetString());
     136           0 :         bfd_remote_state =
     137           0 :             *BFDStateFromString(document["RemoteSessionState"].GetString());
     138           0 :         return true;
     139             :     }
     140           0 :     return false;
     141             : }
     142             : 
     143           0 : void JsonState::EncodeJsonDocument(contrail_rapidjson::Value* document,
     144             :     contrail_rapidjson::Value::AllocatorType *allocator) {
     145           0 :     document->SetObject();
     146           0 :     session_config.EncodeJsonDocument(document, allocator);
     147             : 
     148             :     std::string local_session_state_str
     149           0 :         = boost::lexical_cast<std::string>(bfd_local_state);
     150             :     contrail_rapidjson::Value local_session_state_val(local_session_state_str.c_str(),
     151           0 :                                                 *allocator);
     152           0 :     document->AddMember("LocalSessionState", local_session_state_val,
     153             :                         *allocator);
     154             : 
     155             :     std::string remote_session_state_str =
     156           0 :         boost::lexical_cast<std::string>(bfd_remote_state);
     157             :     contrail_rapidjson::Value remote_session_state_val(remote_session_state_str.c_str(),
     158           0 :                                                 *allocator);
     159           0 :     document->AddMember("RemoteSessionState", remote_session_state_val,
     160             :                         *allocator);
     161           0 :     document->AddMember("LocalDiscriminator", local_discriminator,
     162             :                         *allocator);
     163           0 :     document->AddMember("RemoteDiscriminator", remote_discriminator,
     164             :                         *allocator);
     165           0 :     document->AddMember("RemoteMinRxInterval",
     166             :                         remote_min_rx_interval.total_microseconds(),
     167             :                         *allocator);
     168           0 : }
     169             : 
     170           0 : bool JsonStateNotification::ValidateJsonDocument(
     171             :                                     const contrail_rapidjson::Value& document) {
     172             :     const std::vector<Constraint> constraints = boost::assign::list_of
     173           0 :         (Constraint("Address", &contrail_rapidjson::Value::IsString))
     174           0 :         (Constraint("SessionState", &contrail_rapidjson::Value::IsString));
     175           0 :     return AreConstraintsMet(constraints, document) &&
     176           0 :             IsIPAddressValid(document["Address"].GetString()) &&
     177           0 :             BFDStateFromString(document["SessionState"].GetString());
     178           0 : }
     179             : 
     180           0 : bool JsonStateNotification::ParseFromJsonDocument(const contrail_rapidjson::Value
     181             :                                                         &document) {
     182           0 :     if (ValidateJsonDocument(document)) {
     183             : 
     184           0 :         boost::system::error_code ec;
     185           0 :         address = AddressFromString(document["Address"].GetString(), &ec);
     186           0 :         state =
     187           0 :             *BFDStateFromString(document["SessionState"].GetString());
     188           0 :         return true;
     189             :     }
     190           0 :     return false;
     191             : }
     192             : 
     193           0 : void JsonStateNotification::EncodeJsonDocument(contrail_rapidjson::Value* document,
     194             :         contrail_rapidjson::Value::AllocatorType *allocator) {
     195           0 :     document->SetObject();
     196           0 :     std::string address_str = address.to_string();
     197           0 :     contrail_rapidjson::Value address_val(address_str.c_str(), *allocator);
     198           0 :     document->AddMember("Address", address_val, *allocator);
     199             : 
     200           0 :     std::string session_state_str = boost::lexical_cast<std::string>(state);
     201           0 :     contrail_rapidjson::Value session_state_val(session_state_str.c_str(), *allocator);
     202           0 :     document->AddMember("SessionState", session_state_val, *allocator);
     203           0 : }
     204             : 
     205           0 : void JsonStateNotificationList::EncodeJsonDocument(contrail_rapidjson::Value* document,
     206             :         contrail_rapidjson::Value::AllocatorType *allocator) {
     207           0 :     document->SetArray();
     208           0 :     for (std::vector<JsonStateNotification>::iterator it =
     209           0 :             notifications.begin(); it != notifications.end(); ++it) {
     210           0 :         contrail_rapidjson::Value notification;
     211           0 :         it->EncodeJsonDocument(&notification, allocator);
     212           0 :         document->PushBack(notification, *allocator);
     213           0 :     }
     214           0 : }
     215             : 
     216           0 : bool JsonStateNotificationList::ValidateJsonDocument(
     217             :                     const contrail_rapidjson::Value& document) {
     218           0 :     return true;
     219             : }
     220             : 
     221           0 : bool JsonStateNotificationList::ParseFromJsonDocument(
     222             :                     const contrail_rapidjson::Value& document) {
     223           0 :     return false;
     224             : }
     225             : 
     226           0 : void JsonStateMap::EncodeJsonDocument(contrail_rapidjson::Value* document,
     227             :     contrail_rapidjson::Value::AllocatorType* allocator) {
     228           0 :     document->SetObject();
     229             : 
     230           0 :     for (StateMap::iterator it = states.begin(); it != states.end(); ++it) {
     231           0 :         std::string address_str = it->first.to_string();
     232           0 :         contrail_rapidjson::Value address_val(address_str.c_str(), *allocator);
     233             : 
     234             :         std::string session_state_str =
     235           0 :             boost::lexical_cast<std::string>(it->second);
     236             :         contrail_rapidjson::Value session_state_val(session_state_str.c_str(),
     237           0 :                                             *allocator);
     238             : 
     239           0 :         document->AddMember(address_val, session_state_val, *allocator);
     240           0 :     }
     241           0 : }
     242             : 
     243           0 : bool JsonStateMap::ValidateJsonDocument(const contrail_rapidjson::Value& document) {
     244           0 :     if (!document.IsObject())
     245           0 :         return false;
     246             : 
     247           0 :     for (contrail_rapidjson::Value::ConstMemberIterator it = document.MemberBegin();
     248           0 :             it != document.MemberEnd(); ++it) {
     249             :         using boost::system::error_code;
     250             : 
     251           0 :         if (!it->name.IsString() || !it->value.IsString())
     252           0 :             return false;
     253             : 
     254           0 :         error_code ec;
     255           0 :         if (ec.failed())
     256           0 :             return false;
     257           0 :         if (!BFDStateFromString(it->value.GetString()))
     258           0 :             return false;
     259             :     }
     260           0 :     return true;
     261             : }
     262             : 
     263           0 : bool JsonStateMap::ParseFromJsonDocument(
     264             :         const contrail_rapidjson::Value& document) {
     265           0 :     if (!ValidateJsonDocument(document))
     266           0 :         return false;
     267             : 
     268           0 :     states.clear();
     269             : 
     270           0 :     for (contrail_rapidjson::Value::ConstMemberIterator
     271           0 :             it = document.MemberBegin(); it != document.MemberEnd(); ++it) {
     272           0 :         boost::system::error_code ec;
     273             :         boost::asio::ip::address address =
     274           0 :             AddressFromString(it->name.GetString(), &ec);
     275           0 :         BFDState state = *BFDStateFromString(it->value.GetString());
     276           0 :         states[address] = state;
     277             :     }
     278           0 :     return true;
     279             : }
     280             : 
     281             : }  // namespace REST
     282             : }  // namespace BFD
     283             : 

Generated by: LCOV version 1.14