Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Airsync Daemon #153

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
dc82c29
Added UI for invitation email and link click
Sep 28, 2023
049c79c
Disable update for pre-added fleet and email values
Sep 28, 2023
99c0d5e
Added api endpoint for email invitation
Oct 1, 2023
6d62dff
Refined ui
e911 Oct 1, 2023
3a84738
Fix class name on logger
e911 Oct 1, 2023
d45ee3b
Fixed email link and refined ui
e911 Oct 2, 2023
5717e7a
Merge branch 'main' of github.com:travisdesell/ngafid2.0
Oct 24, 2023
328ffc5
New flight file format
e911 Oct 25, 2023
a18171b
LatLon fix
e911 Oct 25, 2023
cdbb984
LatLon fix
e911 Oct 25, 2023
86f7bfa
Merge branch 'main' of github.com:travisdesell/ngafid2.0
Oct 25, 2023
1c90d89
Fixed flight data
e911 Oct 26, 2023
c6ace09
Added tail number for the flight
e911 Oct 26, 2023
56e3df2
Merge branch 'pujan/new_flight_format' of github.com:travisdesell/nga…
Oct 30, 2023
542998c
Merge branch 'main' of github.com:travisdesell/ngafid2.0
Nov 20, 2023
cd87112
Merge branch 'main' of github.com:travisdesell/ngafid2.0
Jan 4, 2024
bcbf433
Merge branch 'main' of github.com:travisdesell/ngafid2.0
Apr 30, 2024
3da68e1
Merge branch 'main' of github.com:travisdesell/ngafid2.0
Jun 7, 2024
274ea19
Merge branch 'main' of github.com:travisdesell/ngafid2.0
Jun 19, 2024
a37cbd6
Rebase conflicts
Jun 19, 2024
fb45c78
Leftover conflict
Jun 20, 2024
7ec923f
Add override field
Jun 21, 2024
6387920
Fix airsync database integrity bug
jkarns275 Jul 23, 2024
f5b07a8
Partition aircraft by Airsync fleet name
jkarns275 Aug 14, 2024
9dce31a
Resolve merge conflicts
jkarns275 Aug 14, 2024
e18dfa1
Fix two small bugs
jkarns275 Sep 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 6 additions & 40 deletions db/create_tables.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@
query_ngafid_db($query);



$query = "CREATE TABLE `user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`email` VARCHAR(128) NOT NULL,
Expand Down Expand Up @@ -608,12 +607,13 @@
query_ngafid_db($query);

$query = "CREATE TABLE `airsync_fleet_info` (
`fleet_id` int(11) NOT NULL,
`api_key` varchar(32) NOT NULL,
`api_secret` varchar(64) NOT NULL,
`fleet_id` int(11) NOT NULL,
`airsync_fleet_name` TEXT NOT NULL,
`api_key` varchar(32) NOT NULL,
`api_secret` varchar(64) NOT NULL,
`last_upload_time` timestamp ON UPDATE CURRENT_TIMESTAMP,
`timeout` int(11) DEFAULT NULL,
`mutex` TINYINT DEFAULT 0,
`timeout` int(11) DEFAULT NULL,
`override` tinyint(4) DEFAULT NULL,

PRIMARY KEY(`fleet_id`),
FOREIGN KEY(`fleet_id`) REFERENCES `fleet`(`id`)
Expand Down Expand Up @@ -641,40 +641,6 @@
query_ngafid_db($query);
}

if ($create_airsync) {
$query = "CREATE TABLE `airsync_fleet_info` (
`fleet_id` int(11) NOT NULL,
`api_key` varchar(32) NOT NULL,
`api_secret` varchar(64) NOT NULL,
`last_upload_time` timestamp ON UPDATE CURRENT_TIMESTAMP,
`timeout` int(11) DEFAULT NULL,
`mutex` TINYINT DEFAULT 0,
KEY `airsync_fleet_id_fk` (`fleet_id`),
CONSTRAINT `airsync_fleet_id_fk` FOREIGN KEY (`fleet_id`) REFERENCES `fleet` (`id`)
);";

query_ngafid_db($query);

