LCOV - code coverage report
Current view: top level - vnsw/agent/port_ipc - rest_server.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 178 0.0 %
Date: 2026-08-03 02:19:58 Functions: 0 23 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include <vector>
       6             : #include <string>
       7             : 
       8             : #include <boost/bind/bind.hpp>
       9             : #include <boost/assign.hpp>
      10             : #include <boost/foreach.hpp>
      11             : 
      12             : #include "base/regex.h"
      13             : #include "http/http_server.h"
      14             : #include "http/http_request.h"
      15             : #include "http/http_session.h"
      16             : #include "base/contrail_ports.h"
      17             : #include "port_ipc/port_ipc_handler.h"
      18             : #include "cmn/agent.h"
      19             : #include "rest_server.h"
      20             : #include "rest_common.h"
      21             : #include "init/agent_param.h"
      22             : 
      23             : using namespace boost::placeholders;
      24             : 
      25             : using contrail::regex;
      26             : using contrail::regex_match;
      27             : using contrail::regex_search;
      28             : 
      29             : class RestServerGetVmCfgTask : public Task {
      30             : public:
      31           0 :     RestServerGetVmCfgTask(PortIpcHandler *pih,
      32           0 :                             const struct RestServer::RESTData& data):
      33             :         Task((TaskScheduler::GetInstance()->GetTaskId("Agent::RestApi")), 0),
      34           0 :         pih_(pih),
      35           0 :         vm_name_((*data.match)[1]),
      36           0 :         data_(data),
      37           0 :         context_(data_.session->get_context()) {
      38           0 :     }
      39           0 :     virtual ~RestServerGetVmCfgTask() { }
      40           0 :     virtual bool Run() {
      41           0 :         std::string info;
      42           0 :         const std::string client_ctx = data_.session->get_client_context(context_);
      43             :         // check session is not deleted
      44           0 :         if ((!data_.session->set_client_context(context_, client_ctx)) ||
      45           0 :             (context_.empty()))
      46           0 :             return true;
      47           0 :         if (pih_->GetVmVnCfgPort(vm_name_, info)) {
      48           0 :             REST::SendResponse(data_.session, info, 200, context_);
      49             :         } else {
      50           0 :             REST::SendErrorResponse(data_.session, "{ Not Found }", 404, context_);
      51             :         }
      52           0 :         return true;
      53           0 :     }
      54           0 :     std::string Description() const { return "RestServerGetVmCfgTask"; }
      55             : private:
      56             :     const PortIpcHandler *pih_;
      57             :     std::string vm_name_;
      58             :     const struct RestServer::RESTData& data_;
      59             :     const std::string context_;
      60             :     DISALLOW_COPY_AND_ASSIGN(RestServerGetVmCfgTask);
      61             : };
      62             : 
      63           0 : void RestServer::VmPortPostHandler(const struct RESTData& data) {
      64           0 :     PortIpcHandler *pih = agent_->port_ipc_handler();
      65           0 :     if (pih) {
      66           0 :         std::string err_msg;
      67           0 :         if (pih->AddPortFromJson(data.request->Body(), false, err_msg, true)) {
      68           0 :             REST::SendResponse(data.session, "{}");
      69             :         } else {
      70           0 :             REST::SendErrorResponse(data.session, "{ " + err_msg + " }");
      71             :         }
      72           0 :     } else {
      73           0 :        REST::SendErrorResponse(data.session, "{ Operation Not Supported }");
      74             :     }
      75           0 : }
      76             : 
      77           0 : void RestServer::VmPortSyncHandler(const struct RESTData& data) {
      78           0 :     PortIpcHandler *pih = agent_->port_ipc_handler();
      79           0 :     if (pih) {
      80           0 :         pih->SyncHandler();
      81           0 :         REST::SendResponse(data.session, "{}");
      82             :     } else {
      83           0 :        REST::SendErrorResponse(data.session, "{ Operation Not Supported }");
      84             :     }
      85           0 : }
      86             : 
      87           0 : void RestServer::VmPortDeleteHandler(const struct RESTData& data) {
      88           0 :     std::string error;
      89           0 :     const std::string& port_id = (*data.match)[1];
      90           0 :     PortIpcHandler *pih = agent_->port_ipc_handler();
      91           0 :     if (pih) {
      92           0 :         if (pih->DeletePort(port_id, error)) {
      93           0 :             REST::SendResponse(data.session, "{}");
      94             :         } else {
      95           0 :             REST::SendErrorResponse(data.session, "{" + error + "}");
      96             :         }
      97             :     } else {
      98           0 :         REST::SendErrorResponse(data.session, "{ Operation Not Supported }");
      99             :     }
     100           0 : }
     101             : 
     102           0 : void RestServer::VmPortGetHandler(const struct RESTData& data) {
     103           0 :     const std::string& port_id = (*data.match)[1];
     104           0 :     PortIpcHandler *pih = agent_->port_ipc_handler();
     105           0 :     if (pih) {
     106           0 :         std::string info;
     107           0 :         if (pih->GetPortInfo(port_id, info)) {
     108           0 :             REST::SendResponse(data.session, info);
     109             :         } else {
     110           0 :             REST::SendErrorResponse(data.session, "{ Not Found }", 404);
     111             :         }
     112           0 :     } else {
     113           0 :         REST::SendErrorResponse(data.session, "{ Operation Not Supported }");
     114             :     }
     115           0 : }
     116             : 
     117           0 : void RestServer::GatewayPostHandler(const struct RESTData& data) {
     118           0 :     PortIpcHandler *pih = agent_->port_ipc_handler();
     119           0 :     if (pih) {
     120           0 :         std::string err_msg;
     121           0 :         if (pih->AddVgwFromJson(data.request->Body(), err_msg)) {
     122           0 :             REST::SendResponse(data.session, "{}");
     123             :         } else {
     124           0 :             REST::SendErrorResponse(data.session, "{ " + err_msg + " }");
     125             :         }
     126           0 :     } else {
     127           0 :        REST::SendErrorResponse(data.session, "{ Operation Not Supported }");
     128             :     }
     129           0 : }
     130             : 
     131           0 : void RestServer::GatewayDeleteHandler(const struct RESTData& data) {
     132           0 :     std::string error;
     133           0 :     PortIpcHandler *pih = agent_->port_ipc_handler();
     134           0 :     if (pih) {
     135           0 :         std::string err_msg;
     136           0 :         if (pih->DelVgwFromJson(data.request->Body(), err_msg)) {
     137           0 :             REST::SendResponse(data.session, "{}");
     138             :         } else {
     139           0 :             REST::SendErrorResponse(data.session, "{" + error + "}");
     140             :         }
     141           0 :     } else {
     142           0 :         REST::SendErrorResponse(data.session, "{ Operation Not Supported }");
     143             :     }
     144           0 : }
     145             : 
     146           0 : void RestServer::VmVnPortPostHandler(const struct RESTData& data) {
     147           0 :     PortIpcHandler *pih = agent_->port_ipc_handler();
     148           0 :     if (pih) {
     149           0 :         std::string err_msg;
     150           0 :         if (pih->AddVmVnPort(data.request->Body(), false, err_msg, true)) {
     151           0 :             REST::SendResponse(data.session, "{}");
     152             :         } else {
     153           0 :             REST::SendErrorResponse(data.session, "{ " + err_msg + " }");
     154             :         }
     155           0 :     } else {
     156           0 :        REST::SendErrorResponse(data.session, "{ Operation Not Supported }");
     157             :     }
     158           0 : }
     159             : 
     160           0 : void RestServer::VmVnPortDeleteHandler(const struct RESTData& data) {
     161           0 :     std::string error;
     162           0 :     const std::string &vm_uuid = (*data.match)[1];
     163           0 :     PortIpcHandler *pih = agent_->port_ipc_handler();
     164           0 :     if (pih) {
     165           0 :         if (pih->DeleteVmVnPort(data.request->Body(), vm_uuid, error)) {
     166           0 :             REST::SendResponse(data.session, "{}");
     167             :         } else {
     168           0 :             REST::SendErrorResponse(data.session, "{" + error + "}");
     169             :         }
     170             :     } else {
     171           0 :         REST::SendErrorResponse(data.session, "{ Operation Not Supported }");
     172             :     }
     173           0 : }
     174             : 
     175           0 : void RestServer::VmVnPortGetHandler(const struct RESTData& data) {
     176           0 :     std::string url = (*data.match)[0];
     177           0 :     bool vmi_uuid_presence = false;
     178           0 :     std::size_t pos = 4; // skip "/vm/"
     179           0 :     std::size_t vmi_uuid_pos = url.find("/", pos);
     180           0 :     if (vmi_uuid_pos != std::string::npos) {
     181           0 :         vmi_uuid_presence = true;
     182             :     }
     183           0 :     std::string vm_uuid = url.substr(pos, vmi_uuid_pos);
     184           0 :     std::string vmi_uuid = "";
     185           0 :     if (vmi_uuid_presence) {
     186           0 :         vmi_uuid = url.substr(vmi_uuid_pos+1, std::string::npos);
     187             :     }
     188             : 
     189           0 :     PortIpcHandler *pih = agent_->port_ipc_handler();
     190           0 :     if (pih) {
     191           0 :         std::string info;
     192           0 :         if (pih->GetVmVnPort(vm_uuid, vmi_uuid, info)) {
     193           0 :             REST::SendResponse(data.session, info);
     194             :         } else {
     195           0 :             REST::SendErrorResponse(data.session, "{ Not Found }", 404);
     196             :         }
     197           0 :     } else {
     198           0 :         REST::SendErrorResponse(data.session, "{ Operation Not Supported }");
     199             :     }
     200           0 : }
     201             : 
     202           0 : void RestServer::VmVnPortCfgGetHandler(const struct RESTData& data) {
     203           0 :     PortIpcHandler *pih = agent_->port_ipc_handler();
     204           0 :     if (pih) {
     205             :         RestServerGetVmCfgTask *t =
     206           0 :             new RestServerGetVmCfgTask(pih, data);
     207           0 :         TaskScheduler *scheduler = TaskScheduler::GetInstance();
     208           0 :         scheduler->Enqueue(t);
     209             :     } else {
     210           0 :         REST::SendErrorResponse(data.session, "{ Operation Not Supported }");
     211             :     }
     212           0 : }
     213             : 
     214           0 : void RestServer::VmPortEnableHandler(const struct RESTData& data) {
     215           0 :     std::string error;
     216           0 :     const std::string& port_id = (*data.match)[1];
     217           0 :     PortIpcHandler *pih = agent_->port_ipc_handler();
     218           0 :     if (pih) {
     219           0 :         if (pih->EnablePort(port_id, error)) {
     220           0 :             REST::SendResponse(data.session, "{}");
     221             :         } else {
     222           0 :             REST::SendErrorResponse(data.session, "{" + error + "}");
     223             :         }
     224             :     } else {
     225           0 :         REST::SendErrorResponse(data.session, "{ Operation Not Supported }");
     226             :     }
     227           0 : }
     228             : 
     229           0 : void RestServer::VmPortDisableHandler(const struct RESTData& data) {
     230           0 :     std::string error;
     231           0 :     const std::string& port_id = (*data.match)[1];
     232           0 :     PortIpcHandler *pih = agent_->port_ipc_handler();
     233           0 :     if (pih) {
     234           0 :         if (pih->DisablePort(port_id, error)) {
     235           0 :             REST::SendResponse(data.session, "{}");
     236             :         } else {
     237           0 :             REST::SendErrorResponse(data.session, "{" + error + "}");
     238             :         }
     239             :     } else {
     240           0 :         REST::SendErrorResponse(data.session, "{ Operation Not Supported }");
     241             :     }
     242           0 : }
     243             : 
     244             : const std::vector<RestServer::HandlerSpecifier> RestServer::RESTHandlers_ =
     245             :     boost::assign::list_of
     246             :     (HandlerSpecifier(
     247             :         regex("/port"),
     248             :         HTTP_POST,
     249             :         &RestServer::VmPortPostHandler))
     250             :     (HandlerSpecifier(
     251             :         regex("/syncports"),
     252             :         HTTP_POST,
     253             :         &RestServer::VmPortSyncHandler))
     254             :     (HandlerSpecifier(
     255             :         regex("/port/"
     256             :             "([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})"),
     257             :         HTTP_DELETE,
     258             :         &RestServer::VmPortDeleteHandler))
     259             :     (HandlerSpecifier(
     260             :         regex("/port/"
     261             :             "([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})"),
     262             :         HTTP_GET,
     263             :         &RestServer::VmPortGetHandler))
     264             :     (HandlerSpecifier(
     265             :         regex("/gateway"),
     266             :         HTTP_POST,
     267             :         &RestServer::GatewayPostHandler))
     268             :     (HandlerSpecifier(
     269             :         regex("/gateway"),
     270             :         HTTP_DELETE,
     271             :         &RestServer::GatewayDeleteHandler))
     272             :     (HandlerSpecifier(
     273             :         regex("/vm"),
     274             :         HTTP_POST,
     275             :         &RestServer::VmVnPortPostHandler))
     276             :     (HandlerSpecifier(
     277             :         regex("/vm/"
     278             :             "([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})"),
     279             :         HTTP_DELETE,
     280             :         &RestServer::VmVnPortDeleteHandler))
     281             :     (HandlerSpecifier(
     282             :         regex("/vm/"
     283             :             "([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})"),
     284             :         HTTP_GET,
     285             :         &RestServer::VmVnPortGetHandler))
     286             :     (HandlerSpecifier(
     287             :         regex("/vm/"
     288             :             "([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/"
     289             :             "([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})"),
     290             :         HTTP_GET,
     291             :         &RestServer::VmVnPortGetHandler))
     292             :     (HandlerSpecifier(
     293             :         regex("/vm-cfg/(.*)"),
     294             :         HTTP_GET,
     295             :         &RestServer::VmVnPortCfgGetHandler))
     296             :     (HandlerSpecifier(
     297             :         regex("/enable-port/"
     298             :             "([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})"),
     299             :         HTTP_PUT,
     300             :         &RestServer::VmPortEnableHandler))
     301             :     (HandlerSpecifier(
     302             :         regex("/disable-port/"
     303             :             "([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})"),
     304             :         HTTP_PUT,
     305             :         &RestServer::VmPortDisableHandler));
     306             : 
     307           0 : RestServer::RestServer(Agent *agent)
     308           0 :     : agent_(agent), http_server_(new HttpServer(agent->event_manager())) {
     309           0 :     http_server_->RegisterHandler(HTTP_WILDCARD_ENTRY,
     310             :         boost::bind(&RestServer::HandleRequest, this, _1, _2));
     311           0 : }
     312             : 
     313           0 : void RestServer::InitDone() {
     314           0 :      if (agent_ && agent_->params() && agent_->params()->cat_is_agent_mocked())
     315             :          //only if RestServer is used via mocked agent
     316           0 :          http_server_->Initialize(agent_->params()->rest_port());
     317             :      else //otherwise , use the hardcoded value
     318           0 :          http_server_->Initialize(ContrailPorts::PortIpcVrouterAgentPort());
     319           0 : }
     320             : 
     321           0 : void RestServer::HandleRequest(HttpSession* session,
     322             :                                const HttpRequest* request) {
     323           0 :     std::string path = request->UrlPath();
     324           0 :     BOOST_FOREACH(const RestServer::HandlerSpecifier& hs, RESTHandlers_) {
     325           0 :         boost::smatch match;
     326           0 :         if (regex_match(path, match, hs.request_regex) &&
     327           0 :             request->GetMethod() == hs.method) {
     328             :             struct RESTData data = {
     329             :                 &match,
     330           0 :                 request->GetMethod(),
     331             :                 session,
     332             :                 request
     333           0 :             };
     334           0 :             (this->*hs.handler_func)(data);
     335             :             // Though IMHO it contradicts most programmers' intuition,
     336             :             // currently handlers are responsible for freeing handled
     337             :             // requests.
     338           0 :             delete request;
     339           0 :             return;
     340             :         }
     341           0 :     }
     342           0 :     REST::SendErrorResponse(session, "Unknown Request", 404);
     343           0 : }
     344             : 
     345           0 : void RestServer::Shutdown() {
     346           0 :     if (http_server_) {
     347           0 :         http_server_->Shutdown();
     348           0 :         TcpServerManager::DeleteServer(http_server_);
     349           0 :         http_server_ = NULL;
     350             :     }
     351           0 : }
     352             : 
     353           0 : RestServer::~RestServer() {
     354           0 : }

Generated by: LCOV version 1.14