465 lines
6.7 KiB
TypeScript
465 lines
6.7 KiB
TypeScript
import * as amqp from "amqplib";
|
|
import os from "os";
|
|
import { loadConfig, saveConfig, RABBITMQ_URL, WRAPPER_HEARTBEAT_INTERVAL } from "./config";
|
|
import { ProcessManager } from "./processManager";
|
|
import { StatusReporter } from "./statusReporter";
|
|
import { QueryManager } from "./queryManager";
|
|
import {
|
|
WrapperRegisterMessage,
|
|
WrapperHeartbeatMessage,
|
|
ServerStartCommand,
|
|
ServerStopCommand
|
|
} from "server-manager-shared";
|
|
import { getLogger } from "./logger";
|
|
|
|
const logger = getLogger("Wrapper");
|
|
|
|
|
|
class Wrapper {
|
|
|
|
processManager =
|
|
new ProcessManager();
|
|
|
|
queryManager =
|
|
new QueryManager(
|
|
this.processManager
|
|
);
|
|
|
|
connection!: amqp.ChannelModel;
|
|
channel!: amqp.Channel;
|
|
|
|
|
|
id?: string;
|
|
|
|
|
|
|
|
async start(){
|
|
|
|
|
|
const config =
|
|
loadConfig();
|
|
|
|
logger.info("Konfiguration geladen");
|
|
|
|
|
|
if(config.wrapperId){
|
|
|
|
|
|
this.id =
|
|
config.wrapperId;
|
|
|
|
|
|
|
|
logger.debug(
|
|
"Starte mit vorhandener ID:",
|
|
this.id
|
|
);
|
|
|
|
|
|
}else{
|
|
|
|
|
|
logger.warn(
|
|
"Keine Wrapper ID vorhanden - neue Registrierung"
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.connection =
|
|
await amqp.connect(
|
|
RABBITMQ_URL
|
|
);
|
|
|
|
|
|
|
|
this.channel =
|
|
await this.connection.createChannel();
|
|
|
|
|
|
|
|
logger.info(
|
|
"RabbitMQ Verbindung hergestellt"
|
|
);
|
|
|
|
|
|
|
|
this.queryManager.start();
|
|
await this.register();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async register(){
|
|
|
|
|
|
|
|
const reply =
|
|
await this.channel.assertQueue(
|
|
"",
|
|
{
|
|
exclusive:true
|
|
}
|
|
);
|
|
|
|
|
|
|
|
const replyQueue =
|
|
reply.queue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await this.channel.consume(
|
|
|
|
replyQueue,
|
|
|
|
msg=>{
|
|
|
|
|
|
if(!msg)
|
|
return;
|
|
|
|
|
|
|
|
const data =
|
|
JSON.parse(
|
|
msg.content.toString()
|
|
);
|
|
|
|
|
|
|
|
logger.debug(
|
|
"Antwort vom Manager:",
|
|
data.type
|
|
);
|
|
|
|
|
|
|
|
|
|
if(data.type==="wrapper.registered"){
|
|
|
|
|
|
|
|
this.id =
|
|
data.wrapperId;
|
|
|
|
|
|
|
|
saveConfig({
|
|
|
|
wrapperId:
|
|
this.id
|
|
|
|
});
|
|
|
|
|
|
|
|
logger.info(
|
|
"Registrierung beim Manager erfolgreich"
|
|
);
|
|
logger.debug(
|
|
"Wrapper ID gespeichert:",
|
|
this.id
|
|
);
|
|
|
|
if(!this.id){
|
|
|
|
logger.error(
|
|
"Keine Wrapper ID erhalten!"
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
this.listenCommands(
|
|
data.commandQueue
|
|
);
|
|
|
|
const reporter =
|
|
new StatusReporter(
|
|
|
|
this.channel,
|
|
|
|
this.processManager,
|
|
|
|
this.queryManager,
|
|
|
|
this.id
|
|
|
|
);
|
|
|
|
|
|
reporter.start();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this.channel.ack(msg);
|
|
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const message: WrapperRegisterMessage = {
|
|
|
|
|
|
|
|
type:
|
|
"wrapper.register",
|
|
|
|
|
|
|
|
// vorhandene ID mitsenden
|
|
wrapperId:
|
|
this.id,
|
|
|
|
|
|
|
|
hostname:
|
|
os.hostname(),
|
|
|
|
|
|
|
|
cpu:
|
|
os.cpus().length,
|
|
|
|
|
|
|
|
ram:
|
|
Math.round(
|
|
os.totalmem()/1024/1024
|
|
),
|
|
|
|
|
|
|
|
replyQueue
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await this.channel.sendToQueue(
|
|
|
|
"wrapper.register",
|
|
|
|
Buffer.from(
|
|
JSON.stringify(message)
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
logger.debug(
|
|
"Registrierung gesendet",
|
|
this.id ?? "ohne ID"
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async listenCommands(queue:string){
|
|
|
|
|
|
await this.channel.consume(
|
|
|
|
queue,
|
|
|
|
msg=>{
|
|
|
|
|
|
if(!msg)
|
|
return;
|
|
|
|
|
|
|
|
const rawCommand =
|
|
JSON.parse(
|
|
msg.content.toString()
|
|
) as unknown;
|
|
|
|
|
|
|
|
const commandType = (rawCommand as { type?: string }).type;
|
|
switch(commandType){
|
|
|
|
|
|
|
|
case "test": {
|
|
const command = rawCommand as {
|
|
type: string;
|
|
message?: unknown;
|
|
};
|
|
|
|
logger.debug(
|
|
"TEST COMMAND:",
|
|
command.message
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
case "server.start": {
|
|
const command = rawCommand as ServerStartCommand;
|
|
|
|
this.processManager.startServer(
|
|
command
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
case "server.stop": {
|
|
const command = rawCommand as ServerStopCommand;
|
|
|
|
this.processManager.stopServer(
|
|
command.serverId
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
default:
|
|
|
|
|
|
logger.warn(
|
|
"Unbekannter Command:",
|
|
commandType
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this.channel.ack(msg);
|
|
|
|
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
logger.debug(
|
|
"Warte auf Commands:",
|
|
queue
|
|
);
|
|
|
|
|
|
|
|
this.heartbeat();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
heartbeat(){
|
|
|
|
logger.debug("Heartbeat gestartet");
|
|
setInterval(()=>{
|
|
|
|
|
|
|
|
if(!this.id)
|
|
return;
|
|
|
|
|
|
|
|
const heartbeat: WrapperHeartbeatMessage = {
|
|
|
|
|
|
type:
|
|
"wrapper.heartbeat",
|
|
|
|
|
|
|
|
wrapperId:
|
|
this.id
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.channel.sendToQueue(
|
|
|
|
|
|
"wrapper.register",
|
|
|
|
|
|
|
|
Buffer.from(
|
|
|
|
JSON.stringify(
|
|
heartbeat
|
|
)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
logger.debug(
|
|
"Heartbeat gesendet"
|
|
);
|
|
|
|
|
|
|
|
},WRAPPER_HEARTBEAT_INTERVAL);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
new Wrapper().start(); |