$query = "CREATE TABLE `airsync_imports` (
`id` int(11) NOT NULL,
`time_received` timestamp NULL DEFAULT NULL,
`upload_id` int(11) NOT NULL,
`fleet_id` int(11) NOT NULL,
`flight_id` int(11) DEFAULT NULL,
`tail` varchar(512) NOT NULL,
PRIMARY KEY (`id`),
KEY `airsync_imports_uploads_null_fk` (`upload_id`),
KEY `airsync_imports_fleet_id_fk` (`fleet_id`),
KEY `airsync_imports_flights_null_fk` (`flight_id`),
CONSTRAINT `airsync_imports_fleet_id_fk` FOREIGN KEY (`fleet_id`) REFERENCES `fleet` (`id`),
CONSTRAINT `airsync_imports_flights_null_fk` FOREIGN KEY (`flight_id`) REFERENCES `flights` (`id`),
CONSTRAINT `airsync_imports_uploads_null_fk` FOREIGN KEY (`upload_id`) REFERENCES `uploads` (`id`)
);";

query_ngafid_db($query);
}


if (!$update_turn_to_final) {
$query = "CREATE TABLE `turn_to_final` (
`flight_id` INT(11) NOT NULL,
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/org/ngafid/WebServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ public LocalDateTime read(final JsonReader jsonReader) throws IOException {
}
MUSTACHE_TEMPLATE_DIR = System.getenv("MUSTACHE_TEMPLATE_DIR");

Runtime.getRuntime().addShutdownHook(new Thread(() -> {
String message = "NGAFID WebServer has shutdown at " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm:ss"));
LOG.info(message);
sendAdminEmails(message, "", EmailType.ADMIN_SHUTDOWN_NOTIFICATION);
}));
// Runtime.getRuntime().addShutdownHook(new Thread(() -> {
// String message = "NGAFID WebServer has shutdown at " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm:ss"));
// LOG.info(message);
// sendAdminEmails(message, "", EmailType.ADMIN_SHUTDOWN_NOTIFICATION);
// }));
}

