Skip to content

Commit 4ec4563

Browse files
committed
refactor: api data download process
1 parent 941cb71 commit 4ec4563

22 files changed

Lines changed: 483 additions & 226 deletions

src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ SET(PROJECT_NAME flow_plugin_sdk_src)
44

55
set(CMAKE_CXX_STANDARD 20)
66

7-
set(src_api api/ApiDataDownloader.cpp api/ApiDataDownloader.h api/ApiDataScheduler.cpp api/ApiDataScheduler.h api/FlightInformationRegionDataParser.cpp api/FlightInformationRegionDataParser.h api/ApiDataListenerTypes.h api/InternalApiElementCollection.h api/InternalStringIdentifiedApiElementCollection.h api/ConcreteApiElementCollection.cpp api/ConcreteApiElementCollection.h api/ApiElementIterator.cpp api/ConcreteStringIdentifiedApiElementCollection.cpp api/ConcreteStringIdentifiedApiElementCollection.h api/InternalElementCollectionTypes.h api/EventDataParser.cpp api/EventDataParser.h api/FlowMeasureDataParser.cpp api/FlowMeasureDataParser.h api/FlowMeasureMeasureParserInterface.h api/FlowMeasureFilterParser.cpp api/FlowMeasureFilterParser.h)
7+
set(src_api api/ApiDataDownloader.cpp api/ApiDataDownloader.h api/ApiDataScheduler.cpp api/ApiDataScheduler.h api/FlightInformationRegionDataParser.cpp api/FlightInformationRegionDataParser.h api/ApiDataListenerTypes.h api/InternalApiElementCollection.h api/InternalStringIdentifiedApiElementCollection.h api/ConcreteApiElementCollection.cpp api/ConcreteApiElementCollection.h api/ApiElementIterator.cpp api/ConcreteStringIdentifiedApiElementCollection.cpp api/ConcreteStringIdentifiedApiElementCollection.h api/InternalElementCollectionTypes.h api/EventDataParser.cpp api/EventDataParser.h api/FlowMeasureDataParser.cpp api/FlowMeasureDataParser.h api/FlowMeasureMeasureParserInterface.h api/FlowMeasureFilterParser.cpp api/FlowMeasureFilterParser.h api/ApiDataParser.cpp api/ApiDataParser.h api/ApiDataDownloadedEvent.h api/FlightInformationRegionDataParserInterface.h api/EventDataParserInterface.h api/FlowMeasureDataParserInterface.h)
88

99
set(src_date date/ParseDateStrings.cpp date/ParseDateStrings.h)
1010

src/api/ApiDataDownloadedEvent.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#pragma once
2+
#include "nlohmann/json.hpp"
3+
4+
namespace ECFMP::Api {
5+
using ApiDataDownloadedEvent = struct ApiDataDownloadedEvent {
6+
nlohmann::json data;
7+
};
8+
}// namespace ECFMP::Api

src/api/ApiDataDownloader.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
#include "ApiDataDownloader.h"
2+
#include "ApiDataDownloadedEvent.h"
23
#include "ECFMP/http/HttpClient.h"
34
#include "ECFMP/log/Logger.h"
5+
#include "eventbus/InternalEventBus.h"
46
#include "nlohmann/json.hpp"
5-
#include "plugin/InternalEventListeners.h"
67

78
namespace ECFMP::Api {
89

910
const std::string PLUGIN_API_DATA_URL = "https://ecfmp.vatsim.net/api/v1/plugin?deleted=1";
1011

1112
ApiDataDownloader::ApiDataDownloader(
12-
std::unique_ptr<Http::HttpClient> httpClient,
13-
std::unique_ptr<Plugin::InternalEventListeners<const nlohmann::json&>> listeners,
13+
std::unique_ptr<Http::HttpClient> httpClient, std::shared_ptr<EventBus::InternalEventBus> eventBus,
1414
std::shared_ptr<Log::Logger> logger
1515
)
16-
: httpClient(std::move(httpClient)), listeners(std::move(listeners)), logger(std::move(logger))
16+
: httpClient(std::move(httpClient)), eventBus(std::move(eventBus)), logger(std::move(logger))
1717
{
1818
assert(this->httpClient && "Http client not set in ApiDataDownloader");
19-
assert(this->listeners && "Listeners not set in ApiDataDownloader");
19+
assert(this->eventBus && "Event bus not set in ApiDataDownloader");
2020
assert(this->logger && "Logger not set in ApiDataDownloader");
2121
}
2222
ApiDataDownloader::~ApiDataDownloader() = default;
@@ -49,6 +49,6 @@ namespace ECFMP::Api {
4949
}
5050

5151
// Disseminate the JSON to any listeners
52-
listeners->OnEvent(parsedData);
52+
eventBus->OnEvent<ApiDataDownloadedEvent>({parsedData});
5353
}
5454
}// namespace ECFMP::Api

