Sesame-Server/Sources/App/configure.swift

95 lines
3.2 KiB
Swift
Raw Normal View History

2022-01-23 20:49:06 +01:00
import Vapor
2023-01-31 19:10:57 +01:00
import Clairvoyant
2023-09-07 14:13:28 +02:00
import ClairvoyantVapor
import ClairvoyantBinaryCodable
2022-01-23 20:49:06 +01:00
2022-04-07 23:53:25 +02:00
var deviceManager: DeviceManager!
2022-01-24 17:17:06 +01:00
2023-09-07 14:13:28 +02:00
private var provider: VaporMetricProvider!
2023-11-27 18:17:00 +01:00
private var asyncScheduler = MultiThreadedEventLoopGroup(numberOfThreads: 2)
2023-10-01 19:26:31 +02:00
2023-11-10 15:08:33 +01:00
private let df: DateFormatter = {
let df = DateFormatter()
df.dateStyle = .short
df.timeStyle = .short
return df
}()
2022-01-23 20:49:06 +01:00
// configures your application
2023-12-06 09:49:26 +01:00
public func configure(_ app: Application) async throws {
2022-01-24 17:17:06 +01:00
let storageFolder = URL(fileURLWithPath: app.directory.resourcesDirectory)
2023-11-22 11:48:50 +01:00
let configUrl = storageFolder.appendingPathComponent("config.json")
let config = try Config(loadFrom: configUrl)
let logFolder = config.logURL(possiblyRelativeTo: storageFolder)
2023-09-07 15:33:10 +02:00
2023-09-07 14:13:28 +02:00
let monitor = MetricObserver(logFileFolder: logFolder, logMetricId: "sesame.log")
2023-01-31 19:10:57 +01:00
MetricObserver.standard = monitor
2023-12-08 12:39:10 +01:00
let status = Metric<ServerStatus>("sesame.status")
2023-12-06 09:49:26 +01:00
try await status.update(.initializing)
2023-01-31 19:10:33 +01:00
app.http.server.configuration.port = config.port
let keyFile = storageFolder.appendingPathComponent(config.keyFileName)
let (deviceKey, remoteKey) = try loadKeys(at: keyFile)
2023-12-08 12:39:10 +01:00
deviceManager = DeviceManager(deviceKey: deviceKey, remoteKey: remoteKey, deviceTimeout: config.deviceTimeout, serverStatus: status)
2023-12-08 20:26:17 +01:00
deviceManager.logger = app.logger
2023-12-08 12:39:10 +01:00
routes(app)
2023-09-07 14:13:28 +02:00
provider = .init(observer: monitor, accessManager: config.authenticationTokens)
2023-10-01 19:26:31 +02:00
provider.asyncScheduler = asyncScheduler
2023-09-07 14:13:28 +02:00
provider.registerRoutes(app)
2023-11-28 08:46:26 +01:00
monitor.saveCurrentListOfMetricsToLogFolder()
2023-01-31 19:10:33 +01:00
2023-12-08 12:39:10 +01:00
// Update the metric of the device and server status
2023-12-10 19:32:09 +01:00
await deviceManager.updateDeviceConnectionMetrics()
2023-11-08 10:24:50 +01:00
2023-11-27 18:17:00 +01:00
log("[\(df.string(from: Date()))] Server started")
2023-01-31 19:10:33 +01:00
}
2023-12-08 15:57:33 +01:00
public func shutdown() async {
// Gracefully shut down by closing potentially open socket
await deviceManager.removeDeviceConnection()
do {
try await asyncScheduler.shutdownGracefully()
} catch {
2023-12-08 19:54:51 +01:00
printAndFlush("Failed to shut down MultiThreadedEventLoopGroup: \(error)")
2023-11-28 11:20:29 +01:00
}
2023-12-08 19:54:51 +01:00
printAndFlush("[\(df.string(from: Date()))] Server shutdown")
2023-11-27 18:17:00 +01:00
}
2023-01-31 19:10:33 +01:00
private func loadKeys(at url: URL) throws -> (deviceKey: Data, remoteKey: Data) {
let authContent: [Data] = try String(contentsOf: url)
2022-01-24 17:17:06 +01:00
.trimmingCharacters(in: .whitespacesAndNewlines)
2022-05-01 13:12:16 +02:00
.components(separatedBy: "\n")
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
2022-05-01 13:28:06 +02:00
.map {
guard let key = Data(fromHexEncodedString: $0) else {
2023-12-06 09:53:24 +01:00
fatalError("Invalid key data: Failed to convert hex to binary.")
2022-05-01 13:28:06 +02:00
}
guard key.count == SHA256.byteCount else {
2023-12-06 09:53:24 +01:00
fatalError("Invalid key data: Length should be \(SHA256.byteCount), not \(key.count)")
2022-05-01 13:28:06 +02:00
}
return key
}
2022-05-01 13:12:16 +02:00
guard authContent.count == 2 else {
2023-12-06 09:53:24 +01:00
fatalError("Invalid keys: Expected 2, found \(authContent.count)")
2022-05-01 13:12:16 +02:00
}
2023-01-31 19:10:33 +01:00
return (deviceKey: authContent[0], remoteKey: authContent[1])
2022-01-23 20:49:06 +01:00
}
2023-02-06 21:44:56 +01:00
func log(_ message: String) {
2023-02-17 00:09:51 +01:00
guard let observer = MetricObserver.standard else {
2023-12-08 19:54:51 +01:00
printAndFlush(message)
2023-02-17 00:09:51 +01:00
return
}
2023-10-01 19:26:31 +02:00
asyncScheduler.schedule {
await observer.log(message)
2023-12-08 19:54:51 +01:00
flushStdout()
2023-10-01 19:26:31 +02:00
}
2023-02-06 21:44:56 +01:00
}