1cd22786aSRatan Gupta /**
2cd22786aSRatan Gupta  * Copyright © 2017 IBM Corporation
3cd22786aSRatan Gupta  *
4cd22786aSRatan Gupta  * Licensed under the Apache License, Version 2.0 (the "License");
5cd22786aSRatan Gupta  * you may not use this file except in compliance with the License.
6cd22786aSRatan Gupta  * You may obtain a copy of the License at
7cd22786aSRatan Gupta  *
8cd22786aSRatan Gupta  *     http://www.apache.org/licenses/LICENSE-2.0
9cd22786aSRatan Gupta  *
10cd22786aSRatan Gupta  * Unless required by applicable law or agreed to in writing, software
11cd22786aSRatan Gupta  * distributed under the License is distributed on an "AS IS" BASIS,
12cd22786aSRatan Gupta  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cd22786aSRatan Gupta  * See the License for the specific language governing permissions and
14cd22786aSRatan Gupta  * limitations under the License.
15cd22786aSRatan Gupta  */
163e84ec66SRatan Gupta 
173e84ec66SRatan Gupta #include "config.h"
183d6d3182SPatrick Venture 
19cd22786aSRatan Gupta #include "event_manager.hpp"
203d6d3182SPatrick Venture 
213d6d3182SPatrick Venture #include "event.hpp"
226524b9d8SDhruvaraj Subhashchandran #include "event_serialize.hpp"
233e84ec66SRatan Gupta 
2426dc0bcbSPatrick Williams #include <filesystem>
25cd22786aSRatan Gupta 
26cd22786aSRatan Gupta namespace phosphor
27cd22786aSRatan Gupta {
28cd22786aSRatan Gupta namespace events
29cd22786aSRatan Gupta {
30cd22786aSRatan Gupta 
create(const std::string & eventName,const std::string & eventMessage,const std::string & objectPath,const std::string & propertyName,const std::string & propertyValue)31d1eac88dSBrad Bishop void Manager::create(const std::string& eventName,
323e84ec66SRatan Gupta                      const std::string& eventMessage,
33cd22786aSRatan Gupta                      const std::string& objectPath,
34cd22786aSRatan Gupta                      const std::string& propertyName,
353e84ec66SRatan Gupta                      const std::string& propertyValue)
36cd22786aSRatan Gupta {
373e84ec66SRatan Gupta     using namespace std::string_literals;
3826dc0bcbSPatrick Williams     namespace fs = std::filesystem;
393e84ec66SRatan Gupta 
403e84ec66SRatan Gupta     auto msg = eventMessage;
413e84ec66SRatan Gupta     std::vector<std::string> additionalData;
423e84ec66SRatan Gupta 
433e84ec66SRatan Gupta     auto propVal = propertyName + "=" + propertyValue;
443e84ec66SRatan Gupta     auto path = "path="s + objectPath;
453e84ec66SRatan Gupta 
463e84ec66SRatan Gupta     additionalData.push_back(std::move(path));
473e84ec66SRatan Gupta     additionalData.push_back(std::move(propVal));
483e84ec66SRatan Gupta 
493e84ec66SRatan Gupta     auto& eventQueue = eventMap[eventName];
503e84ec66SRatan Gupta 
513e84ec66SRatan Gupta     // get the last event entry for this event
523e84ec66SRatan Gupta     // to generate the id.
533e84ec66SRatan Gupta     auto id = 0;
543e84ec66SRatan Gupta     if (eventQueue.size() > 0)
553e84ec66SRatan Gupta     {
56ecef1191SGeorge Liu         fs::path eventPath(eventQueue.back()->objectPath);
57ecef1191SGeorge Liu         id = std::stoi(std::string(eventPath.filename().c_str()));
583e84ec66SRatan Gupta         id++;
593e84ec66SRatan Gupta     }
603e84ec66SRatan Gupta 
613e84ec66SRatan Gupta     auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
62d1eac88dSBrad Bishop                   std::chrono::system_clock::now().time_since_epoch())
63d1eac88dSBrad Bishop                   .count();
643e84ec66SRatan Gupta 
65*c5fe26a6SPatrick Williams     auto objPath = std::string(OBJ_EVENT) + '/' + eventName + '/' +
66*c5fe26a6SPatrick Williams                    std::to_string(id);
673e84ec66SRatan Gupta 
688bbf9d2cSRatan Gupta     // check for capping of the events,if cap reached then erase the oldest
698bbf9d2cSRatan Gupta     // event.
708bbf9d2cSRatan Gupta     if (eventQueue.size() == MAX_EVENTS)
718bbf9d2cSRatan Gupta     {
726524b9d8SDhruvaraj Subhashchandran         fs::path eventPath(EVENTS_PERSIST_PATH);
736524b9d8SDhruvaraj Subhashchandran         eventPath /= eventName;
746524b9d8SDhruvaraj Subhashchandran         eventPath /= std::to_string(eventQueue.front()->timestamp());
758bbf9d2cSRatan Gupta         eventQueue.pop();
766524b9d8SDhruvaraj Subhashchandran         std::error_code ec;
776524b9d8SDhruvaraj Subhashchandran         fs::remove(eventPath, ec);
788bbf9d2cSRatan Gupta     }
798bbf9d2cSRatan Gupta 
80*c5fe26a6SPatrick Williams     auto event = std::make_unique<Entry>(objPath,
813e84ec66SRatan Gupta                                          ms, // Milliseconds since 1970
82*c5fe26a6SPatrick Williams                                          std::move(msg),
83*c5fe26a6SPatrick Williams                                          std::move(additionalData));
846524b9d8SDhruvaraj Subhashchandran     serialize(*event, eventName);
856524b9d8SDhruvaraj Subhashchandran     eventQueue.push(std::move(event));
866524b9d8SDhruvaraj Subhashchandran }
876524b9d8SDhruvaraj Subhashchandran 
restore()886524b9d8SDhruvaraj Subhashchandran void Manager::restore()
896524b9d8SDhruvaraj Subhashchandran {
906524b9d8SDhruvaraj Subhashchandran     if (!fs::exists(EVENTS_PERSIST_PATH) || fs::is_empty(EVENTS_PERSIST_PATH))
916524b9d8SDhruvaraj Subhashchandran     {
926524b9d8SDhruvaraj Subhashchandran         return;
936524b9d8SDhruvaraj Subhashchandran     }
946524b9d8SDhruvaraj Subhashchandran 
956524b9d8SDhruvaraj Subhashchandran     for (auto& eventFile :
966524b9d8SDhruvaraj Subhashchandran          fs::recursive_directory_iterator(EVENTS_PERSIST_PATH))
976524b9d8SDhruvaraj Subhashchandran     {
986524b9d8SDhruvaraj Subhashchandran         if (!fs::is_regular_file(eventFile))
996524b9d8SDhruvaraj Subhashchandran         {
1006524b9d8SDhruvaraj Subhashchandran             continue;
1016524b9d8SDhruvaraj Subhashchandran         }
1026524b9d8SDhruvaraj Subhashchandran 
1036524b9d8SDhruvaraj Subhashchandran         EventQueue events;
1046524b9d8SDhruvaraj Subhashchandran 
1056524b9d8SDhruvaraj Subhashchandran         auto eventPath = eventFile.path().string();
1066524b9d8SDhruvaraj Subhashchandran         auto pos1 = eventPath.rfind("/");
1076524b9d8SDhruvaraj Subhashchandran         auto pos2 = eventPath.rfind("/", pos1 - 1) + 1;
1086524b9d8SDhruvaraj Subhashchandran         auto eventName = eventPath.substr(pos2, (pos1 - pos2));
1096524b9d8SDhruvaraj Subhashchandran         auto validEvent = false;
1106524b9d8SDhruvaraj Subhashchandran         auto timestamp = eventFile.path().filename().string();
1116524b9d8SDhruvaraj Subhashchandran         auto tsNum = std::stoll(timestamp);
112*c5fe26a6SPatrick Williams         auto objPath = std::string(OBJ_EVENT) + '/' + eventName + '/' +
113*c5fe26a6SPatrick Williams                        timestamp;
1146524b9d8SDhruvaraj Subhashchandran 
1156524b9d8SDhruvaraj Subhashchandran         auto event = std::make_unique<Entry>(objPath, tsNum);
1166524b9d8SDhruvaraj Subhashchandran         if (deserialize(eventFile.path(), *event))
1176524b9d8SDhruvaraj Subhashchandran         {
1186524b9d8SDhruvaraj Subhashchandran             event->emit_object_added();
1196524b9d8SDhruvaraj Subhashchandran             events.push(std::move(event));
1206524b9d8SDhruvaraj Subhashchandran             validEvent = true;
1216524b9d8SDhruvaraj Subhashchandran         }
1226524b9d8SDhruvaraj Subhashchandran 
1236524b9d8SDhruvaraj Subhashchandran         if (validEvent)
1246524b9d8SDhruvaraj Subhashchandran         {
1256524b9d8SDhruvaraj Subhashchandran             eventMap[eventName] = std::move(events);
1266524b9d8SDhruvaraj Subhashchandran         }
1276524b9d8SDhruvaraj Subhashchandran     }
128cd22786aSRatan Gupta }
129cd22786aSRatan Gupta 
getManager()130cd22786aSRatan Gupta Manager& getManager()
131cd22786aSRatan Gupta {
132cd22786aSRatan Gupta     static Manager mgr;
133cd22786aSRatan Gupta     return mgr;
134cd22786aSRatan Gupta }
135cd22786aSRatan Gupta 
136cd22786aSRatan Gupta } // namespace events
137cd22786aSRatan Gupta } // namespace phosphor
138