/**
Expand Down
74 changes: 51 additions & 23 deletions src/main/java/org/ngafid/accounts/AirSyncAircraft.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.net.*;
import java.sql.*;
import javax.net.ssl.HttpsURLConnection;
import java.nio.charset.StandardCharsets;

import org.ngafid.WebServer;
import org.ngafid.accounts.AirSyncAuth.AccessToken;
Expand All @@ -12,6 +13,7 @@

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.google.gson.reflect.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
Expand Down Expand Up @@ -127,13 +129,15 @@ public Optional<LocalDateTime> getLastImportTime(Connection connection) throws S
*
* @throws an exception if there is a network or dbms issue
*/
private List<AirSyncImport> getImportsHTTPS(HttpsURLConnection netConnection, AirSyncAuth authentication) throws Exception {
private List<AirSyncImport> getImportsHTTPS(HttpsURLConnection netConnection, AirSyncAuth authentication) throws IOException {
netConnection.setRequestMethod("GET");
netConnection.setDoOutput(true);
netConnection.setRequestProperty("Authorization", authentication.bearerString());

InputStream is = netConnection.getInputStream();
byte [] respRaw = is.readAllBytes();
byte[] respRaw;
try (InputStream is = netConnection.getInputStream()) {
respRaw = is.readAllBytes();
}

String resp = new String(respRaw).replaceAll("aircraft_id", "aircraftId");
resp = resp.replaceAll("tail_number", "tailNumber");
Expand All @@ -152,6 +156,38 @@ private List<AirSyncImport> getImportsHTTPS(HttpsURLConnection netConnection, Ai
return page;
}

static class AirSyncAircraftAccountInfo {
public String account_token, name;

public AirSyncAircraftAccountInfo() {}
}

public String getAirSyncFleetName() {
try {
AirSyncAuth authentication = fleet.getAuth();
HttpsURLConnection netConnection = (HttpsURLConnection) new URL(AirSyncEndpoints.AIRSYNC_ROOT + "/aircraft/accounts").openConnection();
netConnection.setRequestMethod("GET");
netConnection.setDoOutput(true);
netConnection.setRequestProperty("Authorization", authentication.bearerString());

byte[] respRaw;
try (InputStream is = netConnection.getInputStream()) {
respRaw = is.readAllBytes();
}

List<AirSyncAircraftAccountInfo> info = gson.fromJson(new String(respRaw), new TypeToken<List<AirSyncAircraftAccountInfo>>(){}.getType());

if (info.size() != 1) {
LOG.severe("AirSync aircraft appears for multiple fleets. We do not support this functionality currently...");
System.exit(1);
}

return info.get(0).name;
} catch (IOException e) {
return null;
}
}

/**
* Gets ALL imports for this Aircraft
*
Expand All @@ -160,23 +196,19 @@ private List<AirSyncImport> getImportsHTTPS(HttpsURLConnection netConnection, Ai
*
* @return a {@link List} of AirSyncImports
*/
public List<AirSyncImport> getImports(Connection connection, AirSyncFleet fleet) {
public List<AirSyncImport> getImports(Connection connection, AirSyncFleet fleet) throws IOException {
AirSyncAuth authentication = fleet.getAuth();
List<AirSyncImport> imports = new LinkedList<>();

boolean continueIteration = true;

int nPage = 0;
while (continueIteration) {
try {
HttpsURLConnection netConnection = (HttpsURLConnection) getAircraftLogURL(nPage++).openConnection();
List<AirSyncImport> page = getImportsHTTPS(netConnection, fleet.getAuth());

continueIteration = page.size() == AirSyncEndpoints.PAGE_SIZE;
imports.addAll(page);
} catch (Exception e) {
AirSync.handleAirSyncAPIException(e, authentication);
}
HttpsURLConnection netConnection = (HttpsURLConnection) getAircraftLogURL(nPage++).openConnection();
List<AirSyncImport> page = getImportsHTTPS(netConnection, fleet.getAuth());

continueIteration = page.size() == AirSyncEndpoints.PAGE_SIZE;
imports.addAll(page);
}

return imports;
Expand All @@ -191,7 +223,7 @@ public List<AirSyncImport> getImports(Connection connection, AirSyncFleet fleet)
*
* @return a {@link List} of AirSyncImports
*/
public List<AirSyncImport> getImportsAfterDate(Connection connection, AirSyncFleet fleet, LocalDateTime lastImportTime) {
public List<AirSyncImport> getImportsAfterDate(Connection connection, AirSyncFleet fleet, LocalDateTime lastImportTime) throws IOException {
AirSyncAuth authentication = fleet.getAuth();
List<AirSyncImport> imports = new LinkedList<>();

Expand All @@ -200,15 +232,11 @@ public List<AirSyncImport> getImportsAfterDate(Connection connection, AirSyncFle
int nPage = 0;

while (continueIteration) {
try {
HttpsURLConnection netConnection = (HttpsURLConnection) getAircraftLogURL(nPage++, lastImportTime).openConnection();
List<AirSyncImport> page = getImportsHTTPS(netConnection, authentication);

continueIteration = page.size() == AirSyncEndpoints.PAGE_SIZE;
imports.addAll(page);
} catch (Exception e) {
AirSync.handleAirSyncAPIException(e, authentication);
}
HttpsURLConnection netConnection = (HttpsURLConnection) getAircraftLogURL(nPage++, lastImportTime).openConnection();
List<AirSyncImport> page = getImportsHTTPS(netConnection, authentication);

continueIteration = page.size() == AirSyncEndpoints.PAGE_SIZE;
imports.addAll(page);
}

return imports;
Expand Down
16 changes: 10 additions & 6 deletions src/main/java/org/ngafid/accounts/AirSyncAuth.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ class AccessToken {
public AirSyncAuth(String apiKey, String apiSecret) {
byte [] srcWord = (apiKey + ":" + apiSecret).getBytes();
this.hash = Base64.getEncoder().encode(srcWord);

System.out.println("API Key = " + apiKey);
System.out.println("API Secret = " + apiSecret);
this.requestAuthorization();
}

Expand All @@ -69,13 +70,16 @@ public void requestAuthorization() {
connection.setDoOutput(true);
connection.setRequestProperty("Authorization", "Basic " + new String(this.hash));

InputStream is = connection.getInputStream();
byte [] respRaw = is.readAllBytes();
try (InputStream is = connection.getInputStream()) {
byte [] respRaw = is.readAllBytes();

is.close();

String resp = new String(respRaw).replaceAll("access_token", "accessToken");
String resp = new String(respRaw).replaceAll("access_token", "accessToken");

this.accessToken = gson.fromJson(resp, AccessToken.class);
this.issueTime = LocalDateTime.now();
this.accessToken = gson.fromJson(resp, AccessToken.class);
this.issueTime = LocalDateTime.now();
}
} catch (IOException ie) {
ie.printStackTrace();
System.err.println("FATAL: Unable to get a token from AirSync! Exiting due to fatal error.");
Expand Down
Loading