mirror of
https://github.com/openappsec/openappsec.git
synced 2025-09-29 11:16:30 +03:00
Jan_31_2024-Dev
This commit is contained in:
@@ -24,6 +24,15 @@
|
||||
#define MAX_FINAL_SCORE 10.0
|
||||
#define ATTACK_IN_PARAM "attack_in_param"
|
||||
|
||||
enum TrafficMethod {
|
||||
POST,
|
||||
GET,
|
||||
PUT,
|
||||
PATCH,
|
||||
DELETE,
|
||||
OTHER
|
||||
};
|
||||
|
||||
enum ThreatLevel {
|
||||
NO_THREAT = 0,
|
||||
THREAT_INFO,
|
||||
|
@@ -54,6 +54,8 @@ public:
|
||||
|
||||
MatchQuery(): is_specific_label(false), is_ignore_keyword(false) {}
|
||||
|
||||
MatchQuery(const std::string &match);
|
||||
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
MatchType getType() const { return type; }
|
||||
|
24
components/include/geo_location.h
Normal file
24
components/include/geo_location.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef __GEO_LOCATION_H__
|
||||
#define __GEO_LOCATION_H__
|
||||
|
||||
#include "i_geo_location.h"
|
||||
#include "singleton.h"
|
||||
#include "component.h"
|
||||
|
||||
class GeoLocation : public Component, Singleton::Provide<I_GeoLocation>
|
||||
{
|
||||
public:
|
||||
GeoLocation();
|
||||
~GeoLocation();
|
||||
|
||||
void preload();
|
||||
|
||||
void init();
|
||||
void fini();
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> pimpl;
|
||||
};
|
||||
|
||||
#endif // __GEO_LOCATION_H__
|
35
components/include/http_geo_filter.h
Normal file
35
components/include/http_geo_filter.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef __HTTP_GEO_FILTER_H__
|
||||
#define __HTTP_GEO_FILTER_H__
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "singleton.h"
|
||||
#include "i_mainloop.h"
|
||||
#include "component.h"
|
||||
#include "http_inspection_events.h"
|
||||
#include "i_geo_location.h"
|
||||
#include "i_generic_rulebase.h"
|
||||
|
||||
class HttpGeoFilter
|
||||
:
|
||||
public Component,
|
||||
Singleton::Consume<I_MainLoop>,
|
||||
Singleton::Consume<I_GeoLocation>,
|
||||
Singleton::Consume<I_GenericRulebase>
|
||||
{
|
||||
public:
|
||||
HttpGeoFilter();
|
||||
~HttpGeoFilter();
|
||||
|
||||
void preload() override;
|
||||
|
||||
void init() override;
|
||||
void fini() override;
|
||||
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> pimpl;
|
||||
};
|
||||
|
||||
#endif // __HTTP_GEO_FILTER_H__
|
@@ -27,7 +27,7 @@ public:
|
||||
virtual std::string getAgentVersion() = 0;
|
||||
virtual bool isKernelVersion3OrHigher() = 0;
|
||||
virtual bool isGwNotVsx() = 0;
|
||||
virtual bool isVersionEqualOrAboveR8110() = 0;
|
||||
virtual bool isVersionAboveR8110() = 0;
|
||||
virtual bool isReverseProxy() = 0;
|
||||
virtual Maybe<std::tuple<std::string, std::string, std::string>> parseNginxMetadata() = 0;
|
||||
virtual std::map<std::string, std::string> getResolvedDetails() = 0;
|
||||
|
@@ -40,6 +40,10 @@ public:
|
||||
const std::string &service_name
|
||||
) const = 0;
|
||||
|
||||
virtual Maybe<std::string> checkIfFileExists(const Package &package) const = 0;
|
||||
|
||||
virtual void removeDownloadFile(const std::string &file_name) const = 0;
|
||||
|
||||
virtual std::string getProfileFromMap(const std::string &tenant_id) const = 0;
|
||||
};
|
||||
|
||||
|
22
components/include/i_geo_location.h
Normal file
22
components/include/i_geo_location.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef __I_GEO_LOCATION_H__
|
||||
#define __I_GEO_LOCATION_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "connkey.h"
|
||||
#include "enum_array.h"
|
||||
|
||||
|
||||
class I_GeoLocation
|
||||
{
|
||||
public:
|
||||
enum class GeoLocationField { COUNTRY_NAME, COUNTRY_CODE, CONTINENT_NAME, CONTINENT_CODE, COUNT };
|
||||
|
||||
virtual Maybe<EnumArray<GeoLocationField, std::string>> lookupLocation(const std::string &ip) = 0;
|
||||
virtual Maybe<EnumArray<GeoLocationField, std::string>> lookupLocation(const IPAddr &ip) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~I_GeoLocation() {}
|
||||
};
|
||||
|
||||
#endif // __I_GEO_LOCATION_H__
|
37
components/include/i_oa_schema_updater.h
Normal file
37
components/include/i_oa_schema_updater.h
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __I_OA_SCHEMA_UPDATER_H__
|
||||
#define __I_OA_SCHEMA_UPDATER_H__
|
||||
|
||||
#include <string>
|
||||
#include "i_transaction.h"
|
||||
#include "../security_apps/waap/waap_clib/oasu_key_types.h"
|
||||
#include "../security_apps/waap/waap_clib/events_for_oa_schema.h"
|
||||
|
||||
class I_OASUpdater
|
||||
{
|
||||
public:
|
||||
virtual void onKvt(const std::string &value, SchemaKeyType type, IWaf2Transaction &waf2Transaction) = 0;
|
||||
virtual void addOperationField(
|
||||
const std::string &operation_name,
|
||||
const std::string &operation_type,
|
||||
const std::string &field_name,
|
||||
IWaf2Transaction &waf2Transaction) = 0;
|
||||
virtual void removeGraphQLData(IWaf2Transaction &waf2Transaction) = 0;
|
||||
virtual void addActiveOperationName(
|
||||
const std::string &operation_name,
|
||||
IWaf2Transaction &waf2Transaction) = 0;
|
||||
};
|
||||
|
||||
#endif // __I_OA_SCHEMA_UPDATER_H__
|
@@ -33,7 +33,10 @@ public:
|
||||
) const = 0;
|
||||
virtual Maybe<void> authenticateAgent() = 0;
|
||||
virtual Maybe<void> getUpdate(CheckUpdateRequest &request) = 0;
|
||||
virtual Maybe<std::string> downloadAttributeFile(const GetResourceFile &resourse_file) = 0;
|
||||
virtual Maybe<std::string> downloadAttributeFile(
|
||||
const GetResourceFile &resourse_file,
|
||||
const std::string &file_path
|
||||
) = 0;
|
||||
virtual void setAddressExtenesion(const std::string &extension) = 0;
|
||||
};
|
||||
|
||||
|
@@ -23,6 +23,8 @@ struct DecisionTelemetryData
|
||||
std::string practiceId;
|
||||
std::string practiceName;
|
||||
std::string source;
|
||||
TrafficMethod method;
|
||||
int responseCode;
|
||||
std::set<std::string> attackTypes;
|
||||
|
||||
DecisionTelemetryData() :
|
||||
@@ -32,6 +34,8 @@ struct DecisionTelemetryData
|
||||
practiceId(),
|
||||
practiceName(),
|
||||
source(),
|
||||
method(POST),
|
||||
responseCode(0),
|
||||
attackTypes()
|
||||
{
|
||||
}
|
||||
|
@@ -36,15 +36,22 @@ public:
|
||||
std::map<std::string, Package> &corrupted_packages
|
||||
);
|
||||
|
||||
bool
|
||||
Maybe<std::vector<Package>>
|
||||
buildInstallationQueue(
|
||||
const Package &updated_package,
|
||||
const std::map<std::string, Package> ¤t_packages,
|
||||
const std::map<std::string, Package> &new_packages
|
||||
);
|
||||
|
||||
|
||||
private:
|
||||
Maybe<void>
|
||||
buildRecInstallationQueue(
|
||||
const Package &package,
|
||||
std::vector<Package> &installation_queue,
|
||||
const std::map<std::string, Package> ¤t_packages,
|
||||
const std::map<std::string, Package> &new_packages
|
||||
);
|
||||
|
||||
private:
|
||||
std::string corrupted_file_path;
|
||||
};
|
||||
#endif // __MANIFEST_DIFF_CALCULATOR_H__
|
||||
|
@@ -24,6 +24,8 @@
|
||||
#include "i_details_resolver.h"
|
||||
#include "i_time_get.h"
|
||||
|
||||
using packageFilePath = std::string;
|
||||
|
||||
class ManifestHandler
|
||||
:
|
||||
Singleton::Consume<I_MainLoop>,
|
||||
@@ -36,28 +38,23 @@ class ManifestHandler
|
||||
Singleton::Consume<I_DetailsResolver>
|
||||
{
|
||||
public:
|
||||
using packageFilePath = std::string;
|
||||
|
||||
ManifestHandler() = default;
|
||||
void init();
|
||||
|
||||
bool
|
||||
downloadPackages(
|
||||
const std::vector<Package> &updated_packages,
|
||||
std::vector<std::pair<Package, packageFilePath>> &downloaded_packages
|
||||
Maybe<std::vector<std::pair<Package, packageFilePath>>> downloadPackages(
|
||||
const std::map<std::string, Package> &new_packages_to_download
|
||||
);
|
||||
|
||||
bool
|
||||
installPackages(
|
||||
const std::vector<std::pair<Package, packageFilePath>> &downloaded_packages_files,
|
||||
bool installPackage(
|
||||
const std::pair<Package, std::string> &package_downloaded_file,
|
||||
std::map<packageFilePath, Package> ¤t_packages,
|
||||
std::map<packageFilePath, Package> &corrupted_packages
|
||||
);
|
||||
|
||||
bool uninstallPackage(Package &removed_package);
|
||||
|
||||
bool
|
||||
selfUpdate(
|
||||
bool selfUpdate(
|
||||
const Package &updated_package,
|
||||
std::map<packageFilePath, Package> ¤t_packages,
|
||||
const packageFilePath &installation_file
|
||||
|
4
components/include/oas_updater_entry_saver.h
Normal file
4
components/include/oas_updater_entry_saver.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef __SCHEMA_UPDATER_DATA_STRUCTURE_H__
|
||||
#define __SCHEMA_UPDATER_DATA_STRUCTURE_H__
|
||||
|
||||
#endif // __SCHEMA_UPDATER_DATA_STRUCTURE_H__
|
@@ -120,10 +120,10 @@ public:
|
||||
return std::string();
|
||||
}
|
||||
|
||||
I_Messaging::Method
|
||||
HTTPMethod
|
||||
getRequestMethod() const
|
||||
{
|
||||
return isVirtual() ? I_Messaging::Method::POST : I_Messaging::Method::GET;
|
||||
return isVirtual() ? HTTPMethod::POST : HTTPMethod::GET;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@@ -35,10 +35,11 @@ public:
|
||||
const std::string & getName() const { return name; }
|
||||
const std::string & getVersion() const { return version; }
|
||||
const std::string & getChecksum() const { return checksum_value; }
|
||||
const std::string & getErrorMessage() const { return error_message; }
|
||||
const PackageType & getType() const { return package_type; }
|
||||
const std::vector<std::string> & getRequire() const { return require_packages; }
|
||||
const ChecksumTypes & getChecksumType() const { return checksum_type; }
|
||||
const Maybe<void> & isInstallable() const { return installable; }
|
||||
const bool & isInstallable() const { return installable; }
|
||||
|
||||
bool operator==(const Package &other) const;
|
||||
bool operator!=(const Package &other) const;
|
||||
@@ -60,7 +61,8 @@ private:
|
||||
return std::string();
|
||||
}
|
||||
|
||||
Maybe<void> installable = Maybe<void>();
|
||||
bool installable = true;
|
||||
std::string error_message;
|
||||
std::string mirror;
|
||||
std::string name;
|
||||
std::string version;
|
||||
|
@@ -9,9 +9,20 @@
|
||||
#include "debug.h"
|
||||
#include "generic_rulebase/rulebase_config.h"
|
||||
#include "generic_rulebase/triggers_config.h"
|
||||
#include "generic_rulebase/match_query.h"
|
||||
#include "generic_rulebase/evaluators/trigger_eval.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_REVERSE_PROXY);
|
||||
USE_DEBUG_FLAG(D_RATE_LIMIT);
|
||||
|
||||
enum class RateLimitAction
|
||||
{
|
||||
INACTIVE,
|
||||
ACCORDING_TO_PRACTICE,
|
||||
DETECT,
|
||||
PREVENT,
|
||||
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
class RateLimitTrigger
|
||||
{
|
||||
@@ -34,12 +45,12 @@ public:
|
||||
operator bool() const
|
||||
{
|
||||
if (uri.empty()) {
|
||||
dbgTrace(D_REVERSE_PROXY) << "Recived empty URI in rate-limit rule";
|
||||
dbgTrace(D_RATE_LIMIT) << "Recived empty URI in rate-limit rule";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (uri.at(0) != '/') {
|
||||
dbgWarning(D_REVERSE_PROXY)
|
||||
dbgWarning(D_RATE_LIMIT)
|
||||
<< "Recived invalid rate-limit URI in rate-limit rule: "
|
||||
<< uri
|
||||
<< " rate-limit URI must start with /";
|
||||
@@ -47,7 +58,7 @@ public:
|
||||
}
|
||||
|
||||
if (limit <= 0) {
|
||||
dbgWarning(D_REVERSE_PROXY)
|
||||
dbgWarning(D_RATE_LIMIT)
|
||||
<< "Recived invalid rate-limit limit in rate-limit rule: "
|
||||
<< limit
|
||||
<< " rate-limit rule limit must be positive";
|
||||
@@ -70,10 +81,13 @@ public:
|
||||
const std::string & getRateLimitReq() const { return limit_req_template_value; }
|
||||
const std::string & getRateLimitUri() const { return uri; }
|
||||
const std::string & getRateLimitScope() const { return scope; }
|
||||
const RateLimitAction & getRateLimitAction() const { return action; }
|
||||
const MatchQuery & getRateLimitMatch() const { return match; }
|
||||
const LogTriggerConf & getRateLimitTrigger() const { return trigger; }
|
||||
const std::vector<RateLimitTrigger> & getRateLimitTriggers() const { return rate_limit_triggers; }
|
||||
|
||||
bool isRootLocation() const;
|
||||
bool isMatchAny() const;
|
||||
|
||||
bool operator==(const RateLimitRule &rhs) { return uri == rhs.uri; }
|
||||
bool operator<(const RateLimitRule &rhs) { return uri < rhs.uri; }
|
||||
@@ -87,21 +101,27 @@ private:
|
||||
std::string limit_req_template_value;
|
||||
std::string limit_req_zone_template_value;
|
||||
std::string cache_size = "5m";
|
||||
RateLimitAction action = RateLimitAction::ACCORDING_TO_PRACTICE;
|
||||
MatchQuery match = MatchQuery(default_match);
|
||||
std::vector<RateLimitTrigger> rate_limit_triggers;
|
||||
LogTriggerConf trigger;
|
||||
int limit;
|
||||
bool exact_match = false;
|
||||
|
||||
static const std::string default_match;
|
||||
};
|
||||
|
||||
class RateLimitConfig
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &ar);
|
||||
void addSiblingRateLimitRule(RateLimitRule &rule);
|
||||
void addSiblingRateLimitRules();
|
||||
void prepare();
|
||||
|
||||
const std::vector<RateLimitRule> & getRateLimitRules() const { return rate_limit_rules; }
|
||||
const std::string & getRateLimitMode() const { return mode; }
|
||||
const RateLimitAction & getRateLimitMode() const { return mode; }
|
||||
|
||||
RateLimitRule generateSiblingRateLimitRule(const RateLimitRule &rule);
|
||||
|
||||
const LogTriggerConf
|
||||
getRateLimitTrigger(const std::string &nginx_uri) const
|
||||
@@ -110,7 +130,7 @@ public:
|
||||
|
||||
std::set<std::string> rate_limit_triggers_set;
|
||||
for (const RateLimitTrigger &rate_limit_trigger : rule.getRateLimitTriggers()) {
|
||||
dbgTrace(D_REVERSE_PROXY)
|
||||
dbgTrace(D_RATE_LIMIT)
|
||||
<< "Adding trigger ID: "
|
||||
<< rate_limit_trigger.getTriggerId()
|
||||
<< " of rule URI: "
|
||||
@@ -130,12 +150,15 @@ public:
|
||||
|
||||
static bool isActive() { return is_active; }
|
||||
|
||||
static const std::map<RateLimitAction, std::string> rate_limit_action_to_string;
|
||||
static const std::map<std::string, RateLimitAction> rate_limit_string_to_action;
|
||||
|
||||
private:
|
||||
const RateLimitRule
|
||||
findLongestMatchingRule(const std::string &nginx_uri) const;
|
||||
|
||||
static bool is_active;
|
||||
std::string mode;
|
||||
RateLimitAction mode;
|
||||
std::vector<RateLimitRule> rate_limit_rules;
|
||||
};
|
||||
|
||||
|
@@ -37,7 +37,7 @@ public:
|
||||
audience_team,
|
||||
obj,
|
||||
false,
|
||||
MessageTypeTag::GENERIC,
|
||||
MessageCategory::GENERIC,
|
||||
std::forward<Args>(args)...
|
||||
)
|
||||
{
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
audience_team,
|
||||
obj,
|
||||
is_async_message,
|
||||
MessageTypeTag::GENERIC,
|
||||
MessageCategory::GENERIC,
|
||||
std::forward<Args>(args)...
|
||||
)
|
||||
{
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
const ReportIS::AudienceTeam &audience_team,
|
||||
const T &obj,
|
||||
bool is_async_message,
|
||||
const MessageTypeTag &message_type,
|
||||
const MessageCategory &message_type,
|
||||
Args ...args)
|
||||
:
|
||||
ReportMessaging(
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
priority,
|
||||
obj,
|
||||
false,
|
||||
MessageTypeTag::GENERIC,
|
||||
MessageCategory::GENERIC,
|
||||
std::forward<Args>(args)...
|
||||
)
|
||||
{
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
const ReportIS::Priority &priority,
|
||||
const T &obj,
|
||||
bool _is_async_message,
|
||||
const MessageTypeTag &message_type,
|
||||
const MessageCategory &message_type,
|
||||
Args ...args)
|
||||
:
|
||||
report(
|
||||
@@ -144,7 +144,7 @@ public:
|
||||
private:
|
||||
Report report;
|
||||
bool is_async_message;
|
||||
MessageTypeTag message_type_tag;
|
||||
MessageCategory message_type_tag;
|
||||
};
|
||||
|
||||
#endif // __REPORT_MESSAGING_H__
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "i_shell_cmd.h"
|
||||
#include "i_rest_api.h"
|
||||
#include "i_tenant_manager.h"
|
||||
#include "i_messaging.h"
|
||||
#include "service_details.h"
|
||||
#include "i_mainloop.h"
|
||||
#include "component.h"
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include "waap.h"
|
||||
#include "generic_metric.h"
|
||||
|
||||
#define LOGGING_INTERVAL_IN_MINUTES 10
|
||||
enum class AssetType { API, WEB, ALL, COUNT };
|
||||
|
||||
class WaapTelemetryEvent : public Event<WaapTelemetryEvent>
|
||||
@@ -74,6 +75,24 @@ private:
|
||||
std::unordered_set<std::string> sources_seen;
|
||||
};
|
||||
|
||||
class WaapTrafficTelemetrics : public WaapTelemetryBase
|
||||
{
|
||||
public:
|
||||
void updateMetrics(const std::string &asset_id, const DecisionTelemetryData &data);
|
||||
void initMetrics();
|
||||
|
||||
private:
|
||||
MetricCalculations::Counter post_requests{this, "reservedNgenA"};
|
||||
MetricCalculations::Counter get_requests{this, "reservedNgenB"};
|
||||
MetricCalculations::Counter put_requests{this, "reservedNgenC"};
|
||||
MetricCalculations::Counter patch_requests{this, "reservedNgenD"};
|
||||
MetricCalculations::Counter delete_requests{this, "reservedNgenE"};
|
||||
MetricCalculations::Counter other_requests{this, "reservedNgenF"};
|
||||
MetricCalculations::Counter response_2xx{this, "reservedNgenG"};
|
||||
MetricCalculations::Counter response_4xx{this, "reservedNgenH"};
|
||||
MetricCalculations::Counter response_5xx{this, "reservedNgenI"};
|
||||
};
|
||||
|
||||
class WaapAttackTypesMetrics : public WaapTelemetryBase
|
||||
{
|
||||
public:
|
||||
@@ -100,8 +119,62 @@ public:
|
||||
private:
|
||||
std::map<std::string, std::shared_ptr<WaapTelemetrics>> metrics;
|
||||
std::map<std::string, std::shared_ptr<WaapTelemetrics>> telemetries;
|
||||
std::map<std::string, std::shared_ptr<WaapTrafficTelemetrics>> traffic_telemetries;
|
||||
std::map<std::string, std::shared_ptr<WaapAttackTypesMetrics>> attack_types;
|
||||
std::map<std::string, std::shared_ptr<WaapAttackTypesMetrics>> attack_types_telemetries;
|
||||
|
||||
template <typename T>
|
||||
void initializeTelemetryData(
|
||||
const std::string& asset_id,
|
||||
const DecisionTelemetryData& data,
|
||||
const std::string& telemetryName,
|
||||
std::map<std::string, std::shared_ptr<T>>& telemetryMap
|
||||
) {
|
||||
if (!telemetryMap.count(asset_id)) {
|
||||
telemetryMap.emplace(asset_id, std::make_shared<T>());
|
||||
telemetryMap[asset_id]->init(
|
||||
telemetryName,
|
||||
ReportIS::AudienceTeam::WAAP,
|
||||
ReportIS::IssuingEngine::AGENT_CORE,
|
||||
std::chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
|
||||
true,
|
||||
ReportIS::Audience::SECURITY
|
||||
);
|
||||
|
||||
telemetryMap[asset_id]->template registerContext<std::string>(
|
||||
"pracitceType",
|
||||
std::string("Threat Prevention"),
|
||||
EnvKeyAttr::LogSection::SOURCE
|
||||
);
|
||||
telemetryMap[asset_id]->template registerContext<std::string>(
|
||||
"practiceSubType",
|
||||
std::string("Web Application"),
|
||||
EnvKeyAttr::LogSection::SOURCE
|
||||
);
|
||||
telemetryMap[asset_id]->template registerContext<std::string>(
|
||||
"assetId",
|
||||
asset_id,
|
||||
EnvKeyAttr::LogSection::SOURCE
|
||||
);
|
||||
telemetryMap[asset_id]->template registerContext<std::string>(
|
||||
"assetName",
|
||||
data.assetName,
|
||||
EnvKeyAttr::LogSection::SOURCE
|
||||
);
|
||||
telemetryMap[asset_id]->template registerContext<std::string>(
|
||||
"practiceId",
|
||||
data.practiceId,
|
||||
EnvKeyAttr::LogSection::SOURCE
|
||||
);
|
||||
telemetryMap[asset_id]->template registerContext<std::string>(
|
||||
"practiceName",
|
||||
data.practiceName,
|
||||
EnvKeyAttr::LogSection::SOURCE
|
||||
);
|
||||
|
||||
telemetryMap[asset_id]->registerListener();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class AssetCountEvent : public Event<AssetCountEvent>
|
||||
|
Reference in New Issue
Block a user