| /* |
| * Copyright 2023 Google LLC |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with 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. |
| */ |
| |
| #include "subscription.h" |
| |
| #include <functional> |
| #include <string> |
| #include <utility> |
| |
| #include "absl/container/flat_hash_map.h" |
| #include "absl/container/flat_hash_set.h" |
| #include "absl/hash/hash.h" |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/string_view.h" |
| #include "absl/time/time.h" |
| #include "nlohmann/json.hpp" |
| |
| namespace ecclesia { |
| |
| // EventSourceId definitions |
| |
| nlohmann::json EventSourceId::ToJSON() const { |
| nlohmann::json json; |
| json["key"] = key; |
| switch (type) { |
| case Type::kDbusObjects: |
| json["type"] = "kDbusObjects"; |
| break; |
| case Type::kSocketIO: |
| json["type"] = "kSocketIO"; |
| break; |
| case Type::kFileIO: |
| json["type"] = "kFileIO"; |
| break; |
| } |
| return json; |
| } |
| |
| std::string EventSourceId::ToString() const { return this->ToJSON().dump(); } |
| |
| // EventId definitions. |
| |
| EventId::EventId(const SubscriptionId& subscription_id_in, |
| const EventSourceId& source_id_in, absl::Time timestamp_in) |
| : source_id(source_id_in), |
| timestamp(timestamp_in), |
| subscription_id(subscription_id_in), |
| redfish_event_id( |
| absl::HashOf(timestamp_in, source_id_in, subscription_id_in)) {} |
| |
| nlohmann::json EventId::ToJSON() const { |
| nlohmann::json json; |
| json["source_id"] = source_id.ToJSON(); |
| json["timestamp"] = |
| absl::FormatTime(absl::RFC3339_full, timestamp, absl::UTCTimeZone()); |
| json["uuid"] = redfish_event_id; |
| return json; |
| } |
| |
| std::string EventId::ToString() const { return this->ToJSON().dump(); } |
| |
| // SubscriptionContext definitions. |
| |
| SubscriptionContext::SubscriptionContext( |
| const SubscriptionId& subscription_id_in, |
| const absl::flat_hash_map<EventSourceId, absl::flat_hash_set<std::string>>& |
| event_source_to_uris_in, |
| absl::flat_hash_map<std::string, Trigger> id_to_triggers_in, |
| std::function<void(const nlohmann::json&)>&& on_event_callback_in) |
| : subscription_id(subscription_id_in), |
| event_source_to_uri(event_source_to_uris_in), |
| id_to_triggers(std::move(id_to_triggers_in)), |
| on_event_callback(std::move(on_event_callback_in)) {} |
| |
| // Trigger definitions. |
| |
| absl::StatusOr<Trigger> Trigger::Create(const nlohmann::json& trigger_json) { |
| // Check if json is valid. |
| if (trigger_json.is_discarded()) { |
| return absl::InvalidArgumentError("Trigger json is discarded"); |
| } |
| |
| // Parse the JSON data |
| auto find_id = trigger_json.find("Id"); |
| if (find_id == trigger_json.end()) { |
| return absl::InvalidArgumentError("Trigger Id not populated"); |
| } |
| // Extract trigger information from the JSON data |
| const std::string id = find_id->get<std::string>(); |
| |
| auto find_origin_resources = trigger_json.find("OriginResources"); |
| if (find_origin_resources == trigger_json.end()) { |
| return absl::InvalidArgumentError("Origin resources not populated"); |
| } |
| |
| absl::flat_hash_set<std::string> origin_resources; |
| for (const auto& origin_resource : *find_origin_resources) { |
| origin_resources.insert(origin_resource["@odata.id"].get<std::string>()); |
| } |
| |
| std::string predicate; |
| bool event_mask = false; |
| |
| auto find_predicate = trigger_json.find("Predicate"); |
| if (find_predicate != trigger_json.end()) { |
| predicate = *find_predicate; |
| } else { |
| // If predicate is not provided, this trigger will be used to poll data. |
| // TODO(rahulkpr): Handle the polling case after adding trigger associations |
| event_mask = true; |
| } |
| |
| // Create a Trigger object with the extracted information |
| Trigger trigger(id, std::move(origin_resources), predicate, event_mask); |
| |
| return trigger; |
| } |
| |
| Trigger::Trigger(absl::string_view id_in, |
| absl::flat_hash_set<std::string> origin_resources_in, |
| absl::string_view predicate_in, bool mask_in) |
| : id(id_in), |
| origin_resources(std::move(origin_resources_in)), |
| predicate(predicate_in), |
| mask(mask_in) {} |
| |
| nlohmann::json Trigger::ToJSON() const { |
| nlohmann::json json; |
| |
| // Create json array and store all origin_resources |
| nlohmann::json& origin_resources_json = json["origin_resources"]; |
| origin_resources_json = nlohmann::json::array(); |
| origin_resources_json.insert_iterator(origin_resources_json.end(), |
| origin_resources.begin(), |
| origin_resources.end()); |
| json["predicate"] = predicate; |
| json["mask"] = mask; |
| return json; |
| } |
| |
| std::string Trigger::ToString() const { return this->ToJSON().dump(); } |
| |
| } // namespace ecclesia |