src/api/ApiDataDownloader.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
#pragma once
2+
#include "eventbus/InternalEventBus.h"
23
#include "nlohmann/json_fwd.hpp"
34

45
namespace ECFMP {
6+
namespace EventBus {
7+
class InternalEventBus;
8+
}// namespace EventBus
59
namespace Http {
610
class HttpClient;
711
}// namespace Http
812
namespace Log {
913
class Logger;
1014
}// namespace Log
11-
namespace Plugin {
12-
template<class... Types>
13-
class InternalEventListeners;
14-
}// namespace Plugin
1515
}// namespace ECFMP
1616

1717
namespace ECFMP::Api {
@@ -23,8 +23,7 @@ namespace ECFMP::Api {
2323
{
2424
public:
2525
explicit ApiDataDownloader(
26-
std::unique_ptr<Http::HttpClient> httpClient,
27-
std::unique_ptr<Plugin::InternalEventListeners<const nlohmann::json&>> listeners,
26+
std::unique_ptr<Http::HttpClient> httpClient, std::shared_ptr<EventBus::InternalEventBus> eventBus,
2827
std::shared_ptr<Log::Logger> logger
2928
);
3029

@@ -35,8 +34,8 @@ namespace ECFMP::Api {
3534
// HTTP client for getting data
3635
std::unique_ptr<Http::HttpClient> httpClient;
3736

38-
// All the listeners
39-
std::unique_ptr<Plugin::InternalEventListeners<const nlohmann::json&>> listeners;
37+
// Eventbus
38+
std::shared_ptr<EventBus::InternalEventBus> eventBus;
4039

4140
// Logger
4241
std::shared_ptr<Log::Logger> logger;

src/api/ApiDataParser.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#include "ApiDataParser.h"
2+
#include "ECFMP/log/Logger.h"
3+
#include "EventDataParserInterface.h"
4+
#include "FlightInformationRegionDataParserInterface.h"
5+
#include "FlowMeasureDataParserInterface.h"
6+
7+
namespace ECFMP::Api {
8+
9+
ApiDataParser::ApiDataParser(
10+
std::shared_ptr<EventDataParserInterface> eventParser,
11+
std::shared_ptr<FlightInformationRegionDataParserInterface> firParser,
12+
std::shared_ptr<FlowMeasureDataParserInterface> flowMeasureParser, std::shared_ptr<Log::Logger> logger
13+
)
14+
: eventParser(std::move(eventParser)), firParser(std::move(firParser)),
15+
flowMeasureParser(std::move(flowMeasureParser)), logger(std::move(logger))
16+
{
17+
assert(this->eventParser != nullptr && "EventDataParser cannot be null");
18+
assert(this->firParser != nullptr && "FlightInformationRegionDataParser cannot be null");
19+
assert(this->flowMeasureParser != nullptr && "FlowMeasureDataParser cannot be null");
20+
assert(this->logger != nullptr && "Logger cannot be null");
21+
}
22+
23+
void ApiDataParser::OnEvent(const ApiDataDownloadedEvent& event)
24+
{
25+
auto firs = this->firParser->ParseFirs(event.data);
26+
27+
// No FIRs available, so we've got no chance of being able to parse any events.
28+
if (!firs) {
29+
this->logger->Warning("Could not parse FIRs. Events and flow measures will not be parsed.");
30+
return;
31+
}
32+
33+
// No events available, so we've got no chance of being able to parse any flow measures.
34+
auto events = this->eventParser->ParseEvents(event.data, *firs);
35+
if (!events) {
36+
this->logger->Warning("Could not parse events. Flow measures will not be parsed.");
37+
return;
38+
}
39+
40+
auto flowMeasures = this->flowMeasureParser->ParseFlowMeasures(event.data, *events, *firs);
41+
if (!flowMeasures) {
42+
this->logger->Warning("Could not parse flow measures.");
43+
return;
44+
}
45+
}
46+
}// namespace ECFMP::Api

src/api/ApiDataParser.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
#include "ApiDataDownloadedEvent.h"
3+
#include "ECFMP/eventbus/NewEventListener.h"
4+
5+
namespace ECFMP::Log {
6+
class Logger;
7+
}// namespace ECFMP::Log
8+
9+
namespace ECFMP::Api {
10+
11+
class EventDataParserInterface;
12+
class FlightInformationRegionDataParserInterface;
13+
class FlowMeasureDataParserInterface;
14+
15+
class ApiDataParser : public EventBus::NewEventListener<ApiDataDownloadedEvent>
16+
{
17+
public:
18+
ApiDataParser(
19+
std::shared_ptr<EventDataParserInterface> eventParser,
20+
std::shared_ptr<FlightInformationRegionDataParserInterface> firParser,
21+
std::shared_ptr<FlowMeasureDataParserInterface> flowMeasureParser, std::shared_ptr<Log::Logger> logger
22+
);
23+
~ApiDataParser() = default;
24+
void OnEvent(const ApiDataDownloadedEvent& event) override;
25+
26+
private:
27+
// The parsers
28+
std::shared_ptr<EventDataParserInterface> eventParser;
29+
std::shared_ptr<FlightInformationRegionDataParserInterface> firParser;
30+
std::shared_ptr<FlowMeasureDataParserInterface> flowMeasureParser;
31+
32+
// Logger
33+
std::shared_ptr<Log::Logger> logger;
34+
};
35+
36+
}// namespace ECFMP::Api

src/api/EventDataParser.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
11
#include "EventDataParser.h"
2+
#include "ConcreteApiElementCollection.h"
23
#include "ECFMP/log/Logger.h"
34
#include "date/ParseDateStrings.h"
45
#include "event/ConcreteEvent.h"
56
#include "nlohmann/json.hpp"
67

78
namespace ECFMP::Api {
89

9-
EventDataParser::EventDataParser(
10-
std::shared_ptr<InternalEventCollection> events,
11-
std::shared_ptr<const InternalFlightInformationRegionCollection> firs, std::shared_ptr<Log::Logger> logger
12-
)
13-
: events(std::move(events)), firs(std::move(firs)), logger(std::move(logger))
14-
{}
10+
EventDataParser::EventDataParser(std::shared_ptr<Log::Logger> logger) : logger(std::move(logger))
11+
{
12+
assert(this->logger != nullptr && "Logger cannot be null");
13+
}
1514

16-
void EventDataParser::OnEvent(const nlohmann::json& data)
15+
auto EventDataParser::ParseEvents(const nlohmann::json& data, const InternalFlightInformationRegionCollection& firs)
16+
-> std::shared_ptr<InternalEventCollection>
1717
{
18+
auto events = std::make_shared<Api::ConcreteApiElementCollection<Event::Event>>();
1819
logger->Debug("Updating event data");
1920
if (!DataIsValid(data)) {
2021
logger->Error("Invalid event data from API");
21-
return;
22+
return nullptr;
2223
}
2324

2425
for (const auto& event: data.at("events")) {
25-
if (!EventDataIsValid(event)) {
26+
if (!EventDataIsValid(event, firs)) {
2627
logger->Error("Invalid event in event data from API");
2728
logger->Debug("Failed updating event: " + event.dump());
2829
continue;
@@ -32,26 +33,29 @@ namespace ECFMP::Api {
3233
event.at("id").get<int>(), event.at("name").get<std::string>(),
3334
Date::TimePointFromDateString(event.at("date_start").get<std::string>()),
3435
Date::TimePointFromDateString(event.at("date_end").get<std::string>()),
35-
firs->Get(event.at("flight_information_region_id").get<int>()),
36+
firs.Get(event.at("flight_information_region_id").get<int>()),
3637
event.at("vatcan_code").is_null() ? "" : event.at("vatcan_code").get<std::string>()
3738
));
3839
}
3940

4041
logger->Debug("Finished updating events");
42+
return events;
4143
}
4244

4345
auto EventDataParser::DataIsValid(const nlohmann::json& data) -> bool
4446
{
4547
return data.is_object() && data.contains("events") && data.at("events").is_array();
4648
}
4749

48-
auto EventDataParser::EventDataIsValid(const nlohmann::json& data) -> bool
50+
auto
51+
EventDataParser::EventDataIsValid(const nlohmann::json& data, const InternalFlightInformationRegionCollection& firs)
52+
-> bool
4953
{
5054
return data.is_object() && data.contains("id") && data.at("id").is_number_integer() && data.contains("name")
5155
&& data.at("name").is_string() && DateValid(data, "date_start") && DateValid(data, "date_end")
5256
&& data.contains("flight_information_region_id")
5357
&& data.at("flight_information_region_id").is_number_integer()
54-
&& firs->Get(data.at("flight_information_region_id").get<int>()) != nullptr
58+
&& firs.Get(data.at("flight_information_region_id").get<int>()) != nullptr
5559
&& (data.contains("vatcan_code")
5660
&& (data.at("vatcan_code").is_null() || data.at("vatcan_code").is_string()))
5761
&& data.contains("participants") && ParticipantsValid(data.at("participants"));

src/api/EventDataParser.h

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,28 @@
11
#pragma once
2-
#include "ApiDataListenerTypes.h"
3-
#include "InternalElementCollectionTypes.h"
2+
#include "EventDataParserInterface.h"
43
#include "nlohmann/json_fwd.hpp"
54

65
namespace ECFMP::Log {
76
class Logger;
87
}// namespace ECFMP::Log
98

109
namespace ECFMP::Api {
11-
class EventDataParser : public ApiDataListener
10+
class EventDataParser : public EventDataParserInterface
1211
{
1312
public:
14-
EventDataParser(
15-
std::shared_ptr<InternalEventCollection> events,
16-
std::shared_ptr<const InternalFlightInformationRegionCollection> firs,
17-
std::shared_ptr<Log::Logger> logger
18-
);
19-
void OnEvent(const nlohmann::json& data) override;
13+
EventDataParser(std::shared_ptr<Log::Logger> logger);
14+
[[nodiscard]] auto
15+
ParseEvents(const nlohmann::json& data, const InternalFlightInformationRegionCollection& firs)
16+
-> std::shared_ptr<InternalEventCollection> override;
2017

2118
private:
2219
[[nodiscard]] static auto DataIsValid(const nlohmann::json& data) -> bool;
23-
[[nodiscard]] auto EventDataIsValid(const nlohmann::json& data) -> bool;
20+
[[nodiscard]] static auto
21+
EventDataIsValid(const nlohmann::json& data, const InternalFlightInformationRegionCollection& firs) -> bool;
2422
[[nodiscard]] static auto DateValid(const nlohmann::json& data, const std::string& key) -> bool;
2523
[[nodiscard]] static auto ParticipantsValid(const nlohmann::json& data) -> bool;
2624

2725
// A logger, for logging things
2826
std::shared_ptr<Log::Logger> logger;
29-
30-
// Stores the event objects
31-
std::shared_ptr<InternalEventCollection> events;
32-
33-
// Stores firs
34-
std::shared_ptr<const InternalFlightInformationRegionCollection> firs;
3527
};
3628
}// namespace ECFMP::Api

src/api/EventDataParserInterface.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
#include "InternalElementCollectionTypes.h"
3+
#include "nlohmann/json_fwd.hpp"
4+
5+
namespace ECFMP::Api {
6+
7+
class EventDataParserInterface
8+
{
9+
public:
10+
virtual ~EventDataParserInterface() = default;
11+
[[nodiscard]] virtual auto
12+
ParseEvents(const nlohmann::json& data, const InternalFlightInformationRegionCollection& firs)
13+
-> std::shared_ptr<InternalEventCollection> = 0;
14+
};
15+
}// namespace ECFMP::Api

src/api/FlightInformationRegionDataParser.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
#include "FlightInformationRegionDataParser.h"
2+
#include "ConcreteStringIdentifiedApiElementCollection.h"
23
#include "ECFMP/log/Logger.h"
4+
#include "InternalStringIdentifiedApiElementCollection.h"
35
#include "api/ConcreteApiElementCollection.h"
46
#include "flightinformationregion/ConcreteFlightInformationRegion.h"
57
#include "nlohmann/json.hpp"
68

79
namespace ECFMP::Api {
810

9-
FlightInformationRegionDataParser::FlightInformationRegionDataParser(
10-
std::shared_ptr<InternalFlightInformationRegionCollection> firs, std::shared_ptr<Log::Logger> logger
11-
)
12-
: firs(std::move(firs)), logger(std::move(logger))
11+
FlightInformationRegionDataParser::FlightInformationRegionDataParser(std::shared_ptr<Log::Logger> logger)
12+
: logger(std::move(logger))
1313
{
14-
assert(this->firs && "firs not set in FlightInformationRegionDataParser");
1514
assert(this->logger && "logger not set in FlightInformationRegionDataParser");
1615
}
1716

18-
void FlightInformationRegionDataParser::OnEvent(const nlohmann::json& data)
17+
auto FlightInformationRegionDataParser::ParseFirs(const nlohmann::json& data)
18+
-> std::shared_ptr<InternalFlightInformationRegionCollection>
1919
{
20+
auto firs = std::make_shared<
21+
Api::ConcreteStringIdentifiedApiElementCollection<FlightInformationRegion::FlightInformationRegion>>();
22+
2023
logger->Debug("Updating FIRs");
2124
if (!DataIsValid(data)) {
2225
logger->Error("Invalid FIR data from API");
23-
return;
26+
return nullptr;
2427
}
2528

2629
for (const auto& fir: data.at("flight_information_regions")) {
@@ -36,6 +39,7 @@ namespace ECFMP::Api {
3639
}
3740

3841
logger->Debug("Finished updating FIRs");
42+
return firs;
3943
}
4044

4145
auto FlightInformationRegionDataParser::DataIsValid(const nlohmann::json& data) -> bool

0 commit comments

Comments
 (0)