Merged activatedServices and services, removed uses of fmt

Signed-off-by: Arzumify <jliwin98@danwin1210.de>
This commit is contained in:
Tracker-Friendly 2024-10-04 19:37:05 +01:00
parent c3ffab9296
commit 1290b10774
1 changed files with 57 additions and 77 deletions

132
main.go
View File

@ -2,7 +2,6 @@ package main
import ( import (
"errors" "errors"
"fmt"
library "git.ailur.dev/ailur/fg-library" library "git.ailur.dev/ailur/fg-library"
"github.com/go-chi/chi/v5/middleware" "github.com/go-chi/chi/v5/middleware"
"io" "io"
@ -47,8 +46,9 @@ type Config struct {
Services map[string]interface{} `json:"services"` Services map[string]interface{} `json:"services"`
} }
type ActiveService struct { type Service struct {
ServiceID uuid.UUID ServiceID uuid.UUID
ServiceMetadata library.Service
Inbox chan library.InterServiceMessage Inbox chan library.InterServiceMessage
ActivationConfirmed bool ActivationConfirmed bool
} }
@ -61,8 +61,7 @@ var (
}) })
} }
validate *validator.Validate validate *validator.Validate
activeServices = make(map[uuid.UUID]ActiveService) services = make(map[uuid.UUID]Service)
services = make(map[uuid.UUID]library.Service)
lock sync.RWMutex lock sync.RWMutex
) )
@ -71,7 +70,7 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
message := <-channel message := <-channel
if message.ForServiceID == uuid.MustParse("00000000-0000-0000-0000-000000000000") { if message.ForServiceID == uuid.MustParse("00000000-0000-0000-0000-000000000000") {
// Broadcast message // Broadcast message
for _, service := range activeServices { for _, service := range services {
// We don't want to overwhelm a non-activated service // We don't want to overwhelm a non-activated service
if service.ActivationConfirmed { if service.ActivationConfirmed {
service.Inbox <- message service.Inbox <- message
@ -83,11 +82,12 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
case 0: case 0:
// Service initialization message, register the service // Service initialization message, register the service
lock.Lock() lock.Lock()
inbox := activeServices[message.ServiceID].Inbox inbox := services[message.ServiceID].Inbox
activeServices[message.ServiceID] = ActiveService{ services[message.ServiceID] = Service{
ServiceID: message.ServiceID, ServiceID: message.ServiceID,
Inbox: inbox, Inbox: inbox,
ActivationConfirmed: true, ActivationConfirmed: true,
ServiceMetadata: services[message.ServiceID].ServiceMetadata,
} }
lock.Unlock() lock.Unlock()
// Report a successful activation // Report a successful activation
@ -101,14 +101,14 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
case 1: case 1:
// Service database initialization message // Service database initialization message
// Check if the service has the necessary permissions // Check if the service has the necessary permissions
if services[message.ServiceID].Permissions.Database { if services[message.ServiceID].ServiceMetadata.Permissions.Database {
// Check if we are using sqlite or postgres // Check if we are using sqlite or postgres
if config.Database.DatabaseType == "sqlite" { if config.Database.DatabaseType == "sqlite" {
// Open the database and return the connection // Open the database and return the connection
pluginConn, err := sql.Open("sqlite", filepath.Join(config.Database.DatabasePath, message.ServiceID.String()+".db")) pluginConn, err := sql.Open("sqlite", filepath.Join(config.Database.DatabasePath, message.ServiceID.String()+".db"))
if err != nil { if err != nil {
// Report an error // Report an error
activeServices[message.ServiceID].Inbox <- library.InterServiceMessage{ services[message.ServiceID].Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
ForServiceID: message.ServiceID, ForServiceID: message.ServiceID,
MessageType: 1, MessageType: 1,
@ -117,7 +117,7 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
} }
} else { } else {
// Report a successful activation // Report a successful activation
activeServices[message.ServiceID].Inbox <- library.InterServiceMessage{ services[message.ServiceID].Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
ForServiceID: message.ServiceID, ForServiceID: message.ServiceID,
MessageType: 2, MessageType: 2,
@ -130,7 +130,7 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
conn, err := sql.Open("postgres", config.Database.ConnectionString) conn, err := sql.Open("postgres", config.Database.ConnectionString)
if err != nil { if err != nil {
// Report an error // Report an error
activeServices[message.ServiceID].Inbox <- library.InterServiceMessage{ services[message.ServiceID].Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
ForServiceID: message.ServiceID, ForServiceID: message.ServiceID,
MessageType: 1, MessageType: 1,
@ -142,7 +142,7 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
_, err = conn.Exec("CREATE SCHEMA IF NOT EXISTS " + message.ServiceID.String()) _, err = conn.Exec("CREATE SCHEMA IF NOT EXISTS " + message.ServiceID.String())
if err != nil { if err != nil {
// Report an error // Report an error
activeServices[message.ServiceID].Inbox <- library.InterServiceMessage{ services[message.ServiceID].Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
ForServiceID: message.ServiceID, ForServiceID: message.ServiceID,
MessageType: 1, MessageType: 1,
@ -154,7 +154,7 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
pluginConn, err := sql.Open("postgres", config.Database.ConnectionString+" dbname="+message.ServiceID.String()) pluginConn, err := sql.Open("postgres", config.Database.ConnectionString+" dbname="+message.ServiceID.String())
if err != nil { if err != nil {
// Report an error // Report an error
activeServices[message.ServiceID].Inbox <- library.InterServiceMessage{ services[message.ServiceID].Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
ForServiceID: message.ServiceID, ForServiceID: message.ServiceID,
MessageType: 1, MessageType: 1,
@ -166,7 +166,7 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
_, err = pluginConn.Exec("SET search_path TO " + message.ServiceID.String()) _, err = pluginConn.Exec("SET search_path TO " + message.ServiceID.String())
if err != nil { if err != nil {
// Report an error // Report an error
activeServices[message.ServiceID].Inbox <- library.InterServiceMessage{ services[message.ServiceID].Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
ForServiceID: message.ServiceID, ForServiceID: message.ServiceID,
MessageType: 1, MessageType: 1,
@ -175,7 +175,7 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
} }
} else { } else {
// Report a successful activation // Report a successful activation
activeServices[message.ServiceID].Inbox <- library.InterServiceMessage{ services[message.ServiceID].Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
ForServiceID: message.ServiceID, ForServiceID: message.ServiceID,
MessageType: 2, MessageType: 2,
@ -189,7 +189,7 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
} }
} else { } else {
// Report an error // Report an error
activeServices[message.ServiceID].Inbox <- library.InterServiceMessage{ services[message.ServiceID].Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
ForServiceID: message.ServiceID, ForServiceID: message.ServiceID,
MessageType: 1, MessageType: 1,
@ -205,30 +205,30 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
switch message.MessageType { switch message.MessageType {
case 0: case 0:
// Log message // Log message
slog.Info(service.Name + " says: " + message.Message.(string)) slog.Info(service.ServiceMetadata.Name + " says: " + message.Message.(string))
case 1: case 1:
// Warn message // Warn message
slog.Warn(service.Name + " warns: " + message.Message.(string)) slog.Warn(service.ServiceMetadata.Name + " warns: " + message.Message.(string))
case 2: case 2:
// Error message // Error message
slog.Error(service.Name + " complains: " + message.Message.(string)) slog.Error(service.ServiceMetadata.Name + " complains: " + message.Message.(string))
case 3: case 3:
// Fatal message // Fatal message
slog.Error(service.Name + "'s dying wish: " + message.Message.(string)) slog.Error(service.ServiceMetadata.Name + "'s dying wish: " + message.Message.(string))
os.Exit(1) os.Exit(1)
} }
} }
} else if message.ForServiceID == uuid.MustParse("00000000-0000-0000-0000-000000000003") { } else if message.ForServiceID == uuid.MustParse("00000000-0000-0000-0000-000000000003") {
// We need to check if the service is allowed to access the Blob Storage service // We need to check if the service is allowed to access the Blob Storage service
serviceMetadata, ok := services[message.ServiceID] serviceMetadata, ok := services[message.ServiceID]
if ok && serviceMetadata.Permissions.BlobStorage { if ok && serviceMetadata.ServiceMetadata.Permissions.BlobStorage {
// Send message to Blob Storage service // Send message to Blob Storage service
service, ok := activeServices[uuid.MustParse("00000000-0000-0000-0000-000000000003")] service, ok := services[uuid.MustParse("00000000-0000-0000-0000-000000000003")]
if ok && service.ActivationConfirmed { if ok && service.ActivationConfirmed {
service.Inbox <- message service.Inbox <- message
} else if !ok { } else if !ok {
// Send error message // Send error message
service, ok := activeServices[message.ServiceID] service, ok := services[message.ServiceID]
if ok { if ok {
service.Inbox <- library.InterServiceMessage{ service.Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
@ -244,7 +244,7 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
} }
} else { } else {
// Send error message // Send error message
service, ok := activeServices[message.ServiceID] service, ok := services[message.ServiceID]
if ok { if ok {
service.Inbox <- library.InterServiceMessage{ service.Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
@ -261,7 +261,7 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
} }
} else { } else {
// Send error message // Send error message
service, ok := activeServices[message.ServiceID] service, ok := services[message.ServiceID]
if ok { if ok {
service.Inbox <- library.InterServiceMessage{ service.Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
@ -273,21 +273,20 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
} else { } else {
// This should never happen // This should never happen
slog.Error("Bit flip error: Impossible service ID. Move away from radiation or use ECC memory.") slog.Error("Bit flip error: Impossible service ID. Move away from radiation or use ECC memory.")
fmt.Println(message.ServiceID, message.ForServiceID)
os.Exit(1) os.Exit(1)
} }
} }
} else if message.ForServiceID == uuid.MustParse("00000000-0000-0000-0000-000000000004") { } else if message.ForServiceID == uuid.MustParse("00000000-0000-0000-0000-000000000004") {
// We need to check if the service is allowed to access the Authentication service // We need to check if the service is allowed to access the Authentication service
serviceMetadata, ok := services[message.ServiceID] serviceMetadata, ok := services[message.ServiceID]
if ok && serviceMetadata.Permissions.Authenticate { if ok && serviceMetadata.ServiceMetadata.Permissions.Authenticate {
// Send message to Authentication service // Send message to Authentication service
service, ok := activeServices[uuid.MustParse("00000000-0000-0000-0000-000000000004")] service, ok := services[uuid.MustParse("00000000-0000-0000-0000-000000000004")]
if ok && service.ActivationConfirmed { if ok && service.ActivationConfirmed {
service.Inbox <- message service.Inbox <- message
} else if !ok { } else if !ok {
// Send error message // Send error message
service, ok := activeServices[message.ServiceID] service, ok := services[message.ServiceID]
if ok { if ok {
service.Inbox <- library.InterServiceMessage{ service.Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
@ -303,7 +302,7 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
} }
} else { } else {
// Send error message // Send error message
service, ok := activeServices[message.ServiceID] service, ok := services[message.ServiceID]
if ok { if ok {
service.Inbox <- library.InterServiceMessage{ service.Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
@ -320,7 +319,7 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
} }
} else { } else {
// Send error message // Send error message
service, ok := activeServices[message.ServiceID] service, ok := services[message.ServiceID]
if ok { if ok {
service.Inbox <- library.InterServiceMessage{ service.Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
@ -337,14 +336,12 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
} }
} else { } else {
serviceMetadata, ok := services[message.ServiceID] serviceMetadata, ok := services[message.ServiceID]
if ok && serviceMetadata.Permissions.InterServiceCommunication { if ok && serviceMetadata.ServiceMetadata.Permissions.InterServiceCommunication {
// Send message to specific service // Send message to specific service
service, ok := activeServices[message.ForServiceID] service, ok := services[message.ForServiceID]
if ok && service.ActivationConfirmed { if !ok {
service.Inbox <- message
} else if !ok {
// Send error message // Send error message
service, ok := activeServices[message.ServiceID] service, ok := services[message.ServiceID]
if ok { if ok {
service.Inbox <- library.InterServiceMessage{ service.Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
@ -358,26 +355,11 @@ func processInterServiceMessage(channel chan library.InterServiceMessage, config
slog.Error("Bit flip error: Impossible service ID. Move away from radiation or use ECC memory.") slog.Error("Bit flip error: Impossible service ID. Move away from radiation or use ECC memory.")
os.Exit(1) os.Exit(1)
} }
}
service.Inbox <- message
} else { } else {
// Send error message // Send error message
service, ok := activeServices[message.ServiceID] service, ok := services[message.ServiceID]
if ok {
service.Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
ForServiceID: message.ServiceID,
MessageType: 1,
SentAt: time.Now(),
Message: errors.New("requested service not yet available"),
}
} else {
// This should never happen
slog.Error("Bit flip error: Impossible service ID. Move away from radiation or use ECC memory.")
os.Exit(1)
}
}
} else {
// Send error message
service, ok := activeServices[message.ServiceID]
if ok { if ok {
service.Inbox <- library.InterServiceMessage{ service.Inbox <- library.InterServiceMessage{
ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), ServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"),
@ -434,7 +416,7 @@ func parseConfig(path string) Config {
// Validate the configuration // Validate the configuration
err = validate.Struct(config) err = validate.Struct(config)
if err != nil { if err != nil {
slog.Error(fmt.Sprintf("Invalid configuration: \n%s", err)) slog.Error("Invalid configuration: ", err)
os.Exit(1) os.Exit(1)
} }
@ -543,12 +525,14 @@ func main() {
} }
// Load the service information // Load the service information
serviceInformation, err := servicePlugin.Lookup("ServiceInformation") serviceInformationSymbol, err := servicePlugin.Lookup("ServiceInformation")
if err != nil { if err != nil {
slog.Error("Service lacks necessary information: ", err) slog.Error("Service lacks necessary information: ", err)
os.Exit(1) os.Exit(1)
} }
serviceInformation := *serviceInformationSymbol.(*library.Service)
// Load the main function // Load the main function
main, err := servicePlugin.Lookup("Main") main, err := servicePlugin.Lookup("Main")
if err != nil { if err != nil {
@ -556,54 +540,50 @@ func main() {
os.Exit(1) os.Exit(1)
} }
// Add the service to the services map
lock.Lock()
services[serviceInformation.(*library.Service).ServiceID] = *serviceInformation.(*library.Service)
lock.Unlock()
// Initialize the service // Initialize the service
var inbox = make(chan library.InterServiceMessage) var inbox = make(chan library.InterServiceMessage)
lock.Lock() lock.Lock()
activeServices[serviceInformation.(*library.Service).ServiceID] = ActiveService{ services[serviceInformation.ServiceID] = Service{
ServiceID: serviceInformation.(*library.Service).ServiceID, ServiceID: serviceInformation.ServiceID,
Inbox: inbox, Inbox: inbox,
ActivationConfirmed: false, ActivationConfirmed: false,
ServiceMetadata: serviceInformation,
} }
lock.Unlock() lock.Unlock()
// Check if they want a subdomain // Check if they want a subdomain
var finalRouter *chi.Mux var finalRouter *chi.Mux
serviceConfig, ok := config.Services[strings.ToLower(serviceInformation.(*library.Service).Name)] serviceConfig, ok := config.Services[strings.ToLower(serviceInformation.Name)]
if !ok { if !ok {
slog.Error("Service configuration not found for service: ", serviceInformation.(*library.Service).Name) slog.Error("Service configuration not found for service: ", serviceInformation.Name)
os.Exit(1) os.Exit(1)
} }
if serviceConfig.(map[string]interface{})["subdomain"] != nil { if serviceConfig.(map[string]interface{})["subdomain"] != nil {
subdomainRouter := chi.NewRouter() subdomainRouter := chi.NewRouter()
router.Use(middleware.RouteHeaders(). router.Use(middleware.RouteHeaders().
Route("Host", config.Services[strings.ToLower(serviceInformation.(*library.Service).Name)].(map[string]interface{})["subdomain"].(string), middleware.New(subdomainRouter)). Route("Host", config.Services[strings.ToLower(serviceInformation.Name)].(map[string]interface{})["subdomain"].(string), middleware.New(subdomainRouter)).
Handler) Handler)
finalRouter = subdomainRouter finalRouter = subdomainRouter
} else { } else {
finalRouter = router finalRouter = router
} }
slog.Info("Activating service " + serviceInformation.(*library.Service).Name + " with ID " + serviceInformation.(*library.Service).ServiceID.String()) slog.Info("Activating service " + serviceInformation.Name + " with ID " + serviceInformation.ServiceID.String())
// Check if they want a resource directory // Check if they want a resource directory
if serviceInformation.(*library.Service).Permissions.Resources { if serviceInformation.Permissions.Resources {
main.(func(library.ServiceInitializationInformation))(library.ServiceInitializationInformation{ main.(func(library.ServiceInitializationInformation))(library.ServiceInitializationInformation{
Domain: serviceInformation.(*library.Service).Name, Domain: serviceInformation.Name,
Configuration: config.Services[strings.ToLower(serviceInformation.(*library.Service).Name)].(map[string]interface{}), Configuration: config.Services[strings.ToLower(serviceInformation.Name)].(map[string]interface{}),
Outbox: globalOutbox, Outbox: globalOutbox,
Inbox: inbox, Inbox: inbox,
ResourceDir: os.DirFS(filepath.Join(config.Global.ResourceDirectory, serviceInformation.(*library.Service).ServiceID.String())), ResourceDir: os.DirFS(filepath.Join(config.Global.ResourceDirectory, serviceInformation.ServiceID.String())),
Router: finalRouter, Router: finalRouter,
}) })
} else { } else {
main.(func(library.ServiceInitializationInformation))(library.ServiceInitializationInformation{ main.(func(library.ServiceInitializationInformation))(library.ServiceInitializationInformation{
Domain: serviceInformation.(*library.Service).Name, Domain: serviceInformation.Name,
Configuration: config.Services[strings.ToLower(serviceInformation.(*library.Service).Name)].(map[string]interface{}), Configuration: config.Services[strings.ToLower(serviceInformation.Name)].(map[string]interface{}),
Outbox: globalOutbox, Outbox: globalOutbox,
Inbox: inbox, Inbox: inbox,
Router: finalRouter, Router: finalRouter,
@ -611,11 +591,11 @@ func main() {
} }
// Log the service activation // Log the service activation
slog.Info("Service " + serviceInformation.(*library.Service).Name + " activated with ID " + serviceInformation.(*library.Service).ServiceID.String()) slog.Info("Service " + serviceInformation.Name + " activated with ID " + serviceInformation.ServiceID.String())
} }
// Start the server // Start the server
slog.Info(fmt.Sprintf("Starting server on %s:%s", config.Global.IP, config.Global.Port)) slog.Info("Starting server on " + config.Global.IP + ":" + config.Global.Port)
err = http.ListenAndServe(config.Global.IP+":"+config.Global.Port, router) err = http.ListenAndServe(config.Global.IP+":"+config.Global.Port, router)
if err != nil { if err != nil {
slog.Error("Error starting server: ", err) slog.Error("Error starting server: ", err)