Compare commits
3 Commits
f4864127f8
...
ac22fcd4eb
Author | SHA1 | Date | |
---|---|---|---|
|
ac22fcd4eb | ||
|
b2b3c74586 | ||
|
eb10ae6626 |
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) <year> <copyright holders>
|
Copyright (c) 2023 Christoph Hagen
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
@ -13,25 +13,14 @@ let package = Package(
|
|||||||
.package(url: "https://github.com/christophhagen/ClairvoyantBinaryCodable", from: "0.3.1"),
|
.package(url: "https://github.com/christophhagen/ClairvoyantBinaryCodable", from: "0.3.1"),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(
|
.executableTarget(
|
||||||
name: "App",
|
name: "App",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.product(name: "Vapor", package: "vapor"),
|
.product(name: "Vapor", package: "vapor"),
|
||||||
.product(name: "Clairvoyant", package: "Clairvoyant"),
|
.product(name: "Clairvoyant", package: "Clairvoyant"),
|
||||||
.product(name: "ClairvoyantVapor", package: "ClairvoyantVapor"),
|
.product(name: "ClairvoyantVapor", package: "ClairvoyantVapor"),
|
||||||
.product(name: "ClairvoyantBinaryCodable", package: "ClairvoyantBinaryCodable"),
|
.product(name: "ClairvoyantBinaryCodable", package: "ClairvoyantBinaryCodable"),
|
||||||
],
|
]
|
||||||
swiftSettings: [
|
)
|
||||||
// Enable better optimizations when building in Release configuration. Despite the use of
|
|
||||||
// the `.unsafeFlags` construct required by SwiftPM, this flag is recommended for Release
|
|
||||||
// builds. See <https://github.com/swift-server/guides/blob/main/docs/building.md#building-for-production> for details.
|
|
||||||
.unsafeFlags(["-cross-module-optimization"], .when(configuration: .release))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
.executableTarget(name: "Run", dependencies: [.target(name: "App")]),
|
|
||||||
.testTarget(name: "AppTests", dependencies: [
|
|
||||||
.target(name: "App"),
|
|
||||||
.product(name: "XCTVapor", package: "vapor"),
|
|
||||||
])
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
@ -17,23 +17,8 @@ private let df: DateFormatter = {
|
|||||||
return df
|
return df
|
||||||
}()
|
}()
|
||||||
|
|
||||||
enum ServerError: Error {
|
|
||||||
case invalidAuthenticationFileContent
|
|
||||||
case invalidAuthenticationToken
|
|
||||||
}
|
|
||||||
|
|
||||||
private func updateStatus(_ newStatus: ServerStatus) {
|
|
||||||
asyncScheduler.schedule {
|
|
||||||
do {
|
|
||||||
try await status.update(newStatus)
|
|
||||||
} catch {
|
|
||||||
print("Failed to update server status: \(error)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// configures your application
|
// configures your application
|
||||||
public func configure(_ app: Application) throws {
|
public func configure(_ app: Application) async throws {
|
||||||
let storageFolder = URL(fileURLWithPath: app.directory.resourcesDirectory)
|
let storageFolder = URL(fileURLWithPath: app.directory.resourcesDirectory)
|
||||||
|
|
||||||
let configUrl = storageFolder.appendingPathComponent("config.json")
|
let configUrl = storageFolder.appendingPathComponent("config.json")
|
||||||
@ -45,7 +30,7 @@ public func configure(_ app: Application) throws {
|
|||||||
MetricObserver.standard = monitor
|
MetricObserver.standard = monitor
|
||||||
|
|
||||||
status = Metric<ServerStatus>("sesame.status")
|
status = Metric<ServerStatus>("sesame.status")
|
||||||
updateStatus(.initializing)
|
try await status.update(.initializing)
|
||||||
|
|
||||||
app.http.server.configuration.port = config.port
|
app.http.server.configuration.port = config.port
|
||||||
|
|
||||||
@ -61,12 +46,10 @@ public func configure(_ app: Application) throws {
|
|||||||
provider.registerRoutes(app)
|
provider.registerRoutes(app)
|
||||||
monitor.saveCurrentListOfMetricsToLogFolder()
|
monitor.saveCurrentListOfMetricsToLogFolder()
|
||||||
|
|
||||||
updateStatus(.nominal)
|
try await status.update(.nominal)
|
||||||
|
|
||||||
// Update the metric of the device status to ensure that it is accurate
|
// Update the metric of the device status to ensure that it is accurate
|
||||||
asyncScheduler.schedule {
|
|
||||||
await deviceManager.updateDeviceConnectionMetric()
|
await deviceManager.updateDeviceConnectionMetric()
|
||||||
}
|
|
||||||
|
|
||||||
log("[\(df.string(from: Date()))] Server started")
|
log("[\(df.string(from: Date()))] Server started")
|
||||||
}
|
}
|
||||||
@ -91,15 +74,15 @@ private func loadKeys(at url: URL) throws -> (deviceKey: Data, remoteKey: Data)
|
|||||||
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
|
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
|
||||||
.map {
|
.map {
|
||||||
guard let key = Data(fromHexEncodedString: $0) else {
|
guard let key = Data(fromHexEncodedString: $0) else {
|
||||||
throw ServerError.invalidAuthenticationToken
|
fatalError("Invalid key data: Failed to convert hex to binary.")
|
||||||
}
|
}
|
||||||
guard key.count == SHA256.byteCount else {
|
guard key.count == SHA256.byteCount else {
|
||||||
throw ServerError.invalidAuthenticationToken
|
fatalError("Invalid key data: Length should be \(SHA256.byteCount), not \(key.count)")
|
||||||
}
|
}
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
guard authContent.count == 2 else {
|
guard authContent.count == 2 else {
|
||||||
throw ServerError.invalidAuthenticationFileContent
|
fatalError("Invalid keys: Expected 2, found \(authContent.count)")
|
||||||
}
|
}
|
||||||
return (deviceKey: authContent[0], remoteKey: authContent[1])
|
return (deviceKey: authContent[0], remoteKey: authContent[1])
|
||||||
}
|
}
|
||||||
|
43
Sources/App/entrypoint.swift
Normal file
43
Sources/App/entrypoint.swift
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import Vapor
|
||||||
|
import Dispatch
|
||||||
|
import Logging
|
||||||
|
|
||||||
|
/// This extension is temporary and can be removed once Vapor gets this support.
|
||||||
|
private extension Vapor.Application {
|
||||||
|
static let baseExecutionQueue = DispatchQueue(label: "vapor.codes.entrypoint")
|
||||||
|
|
||||||
|
func runFromAsyncMainEntrypoint() async throws {
|
||||||
|
try await withCheckedThrowingContinuation { continuation in
|
||||||
|
Vapor.Application.baseExecutionQueue.async { [self] in
|
||||||
|
do {
|
||||||
|
try self.run()
|
||||||
|
continuation.resume()
|
||||||
|
} catch {
|
||||||
|
continuation.resume(throwing: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@main
|
||||||
|
enum Entrypoint {
|
||||||
|
static func main() async throws {
|
||||||
|
var env = try Environment.detect()
|
||||||
|
try LoggingSystem.bootstrap(from: &env)
|
||||||
|
|
||||||
|
let app = Application(env)
|
||||||
|
defer {
|
||||||
|
shutdown()
|
||||||
|
app.shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
try await configure(app)
|
||||||
|
} catch {
|
||||||
|
app.logger.report(error: error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
try await app.runFromAsyncMainEntrypoint()
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +0,0 @@
|
|||||||
import App
|
|
||||||
import Vapor
|
|
||||||
|
|
||||||
var env = Environment.production //.detect()
|
|
||||||
try LoggingSystem.bootstrap(from: &env)
|
|
||||||
let app = Application(env)
|
|
||||||
defer {
|
|
||||||
shutdown()
|
|
||||||
app.shutdown()
|
|
||||||
}
|
|
||||||
|
|
||||||
try configure(app)
|
|
||||||
try app.run()
|
|
@ -1,13 +0,0 @@
|
|||||||
@testable import App
|
|
||||||
import XCTVapor
|
|
||||||
|
|
||||||
final class AppTests: XCTestCase {
|
|
||||||
|
|
||||||
func testEncodingUInt32() {
|
|
||||||
let input: UInt32 = 123
|
|
||||||
let data = input.encoded
|
|
||||||
let output = UInt32(data: data)
|
|
||||||
XCTAssertEqual(input, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user