Skip to content

Commit

Permalink
feat(api): Improvements to how API requests are made (#432)
Browse files Browse the repository at this point in the history
* Display hold entry time based on proximity

* Navaids by id and time strings

* Event handler for aircraft entering holds

* Event handler for aircraft exiting holds

* Include continuables

* Lots of classes

* Try more things

* Bootstrap it in the plugin

* It works... wow

* A load of changes I dont wanna lose

* More tweaking

* More tweak

* Getting closer

* Way more tweaking

* It works

* Updater and loader compile

* Load hold data

* Locking

* Updated todos

* Tracking status of api requests

* Utils tests at least building

* fix(initialaltitude): Dont allow initial altitude recycle on aircraft out of range (#430)

* fix(initialaltitude): Dont allow initial altitude recycle on aircraft out of range

* More changes

* fix(initialheading): Dont allow initial heading recycle on aircraft out of range (#431)

* fix(initialheading): Dont allow initial heading recycle on aircraft out of range

Fix #429

* Format

* chore(release): 4.2.1 [skip ci]

## [4.2.1](4.2.0...4.2.1) (2022-02-12)

### Bug Fixes

* **initialaltitude:** Dont allow initial altitude recycle on aircraft out of range ([#430](#430)) ([cd3fd0e](cd3fd0e))
* **initialheading:** Dont allow initial heading recycle on aircraft out of range ([#431](#431)) ([e4fd211](e4fd211)), closes [#429](#429)

* Finish SettingRepositoryTest

* Test for api bootstrap

* Curl request factory test

* Api factory test

* Header applicator test

* Api request test, the big one

* ApiRequestData test

* Exception test

* Request factory test

* ApiSettings Test

* Settings factory test

* Url builder test

* Settings provider test

* Curl performer test

* Curl performer factory test

* Response test

* Curl request test

* Http method test

* Status code test

* Json setting file test

* String trimming functions

* Configuration menu item test and base test case

* Api bootstrap tests

* Api testing framework

* Style things

* Timeout on api request waiting

Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
  • Loading branch information
AndyTWF and semantic-release-bot committed Mar 2, 2022
1 parent 676bea3 commit 0b4527f
Show file tree
Hide file tree
Showing 149 changed files with 4,287 additions and 1,268 deletions.
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
[submodule "third_party/googletest"]
path = third_party/googletest
url = git@github.com:google/googletest.git
[submodule "third_party/continuable"]
path = third_party/continuable
url = git@github.com:Naios/continuable.git
[submodule "third_party/function2"]
path = third_party/function2
url = https://github.com/Naios/function2.git
26 changes: 6 additions & 20 deletions docs/UserGuide/Changelog/Changelog.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,15 @@
# UK Controller Plugin Changelog

# [5.0.0-alpha.1](https://github.com/VATSIM-UK/uk-controller-plugin/compare/4.2.0...5.0.0-alpha.1) (2022-02-12)


### Bug Fixes

* **updater:** Handle empty binaries during updates ([#388](https://github.com/VATSIM-UK/uk-controller-plugin/issues/388)) ([dc988b0](https://github.com/VATSIM-UK/uk-controller-plugin/commit/dc988b07292838cd16f127f07da5d020c514aaee))
## [4.2.1](https://github.com/VATSIM-UK/uk-controller-plugin/compare/4.2.0...4.2.1) (2022-02-12)
* **initialaltitude:** Dont allow initial altitude recycle on aircraft out of range ([#430](https://github.com/VATSIM-UK/uk-controller-plugin/issues/430)) ([cd3fd0e](https://github.com/VATSIM-UK/uk-controller-plugin/commit/cd3fd0e553626d256863377d1cbe30c6b521261a))
* **initialheading:** Dont allow initial heading recycle on aircraft out of range ([#431](https://github.com/VATSIM-UK/uk-controller-plugin/issues/431)) ([e4fd211](https://github.com/VATSIM-UK/uk-controller-plugin/commit/e4fd211bfde01b0829deaf58a962f1c043654faf)), closes [#429](https://github.com/VATSIM-UK/uk-controller-plugin/issues/429)

# [5.0.0-alpha.1](https://github.com/VATSIM-UK/uk-controller-plugin/compare/4.2.0...5.0.0-alpha.1) (2022-02-12)

### Features

* **departure:** Combine pending prenotes and departure releases lists into one ([91c0614](https://github.com/VATSIM-UK/uk-controller-plugin/commit/91c0614982e061a29e18db23e2d9c70c86449fcb))
* **departure:** Combine pending prenotes and releases into one list ([#386](https://github.com/VATSIM-UK/uk-controller-plugin/issues/386)) ([531b687](https://github.com/VATSIM-UK/uk-controller-plugin/commit/531b6876f94a2e6284279efd4ce10c88f2bd92e3))
* **hold:** Display hold entry time based on proximity ([#418](https://github.com/VATSIM-UK/uk-controller-plugin/issues/418)) ([3c2e5d1](https://github.com/VATSIM-UK/uk-controller-plugin/commit/3c2e5d1e0c45f90e9f90f4e0f2ac4fcaf4cca79f))
* **missedapproach:** Allow airfields to always alert regardless of service provision ([#384](https://github.com/VATSIM-UK/uk-controller-plugin/issues/384)) ([5fe9fd7](https://github.com/VATSIM-UK/uk-controller-plugin/commit/5fe9fd797bfef1bea9fc47e1385ef999e8c6592b))
* **misssedapproach:** Allow airfields to always alert regardless of service provision ([4398182](https://github.com/VATSIM-UK/uk-controller-plugin/commit/4398182e685fc9f1c7ef9236aaeb6dc494aa28aa))


### BREAKING CHANGES

* **departure:** The old lists are replaced by a single list. New ASR settings
are also used for this list.
* **misssedapproach:** The airfield selector for Missed Approach configuration now acts as an override
to the service provision options, rather than a filter for which airfields to use.

* **holds**: Hold timer by entry time rather than assigned time
*
# [4.2.0](https://github.com/VATSIM-UK/uk-controller-plugin/compare/4.1.1...4.2.0) (2022-02-10)


Expand Down
7 changes: 4 additions & 3 deletions src/loader/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "windows/WinApiInterface.h"
#include "windows/WinApiBootstrap.h"
#include "api/ApiBootstrap.h"
#include "api/ApiFactory.h"
#include "setting/SettingRepositoryFactory.h"
#include "curl/CurlApi.h"
#include "data/PluginDataLocations.h"
Expand Down Expand Up @@ -37,9 +38,9 @@ UKCP_LOADER_API void EuroScopePlugInInit(EuroScopePlugIn::CPlugIn** ppPlugInInst
// Bootstrap the API, download the updater if we don't have it already and run it
UKControllerPlugin::Curl::CurlApi curl;
std::unique_ptr<UKControllerPlugin::Setting::SettingRepository> settings =
UKControllerPlugin::Setting::SettingRepositoryFactory::Create(*windows);
std::unique_ptr<UKControllerPlugin::Api::ApiInterface> api =
UKControllerPlugin::Api::Bootstrap(*settings, curl);
UKControllerPlugin::Setting::SettingRepositoryFactory::Create();
auto factory = UKControllerPluginUtils::Api::Bootstrap(*settings, *windows);
auto api = UKControllerPluginUtils::Api::BootstrapLegacy(*factory, curl);

LogInfo("Loader build version " + std::string(UKControllerPlugin::Plugin::PluginVersion::version));

Expand Down
4 changes: 3 additions & 1 deletion src/plugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ source_group("src\\airfield" FILES ${src__airfield})
set(src__api
"api/ApiConfigurationMenuItem.cpp"
"api/ApiConfigurationMenuItem.h"
)
api/FirstTimeApiConfigLoader.cpp api/FirstTimeApiConfigLoader.h
api/BootstrapApi.cpp api/BootstrapApi.h
api/FirstTimeApiAuthorisationChecker.cpp api/FirstTimeApiAuthorisationChecker.h)
source_group("src\\api" FILES ${src__api})

set(src__bootstrap
Expand Down
44 changes: 40 additions & 4 deletions src/plugin/api/ApiConfigurationMenuItem.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,54 @@
#include "ApiConfigurationMenuItem.h"
#include "api/LocateApiSettings.h"
#include "api/ApiRequestException.h"
#include "api/ApiRequestFactory.h"
#include "api/Response.h"
#include "api/ApiSettingsProviderInterface.h"

using UKControllerPlugin::Plugin::PopupMenuItem;
using UKControllerPlugin::Windows::WinApiInterface;
using UKControllerPluginUtils::Api::ApiRequestException;
using UKControllerPluginUtils::Api::ApiSettingsProviderInterface;
using UKControllerPluginUtils::Api::Response;

namespace UKControllerPlugin::Api {
ApiConfigurationMenuItem::ApiConfigurationMenuItem(WinApiInterface& winApi, int menuCallbackId)
: menuCallbackId(menuCallbackId), winApi(winApi)
ApiConfigurationMenuItem::ApiConfigurationMenuItem(
UKControllerPluginUtils::Api::ApiSettingsProviderInterface& provider,
Windows::WinApiInterface& windows,
int menuCallbackId)
: provider(provider), windows(windows), menuCallbackId(menuCallbackId)
{
}

void ApiConfigurationMenuItem::Configure(int functionId, std::string subject, RECT area)
{
UserRequestedKeyUpdate(this->winApi);
if (!provider.Reload()) {
return;
};

ApiRequest()
.Get("authorise")
.Then([this]() {
LogInfo("Api configuration updated successfully");
windows.OpenMessageBox(
L"API configuration has been replaced sucessfully",
L"Configuration Updated",
MB_OK | MB_ICONINFORMATION);
})
.Catch([this](const ApiRequestException& exception) {
if (UKControllerPluginUtils::Http::IsAuthenticationError(exception.StatusCode())) {
windows.OpenMessageBox(
L"API authentication failed. Please re-download your credentails from the VATSIM UK website "
"and try again. If this problem persists, please contact the Web Services Department. Some "
"functionality such as stand and squawk allocations may not work as expected.",
L"UKCP API Config Invalid",
MB_OK | MB_ICONWARNING);
} else if (UKControllerPluginUtils::Http::IsServerError(exception.StatusCode()))
windows.OpenMessageBox(
L"Unable to perform API config check as the API responded with an error. Please try again "
L"later. Some functionality such as stand and squawk allocations may not work as expected.",
L"Server Error",
MB_OK | MB_ICONERROR);
});
}

/*
Expand Down
22 changes: 18 additions & 4 deletions src/plugin/api/ApiConfigurationMenuItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
#include "radarscreen/ConfigurableDisplayInterface.h"
#include "windows/WinApiInterface.h"

namespace UKControllerPluginUtils::Api {
class ApiSettingsProviderInterface;
} // namespace UKControllerPluginUtils::Api

namespace UKControllerPlugin::Windows {
class WinApiInterface;
} // namespace UKControllerPlugin::Windows

namespace UKControllerPlugin::Api {

/*
Expand All @@ -12,7 +20,10 @@ namespace UKControllerPlugin::Api {
class ApiConfigurationMenuItem : public UKControllerPlugin::RadarScreen::ConfigurableDisplayInterface
{
public:
ApiConfigurationMenuItem(UKControllerPlugin::Windows::WinApiInterface& winApi, int menuCallbackId);
ApiConfigurationMenuItem(
UKControllerPluginUtils::Api::ApiSettingsProviderInterface& provider,
Windows::WinApiInterface& windows,
int menuCallbackId);

// Inherited via ConfigurableDisplayInterface
void Configure(int functionId, std::string subject, RECT area) override;
Expand All @@ -22,10 +33,13 @@ namespace UKControllerPlugin::Api {
// The item description
const std::string itemDescription = "Replace Personal API Configuration";

// Api credential provider
UKControllerPluginUtils::Api::ApiSettingsProviderInterface& provider;

// Windows API for the dialogs
Windows::WinApiInterface& windows;

// The id of the callback function for when the menu item is clicked
const int menuCallbackId;

// The windows API
UKControllerPlugin::Windows::WinApiInterface& winApi;
};
} // namespace UKControllerPlugin::Api
38 changes: 38 additions & 0 deletions src/plugin/api/BootstrapApi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "ApiConfigurationMenuItem.h"
#include "BootstrapApi.h"
#include "api/ApiBootstrap.h"
#include "api/ApiFactory.h"
#include "bootstrap/PersistenceContainer.h"
#include "euroscope/CallbackFunction.h"
#include "plugin/FunctionCallEventHandler.h"
#include "radarscreen/ConfigurableDisplayCollection.h"

using UKControllerPlugin::Bootstrap::PersistenceContainer;
using UKControllerPlugin::Euroscope::CallbackFunction;

namespace UKControllerPlugin::Api {
void BootstrapApi(PersistenceContainer& container)
{
container.apiFactory =
UKControllerPluginUtils::Api::Bootstrap(*container.settingsRepository, *container.windows);
container.api = UKControllerPluginUtils::Api::BootstrapLegacy(*container.apiFactory, *container.curl);
}

void BootstrapConfigurationMenuItem(
const PersistenceContainer& container, RadarScreen::ConfigurableDisplayCollection& configurableDisplays)
{
unsigned int callbackId = container.pluginFunctionHandlers->ReserveNextDynamicFunctionId();
std::shared_ptr<ApiConfigurationMenuItem> menuItem = std::make_shared<ApiConfigurationMenuItem>(
*container.apiFactory->SettingsProvider(), *container.windows, callbackId);

CallbackFunction menuItemSelectedCallback(
callbackId, // NOLINT
"API Configuration Menu Item Selected",
[menuItem](int functionId, std::string subject, RECT screenObjectArea) {
menuItem->Configure(functionId, std::move(subject), screenObjectArea);
});

container.pluginFunctionHandlers->RegisterFunctionCall(menuItemSelectedCallback);
configurableDisplays.RegisterDisplay(menuItem);
}
} // namespace UKControllerPlugin::Api
17 changes: 17 additions & 0 deletions src/plugin/api/BootstrapApi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

namespace UKControllerPlugin {
namespace Bootstrap {
struct PersistenceContainer;
} // namespace Bootstrap
namespace RadarScreen {
class ConfigurableDisplayCollection;
} // namespace RadarScreen
} // namespace UKControllerPlugin

namespace UKControllerPlugin::Api {
void BootstrapApi(Bootstrap::PersistenceContainer& container);
void BootstrapConfigurationMenuItem(
const Bootstrap::PersistenceContainer& container,
RadarScreen::ConfigurableDisplayCollection& configurableDisplays);
} // namespace UKControllerPlugin::Api
53 changes: 53 additions & 0 deletions src/plugin/api/FirstTimeApiAuthorisationChecker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "FirstTimeApiAuthorisationChecker.h"
#include "api/ApiRequestFactory.h"
#include "api/ApiRequestException.h"
#include "api/ApiSettingsProviderInterface.h"
#include "windows/WinApiInterface.h"

using UKControllerPluginUtils::Api::ApiRequestException;

namespace UKControllerPlugin::Api {

void FirstTimeApiAuthorisationCheck(
UKControllerPluginUtils::Api::ApiSettingsProviderInterface& settingsProviderInterface,
Windows::WinApiInterface& windows)
{
ApiRequest()
.Get("authorise")
.Then([]() { LogInfo("Api authorisation check was successful."); })
.Catch([&windows, &settingsProviderInterface](const ApiRequestException& exception) {
LogWarning(
"Api authorisation check failed, status code was " +
std::to_string(static_cast<uint64_t>(exception.StatusCode())));

if (UKControllerPluginUtils::Http::IsServerError(exception.StatusCode())) {
windows.OpenMessageBox(
L"Server error whilst checking API authentication, some functionality may not work as "
"expected. If your configuration is otherwise correct, functionality will resume when the "
"service is online again.",
L"UKCP API Server Error",
MB_OK | MB_ICONWARNING);
return;
}

auto messageResponse = windows.OpenMessageBox(
L"API authentication failed. Please re-download your credentails from the VATSIM UK website "
"and click OK to try again. If this problem persists, please contact the Web Services Department.",
L"UKCP API Config Invalid",
MB_OKCANCEL | MB_ICONWARNING);

if (messageResponse == IDCANCEL || !settingsProviderInterface.Reload()) {
LogInfo("User elected not to set API key after authentication failure");
windows.OpenMessageBox(
L"You have elected not to complete API setup at this time. Some functionality of the plugin "
"may not work as expected.",
L"UKCP API Config Not Updated",
MB_OK | MB_ICONWARNING);
return;
}

FirstTimeApiAuthorisationCheck(settingsProviderInterface, windows);
})
.Await();
}
} // namespace UKControllerPlugin::Api
14 changes: 14 additions & 0 deletions src/plugin/api/FirstTimeApiAuthorisationChecker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

namespace UKControllerPluginUtils::Api {
class ApiSettingsProviderInterface;
} // namespace UKControllerPluginUtils::Api

namespace UKControllerPlugin::Windows {
class WinApiInterface;
} // namespace UKControllerPlugin::Windows
namespace UKControllerPlugin::Api {
void FirstTimeApiAuthorisationCheck(
UKControllerPluginUtils::Api::ApiSettingsProviderInterface& settingsProviderInterface,
Windows::WinApiInterface& windows);
} // namespace UKControllerPlugin::Api
21 changes: 21 additions & 0 deletions src/plugin/api/FirstTimeApiConfigLoader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "FirstTimeApiConfigLoader.h"
#include "api/ApiSettingsProviderInterface.h"

namespace UKControllerPlugin::Api {

auto LocateConfig(UKControllerPluginUtils::Api::ApiSettingsProviderInterface& settingsProvider) -> bool
{
if (settingsProvider.Has()) {
LogInfo("Api configuration successfully loaded");
return true;
}

if (!settingsProvider.Reload()) {
LogInfo("First time api config load, user elected not to load config");
return false;
}

LogInfo("First time api config load completed");
return true;
}
} // namespace UKControllerPlugin::Api
9 changes: 9 additions & 0 deletions src/plugin/api/FirstTimeApiConfigLoader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

namespace UKControllerPluginUtils::Api {
class ApiSettingsProviderInterface;
} // namespace UKControllerPluginUtils::Api

namespace UKControllerPlugin::Api {
auto LocateConfig(UKControllerPluginUtils::Api::ApiSettingsProviderInterface& settingsProvider) -> bool;
} // namespace UKControllerPlugin::Api

0 comments on commit 0b4527f

Please sign in to comment.