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-2025 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 #define AUTHORIZATION_URL_ADH "REGION_PLACEHOLDER.datahub.connect.aveva.com"
61 #define AUTHORIZATION_URL_OCS "REGION_PLACEHOLDER.osisoft.com:443"
62 
63 enum OMF_ENDPOINT_PORT {
64  ENDPOINT_PORT_PIWEB_API=443,
65  ENDPOINT_PORT_CR=5460,
66  ENDPOINT_PORT_OCS=443,
67  ENDPOINT_PORT_EDS=5590,
68  ENDPOINT_PORT_ADH=443
69 };
70 
75 #define NOT_BLOCKING_ERRORS_DEFAULT QUOTE( \
76  { \
77  "errors400" : [ \
78  "Redefinition of the type with the same ID is not allowed", \
79  "Invalid value type for the property", \
80  "Property does not exist in the type definition", \
81  "Container is not defined", \
82  "Unable to find the property of the container of type" \
83  ] \
84  } \
85 )
86 
87 #define NOT_BLOCKING_ERRORS_DEFAULT_PI_WEB_API QUOTE( \
88  { \
89  "EventInfo" : [ \
90  "The specified value is outside the allowable range" \
91  ] \
92  } \
93 )
94 
95 #define AF_HIERARCHY_RULES QUOTE( \
96  { \
97  } \
98 )
99 
107  public:
108  OMFInformation(ConfigCategory* configData);
109  ~OMFInformation();
110  void start(const std::string& storedData);
111  uint32_t send(const vector<Reading *>& readings);
112  std::string saveData();
113  private:
114  void loadSentDataTypes(rapidjson::Document& JSONData);
115  long getMaxTypeId();
116  int PIWebAPIGetVersion(bool logMessage = true);
117  int EDSGetVersion(bool logMessage = true);
118  int IsADHConnected(bool logMessage = true);
119  void SetOMFVersion();
120  void CheckDataActionCode();
121  OMF_ENDPOINT identifyPIServerEndpoint();
122  std::string saveSentDataTypes();
123  unsigned long calcTypeShort(const std::string& dataTypes);
124  void ParseProductVersion(std::string &versionString, int *major, int *minor);
125  std::string ParseEDSProductInformation(std::string json);
126  std::string AuthBasicCredentialsGenerate(std::string& userId, std::string& password);
127  void AuthKerberosSetup(std::string& keytabEnv, std::string& keytabFileName);
128  double GetElapsedTime(struct timeval *startTime);
129  bool IsDataArchiveConnected();
130  void handleOMFTracing();
131 
132  private:
133  Logger *m_logger;
134  HttpSender *m_sender; // HTTPS connection
135  OMF *m_omf; // OMF data protocol
136  OCS *m_ocs; // ADH and OCS authorization
137  bool m_sendFullStructure; // It sends the minimum OMF structural messages to load data into PI Data Archive if disabled
138  bool m_compression; // whether to compress readings' data
139  string m_protocol; // http / https
140  string m_hostAndPort; // hostname:port for SimpleHttps
141  unsigned int m_retrySleepTime; // Seconds between each retry
142  unsigned int m_maxRetry; // Max number of retries in the communication
143  unsigned int m_timeout; // connect and operation timeout
144  string m_path; // PI Server application path
145  string m_delimiter; // delimiter between Asset and Datapoint in PI data stream names
146  string m_dataActionCode; // Action code to use for OMF Data posts: update or create
147  long m_typeId; // OMF protocol type-id prefix
148  string m_producerToken; // PI Server connector token
149  string m_formatNumber; // OMF protocol Number format
150  string m_formatInteger; // OMF protocol Integer format
151  OMF_ENDPOINT m_PIServerEndpoint; // Defines which End point should be used for the communication
152  NAMINGSCHEME_ENDPOINT
153  m_NamingScheme; // Define how the object names should be generated - https://fledge-iot.readthedocs.io/en/latest/OMF.html#naming-scheme
154  string m_DefaultAFLocation; // 1st hierarchy in Asset Framework, PI Web API only.
155  string m_AFMap; // Defines a set of rules to address where assets should be placed in the AF hierarchy.
156  // https://fledge-iot.readthedocs.io/en/latest/OMF.html#asset-framework-hierarchy-rules
157 
158  string m_prefixAFAsset; // Prefix to generate unique asset id
159  string m_PIWebAPIProductTitle;
160  string m_RestServerVersion;
161  string m_PIWebAPIAuthMethod; // Authentication method to be used with the PI Web API.
162  string m_PIWebAPICredentials; // Credentials is the base64 encoding of id and password joined by a single colon (:)
163  string m_KerberosKeytab; // Kerberos authentication keytab file
164  // stores the environment variable value about the keytab file path
165  // to allow the environment to persist for all the execution of the plugin
166  //
167  // Note : A keytab is a file containing pairs of Kerberos principals
168  // and encrypted keys (which are derived from the Kerberos password).
169  // You can use a keytab file to authenticate to various remote systems
170  // using Kerberos without entering a password.
171 
172  string m_OCSNamespace; // ADH & OCS configurations
173  string m_OCSTenantId;
174  string m_OCSClientId;
175  string m_OCSClientSecret;
176  string m_OCSToken;
177  string m_authUrl;
178 
179  vector<pair<string, string>>
180  m_staticData; // Static data
181  // Errors considered not blocking in the communication with the PI Server
182  std::vector<std::string>
183  m_notBlockingErrors;
184  // Per asset DataTypes
185  std::map<std::string, OMFDataTypes>
186  m_assetsDataTypes;
187  string m_omfversion;
188  bool m_legacy;
189  string m_name;
190  bool m_connected;
191  bool m_tracingEnabled;
192  std::size_t m_numBlocks;
193 };
194 #endif
OCS
The OCS class.
Definition: ocs.h:29
OMF
The OMF class.
Definition: omf.h:109
OMFInformation
A class that holds the configuration information for the OMF plugin.
Definition: omfinfo.h:106
OMFInformation::~OMFInformation
~OMFInformation()
Destructor for the OMFInformation class.
Definition: omfinfo.cpp:385
HttpSender
Definition: http_sender.h:20
ConfigCategory
Definition: config_category.h:56
OMFInformation::start
void start(const std::string &storedData)
The plugin start entry point has been called.
Definition: omfinfo.cpp:399
OMFInformation::OMFInformation
OMFInformation(ConfigCategory *configData)
Constructor for the OMFInformation class.
Definition: omfinfo.cpp:20
OMFInformation::send
uint32_t send(const vector< Reading * > &readings)
Send data to the OMF endpoint.
Definition: omfinfo.cpp:636
Logger
Fledge Logger class used to log to syslog.
Definition: logger.h:42
OMFInformation::saveData
std::string saveData()
Return the data to be persisted.
Definition: omfinfo.cpp:701