2020-04-17 14:50:12 +02:00
|
|
|
module server.handler;
|
|
|
|
|
|
|
|
import std.stdio : writeln;
|
2020-04-17 21:28:35 +02:00
|
|
|
import std.socket : Socket, AddressFamily, parseAddress, SocketType, SocketOSException;
|
2020-04-17 14:50:12 +02:00
|
|
|
import std.json : JSONValue, JSONType;
|
|
|
|
import utils.debugging : debugPrint;
|
|
|
|
|
|
|
|
public class MessageHandler
|
|
|
|
{
|
|
|
|
/* The path to the message handler executable */
|
|
|
|
private string executablePath;
|
|
|
|
|
|
|
|
/* The UNIX domain socket */
|
|
|
|
private Socket domainSocket;
|
|
|
|
|
|
|
|
this(string executablePath, string socketPath)
|
|
|
|
{
|
2020-04-17 16:23:47 +02:00
|
|
|
/* Initialize the socket */
|
2020-04-17 15:53:31 +02:00
|
|
|
initializeUNIXSocket(socketPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void initializeUNIXSocket(string socketPath)
|
|
|
|
{
|
2020-04-17 16:19:18 +02:00
|
|
|
/* Create the UNIX domain socket */
|
2020-04-17 16:22:25 +02:00
|
|
|
domainSocket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
|
2020-04-17 16:19:18 +02:00
|
|
|
|
|
|
|
/* Bind it to the socket path */
|
2020-04-17 16:23:47 +02:00
|
|
|
domainSocket.connect(parseAddress(socketPath));
|
2020-04-17 14:50:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private static string[] getAvailableTypes(JSONValue handlerBlock)
|
|
|
|
{
|
2020-04-17 16:08:05 +02:00
|
|
|
/* Available types as strings */
|
|
|
|
string[] availableTypesStrings;
|
2020-04-17 14:50:12 +02:00
|
|
|
|
|
|
|
/* Get the available handlers */
|
2020-04-17 16:08:05 +02:00
|
|
|
JSONValue availableTypes;
|
2020-04-17 14:50:12 +02:00
|
|
|
|
2020-04-17 16:08:05 +02:00
|
|
|
/* TODO: Bounds check */
|
|
|
|
availableTypes = handlerBlock["availableTypes"];
|
2020-04-17 14:50:12 +02:00
|
|
|
|
2020-04-17 16:08:05 +02:00
|
|
|
/* Make sure it is an array */
|
|
|
|
if(availableTypes.type == JSONType.array)
|
|
|
|
{
|
|
|
|
/* Get the array of available types */
|
|
|
|
JSONValue[] availableTypesArray = availableTypes.array;
|
2020-04-17 14:50:12 +02:00
|
|
|
|
2020-04-17 16:08:05 +02:00
|
|
|
for(uint i = 0; i < availableTypesArray.length; i++)
|
|
|
|
{
|
|
|
|
/* Make sure that it is a string */
|
|
|
|
if(availableTypesArray[i].type == JSONType.string)
|
|
|
|
{
|
|
|
|
/* Add the type handler to the list of available types */
|
|
|
|
availableTypesStrings ~= availableTypesArray[i].str;
|
|
|
|
debugPrint("Module wanted: " ~ availableTypesArray[i].str);
|
2020-04-17 14:50:12 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-17 16:08:05 +02:00
|
|
|
/* TODO: Error handling here */
|
|
|
|
debugPrint("Available type not of type JSON string");
|
2020-04-17 14:50:12 +02:00
|
|
|
}
|
2020-04-17 16:08:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* TODO: Error handling */
|
|
|
|
}
|
|
|
|
|
|
|
|
return availableTypesStrings;
|
2020-04-17 14:50:12 +02:00
|
|
|
}
|
|
|
|
|
2020-04-17 15:33:38 +02:00
|
|
|
private static string[2] getConfigurationArray(string pluginName, JSONValue typeMapBlock)
|
|
|
|
{
|
|
|
|
/* The configuration string */
|
|
|
|
string[2] configurationString;
|
|
|
|
|
2020-04-17 16:19:18 +02:00
|
|
|
/* The module block */
|
2020-04-17 15:33:38 +02:00
|
|
|
JSONValue moduleBlock;
|
|
|
|
|
|
|
|
/* TODO: Bounds check */
|
|
|
|
moduleBlock = typeMapBlock[pluginName];
|
|
|
|
|
|
|
|
/* Module block mst be of tpe JSON object */
|
|
|
|
if(moduleBlock.type == JSONType.object)
|
|
|
|
{
|
|
|
|
/* TODO: Set the executable path */
|
|
|
|
/* TODO: Set the UNIX domain socket path */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* TODO: Error handling */
|
|
|
|
}
|
|
|
|
|
|
|
|
return configurationString;
|
|
|
|
}
|
|
|
|
|
2020-04-17 14:50:12 +02:00
|
|
|
/* TODO: Implement me */
|
|
|
|
public static MessageHandler[] constructHandlers(JSONValue handlerBlock)
|
|
|
|
{
|
|
|
|
/* List of loaded message handlers */
|
|
|
|
MessageHandler[] handlers;
|
|
|
|
|
|
|
|
/* TODO: Throwing error from inside this function */
|
|
|
|
string[] availableTypes = getAvailableTypes(handlerBlock);
|
2020-04-17 15:33:38 +02:00
|
|
|
|
|
|
|
for(uint i = 0; i < availableTypes.length; i++)
|
|
|
|
{
|
|
|
|
/* Load module */
|
|
|
|
string pluginName = availableTypes[i];
|
|
|
|
debugPrint("Loading module \"" ~ pluginName ~ "\"...");
|
|
|
|
|
2020-04-17 21:28:35 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
JSONValue typeMap;
|
|
|
|
|
|
|
|
/* TODO: Bounds check */
|
|
|
|
typeMap = handlerBlock["typeMap"];
|
2020-04-17 15:33:38 +02:00
|
|
|
|
2020-04-17 21:28:35 +02:00
|
|
|
string[2] configuration = getConfigurationArray(pluginName, typeMap);
|
|
|
|
debugPrint("Module executable at: \"" ~ configuration[0] ~ "\"");
|
|
|
|
debugPrint("Module socket path at: \"" ~ configuration[1] ~ "\"");
|
|
|
|
MessageHandler constructedMessageHandler = new MessageHandler(configuration[0], configuration[1]);
|
|
|
|
handlers ~= constructedMessageHandler;
|
|
|
|
debugPrint("Module \"" ~ pluginName ~ "\" loaded");
|
|
|
|
}
|
|
|
|
catch(SocketOSException exception)
|
|
|
|
{
|
|
|
|
debugPrint("Error whilst loading module \"" ~ pluginName ~ "\": " ~ exception.toString());
|
|
|
|
}
|
2020-04-17 15:33:38 +02:00
|
|
|
}
|
2020-04-17 14:50:12 +02:00
|
|
|
|
|
|
|
return handlers;
|
|
|
|
}
|
|
|
|
}
|