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