Fledge
An open source edge computing platform for industrial users
omfinfo.h
1 #ifndef _OMFINFO_H
2 #define _OMFINFO_H
3 /*
4  * Fledge OSIsoft OMF interface to PI Server.
5  *
6  * Copyright (c) 2023 Dianomic Systems
7  *
8  * Released under the Apache 2.0 Licence
9  *
10  * Author: Mark Riddoch
11  */
12 #include <plugin_api.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <strings.h>
16 #include <string>
17 #include <logger.h>
18 #include <plugin_exception.h>
19 #include <iostream>
20 #include <omf.h>
21 #include <piwebapi.h>
22 #include <ocs.h>
23 #include <simple_https.h>
24 #include <simple_http.h>
25 #include <config_category.h>
26 #include "rapidjson/writer.h"
27 #include "rapidjson/stringbuffer.h"
28 #include "json_utils.h"
29 #include "libcurl_https.h"
30 #include "utils.h"
31 #include "string_utils.h"
32 #include <version.h>
33 #include <linkedlookup.h>
34 
35 #include "crypto.hpp"
36 
37 #define PLUGIN_NAME "OMF"
38 #define TYPE_ID_KEY "type-id"
39 #define SENT_TYPES_KEY "sentDataTypes"
40 #define DATA_KEY "dataTypes"
41 #define DATA_KEY_SHORT "dataTypesShort"
42 #define DATA_KEY_HINT "hintChecksum"
43 #define NAMING_SCHEME "namingScheme"
44 #define AFH_HASH "afhHash"
45 #define AF_HIERARCHY "afHierarchy"
46 #define AF_HIERARCHY_ORIG "afHierarchyOrig"
47 
48 
49 #define PROPERTY_TYPE "type"
50 #define PROPERTY_NUMBER "number"
51 #define PROPERTY_STRING "string"
52 
53 #define ENDPOINT_URL_PI_WEB_API "https://HOST_PLACEHOLDER:PORT_PLACEHOLDER/piwebapi/omf"
54 #define ENDPOINT_URL_CR "https://HOST_PLACEHOLDER:PORT_PLACEHOLDER/ingress/messages"
55 #define ENDPOINT_URL_OCS "https://REGION_PLACEHOLDER.osisoft.com:PORT_PLACEHOLDER/api/v1/tenants/TENANT_ID_PLACEHOLDER/Namespaces/NAMESPACE_ID_PLACEHOLDER/omf"
56 #define ENDPOINT_URL_ADH "https://REGION_PLACEHOLDER.datahub.connect.aveva.com:PORT_PLACEHOLDER/api/v1/Tenants/TENANT_ID_PLACEHOLDER/Namespaces/NAMESPACE_ID_PLACEHOLDER/omf"
57 
58 #define ENDPOINT_URL_EDS "http://localhost:PORT_PLACEHOLDER/api/v1/tenants/default/namespaces/default/omf"
59 
60 
61 enum OMF_ENDPOINT_PORT {
62  ENDPOINT_PORT_PIWEB_API=443,
63  ENDPOINT_PORT_CR=5460,
64  ENDPOINT_PORT_OCS=443,
65  ENDPOINT_PORT_EDS=5590,
66  ENDPOINT_PORT_ADH=443
67 };
68 
73 #define NOT_BLOCKING_ERRORS_DEFAULT QUOTE( \
74  { \
75  "errors400" : [ \
76  "Redefinition of the type with the same ID is not allowed", \
77  "Invalid value type for the property", \
78  "Property does not exist in the type definition", \
79  "Container is not defined", \
80  "Unable to find the property of the container of type" \
81  ] \
82  } \
83 )
84 
85 #define NOT_BLOCKING_ERRORS_DEFAULT_PI_WEB_API QUOTE( \
86  { \
87  "EventInfo" : [ \
88  "The specified value is outside the allowable range" \
89  ] \
90  } \
91 )
92 
93 #define AF_HIERARCHY_RULES QUOTE( \
94  { \
95  } \
96 )
97 
105  public:
106  OMFInformation(ConfigCategory* configData);
107  ~OMFInformation();
108  void start(const std::string& storedData);
109  uint32_t send(const vector<Reading *>& readings);
110  std::string saveData();
111  private:
112  void loadSentDataTypes(rapidjson::Document& JSONData);
113  long getMaxTypeId();
114  int PIWebAPIGetVersion(bool logMessage = true);
115  int EDSGetVersion();
116  void SetOMFVersion();
117  void CheckDataActionCode();
118  std::string OCSRetrieveAuthToken();
119  OMF_ENDPOINT identifyPIServerEndpoint();
120  std::string saveSentDataTypes();
121  unsigned long calcTypeShort(const std::string& dataTypes);
122  void ParseProductVersion(std::string &versionString, int *major, int *minor);
123  std::string ParseEDSProductInformation(std::string json);
124  std::string AuthBasicCredentialsGenerate(std::string& userId, std::string& password);
125  void AuthKerberosSetup(std::string& keytabEnv, std::string& keytabFileName);
126  double GetElapsedTime(struct timeval *startTime);
127  bool IsPIWebAPIConnected();
128  void handleOMFTracing();
129 
130  private:
131  Logger *m_logger;
132  HttpSender *m_sender; // HTTPS connection
133  OMF *m_omf; // OMF data protocol
134  bool m_sendFullStructure; // It sends the minimum OMF structural messages to load data into PI Data Archive if disabled
135  bool m_compression; // whether to compress readings' data
136  string m_protocol; // http / https
137  string m_hostAndPort; // hostname:port for SimpleHttps
138  unsigned int m_retrySleepTime; // Seconds between each retry
139  unsigned int m_maxRetry; // Max number of retries in the communication
140  unsigned int m_timeout; // connect and operation timeout
141  string m_path; // PI Server application path
142  string m_delimiter; // delimiter between Asset and Datapoint in PI data stream names
143  string m_dataActionCode; // Action code to use for OMF Data posts: update or create
144  long m_typeId; // OMF protocol type-id prefix
145  string m_producerToken; // PI Server connector token
146  string m_formatNumber; // OMF protocol Number format
147  string m_formatInteger; // OMF protocol Integer format
148  OMF_ENDPOINT m_PIServerEndpoint; // Defines which End point should be used for the communication
149  NAMINGSCHEME_ENDPOINT
150  m_NamingScheme; // Define how the object names should be generated - https://fledge-iot.readthedocs.io/en/latest/OMF.html#naming-scheme
151  string m_DefaultAFLocation; // 1st hierarchy in Asset Framework, PI Web API only.
152  string m_AFMap; // Defines a set of rules to address where assets should be placed in the AF hierarchy.
153  // https://fledge-iot.readthedocs.io/en/latest/OMF.html#asset-framework-hierarchy-rules
154 
155  string m_prefixAFAsset; // Prefix to generate unique asset id
156  string m_PIWebAPIProductTitle;
157  string m_RestServerVersion;
158  string m_PIWebAPIAuthMethod; // Authentication method to be used with the PI Web API.
159  string m_PIWebAPICredentials; // Credentials is the base64 encoding of id and password joined by a single colon (:)
160  string m_KerberosKeytab; // Kerberos authentication keytab file
161  // stores the environment variable value about the keytab file path
162  // to allow the environment to persist for all the execution of the plugin
163  //
164  // Note : A keytab is a file containing pairs of Kerberos principals
165  // and encrypted keys (which are derived from the Kerberos password).
166  // You can use a keytab file to authenticate to various remote systems
167  // using Kerberos without entering a password.
168 
169  string m_OCSNamespace; // OCS configurations
170  string m_OCSTenantId;
171  string m_OCSClientId;
172  string m_OCSClientSecret;
173  string m_OCSToken;
174 
175  vector<pair<string, string>>
176  m_staticData; // Static data
177  // Errors considered not blocking in the communication with the PI Server
178  std::vector<std::string>
179  m_notBlockingErrors;
180  // Per asset DataTypes
181  std::map<std::string, OMFDataTypes>
182  m_assetsDataTypes;
183  string m_omfversion;
184  bool m_legacy;
185  string m_name;
186  bool m_connected;
187  bool m_tracingEnabled;
188 };
189 #endif
Fledge Logger class used to log to syslog.
Definition: logger.h:26
std::string saveData()
Return the data to be persisted.
Definition: omfinfo.cpp:668
Definition: config_category.h:56
The OMF class.
Definition: omf.h:109
OMFInformation(ConfigCategory *configData)
Constructor for the OMFInformation class.
Definition: omfinfo.cpp:20
void start(const std::string &storedData)
The plugin start entry point has been called.
Definition: omfinfo.cpp:392
~OMFInformation()
Destructor for the OMFInformation class.
Definition: omfinfo.cpp:377
Definition: http_sender.h:20
uint32_t send(const vector< Reading *> &readings)
Send data to the OMF endpoint.
Definition: omfinfo.cpp:501
A class that holds the configuration information for the OMF plugin.
Definition: omfinfo.h:104