Fledge
An open source edge computing platform for industrial users
management_client.h
1 #ifndef _MANAGEMENT_CLIENT_H
2 #define _MANAGEMENT_CLIENT_H
3 /*
4  * Fledge storage service.
5  *
6  * Copyright (c) 2017-2018 OSisoft, LLC
7  *
8  * Released under the Apache 2.0 Licence
9  *
10  * Author: Mark Riddoch, Massimiliano Pinto
11  */
12 
13 #include <client_http.hpp>
14 #include <server_http.hpp>
15 #include <config_category.h>
16 #include <service_record.h>
17 #include <logger.h>
18 #include <string>
19 #include <map>
20 #include <vector>
21 #include <rapidjson/document.h>
22 #include <asset_tracking.h>
23 #include <json_utils.h>
24 #include <thread>
25 #include <bearer_token.h>
26 #include <acl.h>
27 #include "utils.h"
28 
29 using HttpClient = SimpleWeb::Client<SimpleWeb::HTTP>;
30 using HttpServer = SimpleWeb::Server<SimpleWeb::HTTP>;
31 using namespace rapidjson;
32 
33 class AssetTrackingTuple;
34 class AssetTrackingTable;
36 
45  public:
46  ManagementClient(const std::string& hostname, const unsigned short port);
48  bool registerService(const ServiceRecord& service);
49  bool unregisterService();
50  bool restartService();
51  bool getService(ServiceRecord& service);
52  bool getServices(std::vector<ServiceRecord *>& services);
53  bool getServices(std::vector<ServiceRecord *>& services, const std::string& type);
54  bool registerCategory(const std::string& categoryName);
55  bool registerCategoryChild(const std::string& categoryName);
56  bool unregisterCategory(const std::string& categoryName);
57  ConfigCategories getCategories();
58  ConfigCategory getCategory(const std::string& categoryName);
59  std::string setCategoryItemValue(const std::string& categoryName,
60  const std::string& itemName,
61  const std::string& itemValue);
62  std::string addChildCategories(const std::string& parentCategory,
63  const std::vector<std::string>& children);
64  std::vector<AssetTrackingTuple*>&
65  getAssetTrackingTuples(const std::string serviceName = "");
66  std::vector<StorageAssetTrackingTuple*>&
67  getStorageAssetTrackingTuples(const std::string serviceName);
68 
69  StorageAssetTrackingTuple* getStorageAssetTrackingTuple(const std::string& serviceName,
70  const std::string& assetName,
71  const std::string& event, const std::string & dp, const unsigned int& c);
72 
73  bool addAssetTrackingTuple(const std::string& service,
74  const std::string& plugin,
75  const std::string& asset,
76  const std::string& event);
77 
78  bool addStorageAssetTrackingTuple(const std::string& service,
79  const std::string& plugin,
80  const std::string& asset,
81  const std::string& event,
82  const bool& deprecated = false,
83  const std::string& datapoints = "",
84  const int& count = 0);
85  ConfigCategories getChildCategories(const std::string& categoryName);
86  HttpClient *getHttpClient();
87  bool addAuditEntry(const std::string& serviceName,
88  const std::string& severity,
89  const std::string& details);
90  std::string& getRegistrationBearerToken()
91  {
92  std::lock_guard<std::mutex> guard(m_bearer_token_mtx);
93  return m_bearer_token;
94  };
95  void setNewBearerToken(const std::string& bearerToken)
96  {
97  std::lock_guard<std::mutex> guard(m_bearer_token_mtx);
98  m_bearer_token = bearerToken;
99  };
100  bool verifyBearerToken(BearerToken& token);
101  bool verifyAccessBearerToken(BearerToken& bToken);
102  bool verifyAccessBearerToken(std::shared_ptr<HttpServer::Request> request);
103  bool refreshBearerToken(const std::string& currentToken,
104  std::string& newToken);
105  std::string& getBearerToken() { return m_bearer_token; };
106  bool addProxy(const std::string& serviceName,
107  const std::string& operation,
108  const std::string& publicEnpoint,
109  const std::string& privateEndpoint);
110  bool addProxy(const std::string& serviceName,
111  const std::map<std::string,
112  std::vector<std::pair<std::string, std::string> > >& endpoints);
113  bool deleteProxy(const std::string& serviceName);
114  const std::string getUrlbase() { return m_urlbase.str(); }
115  ACL getACL(const std::string& aclName);
116  AssetTrackingTuple* getAssetTrackingTuple(const std::string& serviceName,
117  const std::string& assetName,
118  const std::string& event);
119  int validateDatapoints(std::string dp1, std::string dp2);
120  AssetTrackingTable *getDeprecatedAssetTrackingTuples();
121  std::string getAlertByKey(const std::string& key);
122  bool raiseAlert(const std::string& key, const std::string& message, const std::string& urgency="normal");
123  bool clearAlert(const std::string& key);
124 
125  private:
126  std::ostringstream m_urlbase;
127  std::map<std::thread::id, HttpClient *> m_client_map;
128  HttpClient *m_client;
129  std::string *m_uuid;
130  Logger *m_logger;
131  std::map<std::string, std::string> m_categories;
132  // Bearer token returned by service registration
133  // if the service startup token has been passed in registration payload
134  std::string m_bearer_token;
135  // Map of received and verified access bearer tokens from other microservices
136  std::map<std::string, BearerToken> m_received_tokens;
137  // m_received_tokens lock
138  std::mutex m_mtx_rTokens;
139  // m_client_map lock
140  std::mutex m_mtx_client_map;
141  // Get and set bearer token mutex
142  std::mutex m_bearer_token_mtx;
143 
144  public:
145  // member template must be here and not in .cpp file
146  template<class T> bool addCategory(const T& t, bool keepOriginalItems = false)
147  {
148  try {
149  std::string blockedCharacter = {};
150  if (!isValidIdentifier(t.getName(), blockedCharacter))
151  {
152  m_logger->error("The category name %s contains %s invalid character(s).", blockedCharacter.c_str(), t.getName().c_str());
153  return false;
154  }
155  std::string url = "/fledge/service/category";
156 
157  // Build the JSON payload
158  std::ostringstream payload;
159  payload << "{ \"key\" : \"" << JSONescape(t.getName());
160  payload << "\", \"description\" : \"" << JSONescape(t.getDescription());
161  if (! t.getDisplayName().empty() ) {
162  payload << "\", \"display_name\" : \"" << JSONescape(t.getDisplayName());
163  }
164  payload << "\", \"value\" : " << t.itemsToJSON();
165 
166 
175  if (keepOriginalItems)
176  {
177  url += "?keep_original_items=true";
178  }
179 
180  // Terminate JSON string
181  payload << " }";
182 
183  auto res = this->getHttpClient()->request("POST", url.c_str(), payload.str());
184 
185  Document doc;
186  std::string response = res->content.string();
187 
188  doc.Parse(response.c_str());
189  if (doc.HasParseError())
190  {
191  m_logger->error("Failed to parse result of adding a category: %s\n",
192  response.c_str());
193  return false;
194  }
195  else if (doc.HasMember("message"))
196  {
197  m_logger->error("Failed to add configuration category: %s.",
198  doc["message"].GetString());
199  return false;
200  }
201  else
202  {
203  return true;
204  }
205  } catch (const SimpleWeb::system_error &e) {
206  m_logger->error("Add config category failed %s.", e.what());
207  }
208  return false;
209  };
210 };
211 
212 #endif
BearerToken
This class represents a JWT bearer token.
Definition: bearer_token.h:24
AssetTrackingTable
A class to hold a set of asset tracking tuples that allows lookup by name.
Definition: asset_tracking.h:305
Logger::error
void error(const std::string &msg,...)
Log a message at the level error.
Definition: logger.cpp:447
ConfigCategories
Definition: config_category.h:37
AssetTrackingTuple
The AssetTrackingTuple class is used to represent an asset tracking tuple.
Definition: asset_tracking.h:47
ACL
This class represents the ACL (Access Control List) as JSON object fetched from Fledge Storage.
Definition: acl.h:23
ManagementClient
The management client class used by services and tasks to communicate with the management API of the ...
Definition: management_client.h:44
ServiceRecord
Definition: service_record.h:15
ConfigCategory
Definition: config_category.h:56
ManagementClient::addCategory
bool addCategory(const T &t, bool keepOriginalItems=false)
Definition: management_client.h:146
StorageAssetTrackingTuple
Definition: asset_tracking.h:129
Logger
Fledge Logger class used to log to syslog.
Definition: logger.h:42