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

Generated by: LCOV version 1.14