LCOV - code coverage report
Current view: top level - model - AdminServerProvision.hpp (source / functions) Coverage Total Hit
Test: final-coverage.info Lines: 100.0 % 48 48
Test Date: 2025-02-14 17:40:40 Functions: 100.0 % 20 20

            Line data    Source code
       1              : /*
       2              :  ___________________________________________
       3              : |    _     ___                        _     |
       4              : |   | |   |__ \                      | |    |
       5              : |   | |__    ) |__ _  __ _  ___ _ __ | |_   |
       6              : |   | '_ \  / // _` |/ _` |/ _ \ '_ \| __|  |  HTTP/2 AGENT FOR MOCK TESTING
       7              : |   | | | |/ /| (_| | (_| |  __/ | | | |_   |  Version 0.0.z
       8              : |   |_| |_|____\__,_|\__, |\___|_| |_|\__|  |  https://github.com/testillano/h2agent
       9              : |                     __/ |                 |
      10              : |                    |___/                  |
      11              : |___________________________________________|
      12              : 
      13              : Licensed under the MIT License <http://opensource.org/licenses/MIT>.
      14              : SPDX-License-Identifier: MIT
      15              : Copyright (c) 2021 Eduardo Ramos
      16              : 
      17              : Permission is hereby  granted, free of charge, to any  person obtaining a copy
      18              : of this software and associated  documentation files (the "Software"), to deal
      19              : in the Software  without restriction, including without  limitation the rights
      20              : to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
      21              : copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
      22              : furnished to do so, subject to the following conditions:
      23              : 
      24              : The above copyright notice and this permission notice shall be included in all
      25              : copies or substantial portions of the Software.
      26              : 
      27              : THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
      28              : IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
      29              : FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
      30              : AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
      31              : LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      32              : OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
      33              : SOFTWARE.
      34              : */
      35              : 
      36              : #pragma once
      37              : 
      38              : #include <nghttp2/asio_http2_server.h>
      39              : 
      40              : #include <memory>
      41              : #include <string>
      42              : #include <vector>
      43              : #include <regex>
      44              : #include <cstdint>
      45              : 
      46              : #include <nlohmann/json.hpp>
      47              : 
      48              : #include <AdminSchema.hpp>
      49              : #include <Transformation.hpp>
      50              : #include <TypeConverter.hpp>
      51              : #include <DataPart.hpp>
      52              : 
      53              : 
      54              : namespace h2agent
      55              : {
      56              : namespace model
      57              : {
      58              : 
      59              : // Provision key:
      60              : typedef std::string admin_server_provision_key_t; // <inState>#<method>#<uri>
      61              : 
      62              : class MockServerData;
      63              : class MockClientData;
      64              : class AdminData;
      65              : class Configuration;
      66              : class GlobalVariable;
      67              : class FileManager;
      68              : class SocketManager;
      69              : 
      70              : 
      71              : class AdminServerProvision
      72              : {
      73              :     bool employed_{};
      74              : 
      75              :     nlohmann::json json_{}; // provision reference
      76              : 
      77              :     admin_server_provision_key_t key_{}; // calculated in every load()
      78              :     std::regex regex_{}; // precompile key as possible regex for RegexMatching algorithm
      79              : 
      80              :     // Cached information:
      81              :     std::string in_state_{};
      82              :     std::string request_method_{};
      83              :     std::string request_uri_{};
      84              : 
      85              :     std::string out_state_{};
      86              :     unsigned int response_code_{};
      87              :     nghttp2::asio_http2::header_map response_headers_{};
      88              : 
      89              :     nlohmann::json response_body_{};
      90              :     std::string response_body_string_{};
      91              :     /* Tatsuhiro sends strings in response:
      92              :     int response_body_integer_{};
      93              :     double response_body_number_{};
      94              :     bool response_body_boolean_{};
      95              :     bool response_body_null_{};
      96              :     */
      97              : 
      98              :     unsigned int response_delay_ms_{};
      99              : 
     100              :     // Schemas:
     101              :     std::string request_schema_id_{};
     102              :     std::string response_schema_id_{};
     103              :     std::shared_ptr<h2agent::model::AdminSchema> request_schema_{};
     104              :     std::shared_ptr<h2agent::model::AdminSchema> response_schema_{};
     105              : 
     106              :     model::MockServerData *mock_server_events_data_{}; // just in case it is used
     107              :     model::MockClientData *mock_client_events_data_{}; // just in case it is used
     108              :     model::AdminData *admin_data_{}; // just in case it is used
     109              :     model::Configuration *configuration_{}; // just in case it is used
     110              :     model::GlobalVariable *global_variable_{}; // just in case it is used
     111              :     model::FileManager *file_manager_{}; // just in case it is used
     112              :     model::SocketManager *socket_manager_{}; // just in case it is used
     113              : 
     114              :     void loadTransformation(const nlohmann::json &j);
     115              : 
     116              :     std::vector<std::shared_ptr<Transformation>> transformations_{};
     117              : 
     118              :     // Three processing stages: get sources, apply filters and store targets:
     119              :     bool processSources(std::shared_ptr<Transformation> transformation,
     120              :                         TypeConverter& sourceVault,
     121              :                         std::map<std::string, std::string>& variables,
     122              :                         const std::string &requestUri,
     123              :                         const std::string &requestUriPath,
     124              :                         const std::map<std::string, std::string> &requestQueryParametersMap,
     125              :                         const DataPart &requestBodyDataPart,
     126              :                         const nghttp2::asio_http2::header_map &requestHeaders,
     127              :                         bool &eraser,
     128              :                         std::uint64_t generalUniqueServerSequence,
     129              :                         bool usesResponseBodyAsTransformationJsonTarget, const nlohmann::json &responseBodyJson) const; // these two last parameters are used to
     130              :     // know if original response body provision
     131              :     // or the one dynamically modified, must be
     132              :     // used as source
     133              : 
     134              :     bool processFilters(std::shared_ptr<Transformation> transformation,
     135              :                         TypeConverter& sourceVault,
     136              :                         const std::map<std::string, std::string>& variables,
     137              :                         std::smatch &matches,
     138              :                         std::string &source) const;
     139              : 
     140              :     bool processTargets(std::shared_ptr<Transformation> transformation,
     141              :                         TypeConverter& sourceVault,
     142              :                         std::map<std::string, std::string>& variables,
     143              :                         const std::smatch &matches,
     144              :                         bool eraser,
     145              :                         bool hasFilter,
     146              :                         unsigned int &responseStatusCode,
     147              :                         nlohmann::json &responseBodyJson, // to manipulate json
     148              :                         std::string &responseBodyAsString, // to set native data (readable or not)
     149              :                         nghttp2::asio_http2::header_map &responseHeaders,
     150              :                         unsigned int &responseDelayMs,
     151              :                         std::string &outState,
     152              :                         std::string &outStateMethod,
     153              :                         std::string &outStateUri,
     154              :                         bool &breakCondition) const;
     155              : 
     156              : 
     157              : public:
     158              : 
     159              :     AdminServerProvision();
     160              : 
     161              :     // transform logic
     162              : 
     163              :     /**
     164              :      * Applies transformations vector over request received and ongoing response built
     165              :      * Also checks optional schema validation for incoming and/or outgoing traffic
     166              :      *
     167              :      * @param requestUri Request URI
     168              :      * @param requestUriPath Request URI path part
     169              :      * @param requestQueryParametersMap Query Parameters Map (if exists)
     170              :      * @param requestBodyDataPart Request Body data received (could be decoded if needed as source)
     171              :      * @param requestHeaders Request Headers Received
     172              :      * @param generalUniqueServerSequence HTTP/2 server monotonically increased sequence for every reception (unique)
     173              :      *
     174              :      * @param responseStatusCode Response status code filled by reference (if any transformation applies)
     175              :      * @param responseHeaders Response headers filled by reference (if any transformation applies)
     176              :      * @param responseBody Response body filled by reference (if any transformation applies)
     177              :      * @param responseDelayMs Response delay milliseconds filled by reference (if any transformation applies)
     178              :      * @param outState out-state for request context created, filled by reference (if any transformation applies)
     179              :      * @param outStateMethod method inferred towards a virtual server data entry created through a foreign out-state, filled by reference (if any transformation applies)
     180              :      * @param outStateUri uri inferred towards a virtual server data entry created through a foreign out-state, filled by reference (if any transformation applies)
     181              :      */
     182              :     void transform( const std::string &requestUri,
     183              :                     const std::string &requestUriPath,
     184              :                     const std::map<std::string, std::string> &requestQueryParametersMap,
     185              :                     DataPart &requestBodyDataPart,
     186              :                     const nghttp2::asio_http2::header_map &requestHeaders,
     187              :                     std::uint64_t generalUniqueServerSequence,
     188              : 
     189              :                     unsigned int &responseStatusCode,
     190              :                     nghttp2::asio_http2::header_map &responseHeaders,
     191              :                     std::string &responseBody,
     192              :                     unsigned int &responseDelayMs,
     193              :                     std::string &outState,
     194              :                     std::string &outStateMethod,
     195              :                     std::string &outStateUri
     196              :                   );
     197              : 
     198              :     // setters:
     199              : 
     200              :     /**
     201              :      * Load provision information
     202              :      *
     203              :      * @param j Json provision object
     204              :      * @param regexMatchingConfigured provision load depends on matching configuration (priority regexp)
     205              :      *
     206              :      * @return Operation success
     207              :      */
     208              :     bool load(const nlohmann::json &j, bool regexMatchingConfigured);
     209              : 
     210              :     /**
     211              :      * Sets the internal mock server data,
     212              :      * just in case it is used in event source
     213              :      */
     214          117 :     void setMockServerData(model::MockServerData *p) {
     215          117 :         mock_server_events_data_ = p;
     216          117 :     }
     217              : 
     218              :     /**
     219              :      * Sets the internal mock client data,
     220              :      * just in case it is used in event source
     221              :      */
     222          117 :     void setMockClientData(model::MockClientData *p) {
     223          117 :         mock_client_events_data_ = p;
     224          117 :     }
     225              : 
     226              :     /**
     227              :      * Sets the admin data reference,
     228              :      * just in case it is used in SchemaId filter
     229              :      */
     230          117 :     void setAdminData(model::AdminData *p) {
     231          117 :         admin_data_ = p;
     232          117 :     }
     233              : 
     234              :     /**
     235              :      * Sets the configuration reference,
     236              :      * just in case it is used in event target
     237              :      */
     238          117 :     void setConfiguration(model::Configuration *p) {
     239          117 :         configuration_ = p;
     240          117 :     }
     241              : 
     242              :     /**
     243              :      * Sets the global variables data reference,
     244              :      * just in case it is used in event source
     245              :      */
     246          117 :     void setGlobalVariable(model::GlobalVariable *p) {
     247          117 :         global_variable_ = p;
     248          117 :     }
     249              : 
     250              :     /**
     251              :      * Sets the file manager reference,
     252              :      * just in case it is used in event target
     253              :      */
     254          117 :     void setFileManager(model::FileManager *p) {
     255          117 :         file_manager_ = p;
     256          117 :     }
     257              : 
     258              :     /**
     259              :      * Sets the socket manager reference,
     260              :      * just in case it is used in event target
     261              :      */
     262          117 :     void setSocketManager(model::SocketManager *p) {
     263          117 :         socket_manager_ = p;
     264          117 :     }
     265              : 
     266              :     /**
     267              :      * Provision is being employed
     268              :      */
     269            5 :     void employ() {
     270            5 :         employed_ = true;
     271            5 :     }
     272              : 
     273              :     // getters:
     274              : 
     275              :     /**
     276              :      * Gets the provision request uri which could be a regular expression
     277              :      * or a full-matched URI string
     278              :      *
     279              :      * @return Provision request URI
     280              :      */
     281            6 :     const admin_server_provision_key_t &getRequestUri() const {
     282            6 :         return request_uri_;
     283              :     }
     284              : 
     285              :     /**
     286              :      * Gets the provision key as '<in-state>|<request-method>|<request-uri>'
     287              :      *
     288              :      * @return Provision key
     289              :      */
     290          117 :     const admin_server_provision_key_t &getKey() const {
     291          117 :         return key_;
     292              :     }
     293              : 
     294              :     /**
     295              :      * Json for class information
     296              :      *
     297              :      * @return Json object
     298              :      */
     299            7 :     const nlohmann::json &getJson() const {
     300            7 :         return json_;
     301              :     }
     302              : 
     303              :     /**
     304              :      * Precompiled regex for provision key
     305              :      *
     306              :      * @return regex
     307              :      */
     308            4 :     const std::regex &getRegex() const {
     309            4 :         return regex_;
     310              :     }
     311              : 
     312              :     /** Provisioned out state
     313              :      *
     314              :      * @return Out state
     315              :      */
     316          105 :     const std::string &getOutState() const {
     317          105 :         return out_state_;
     318              :     }
     319              : 
     320              :     /** Provisioned in state
     321              :      *
     322              :      * @return In state
     323              :      */
     324            3 :     const std::string &getInState() const {
     325            3 :         return in_state_;
     326              :     }
     327              : 
     328              :     /** Provisioned response code
     329              :      *
     330              :      * @return Response code
     331              :      */
     332          103 :     unsigned int getResponseCode() const {
     333          103 :         return response_code_;
     334              :     }
     335              : 
     336              :     /** Provisioned response headers
     337              :      *
     338              :      * @return Response headers
     339              :      */
     340          103 :     const nghttp2::asio_http2::header_map &getResponseHeaders() const {
     341          103 :         return response_headers_;
     342              :     }
     343              : 
     344              :     /** Provisioned response body as json representation
     345              :      *
     346              :      * @return Response body as json representation
     347              :      */
     348           37 :     const nlohmann::json &getResponseBody() const {
     349           37 :         return response_body_;
     350              :     }
     351              : 
     352              :     /** Provisioned response body as string.
     353              :      *
     354              :      * This is useful as cached response data when the provision
     355              :      * response is not modified with transformation items.
     356              :      *
     357              :      * When the object is not a valid json, the data is
     358              :      * assumed as a readable string (TODO: refactor for multipart support)
     359              :      *
     360              :      * @return Response body string
     361              :      */
     362           70 :     const std::string &getResponseBodyAsString() const {
     363           70 :         return response_body_string_;
     364              :     }
     365              : 
     366              :     /** Provisioned response delay milliseconds
     367              :      *
     368              :      * @return Response delay milliseconds
     369              :      */
     370          103 :     unsigned int getResponseDelayMilliseconds() const {
     371          103 :         return response_delay_ms_;
     372              :     }
     373              : 
     374              :     /** Provisioned request schema reference
     375              :      *
     376              :      * @return Request schema to validate incoming traffic, nullptr if missing
     377              :      */
     378              :     std::shared_ptr<h2agent::model::AdminSchema> getRequestSchema();
     379              : 
     380              :     /** Provisioned response schema reference
     381              :      *
     382              :      * @return Response schema to validate outgoing traffic, nullptr if missing
     383              :      */
     384              :     std::shared_ptr<h2agent::model::AdminSchema> getResponseSchema();
     385              : 
     386              :     /** Provision was employed
     387              :      *
     388              :      * @return Boolean about if this provision has been used
     389              :      */
     390            4 :     bool employed() const {
     391            4 :         return employed_;
     392              :     }
     393              : };
     394              : 
     395              : }
     396              : }
     397              : 
        

Generated by: LCOV version 2.0-1