139 lines
3.7 KiB
GLSL
Executable File
139 lines
3.7 KiB
GLSL
Executable File
#!/usr/bin/env -S v -w -n -enable-globals run
|
|
|
|
import os
|
|
import time
|
|
import veb
|
|
import json
|
|
import x.json2 { Any }
|
|
import net.http
|
|
import freeflowuniverse.herolib.data.jsonschema { Schema }
|
|
import freeflowuniverse.herolib.web.openapi { Context, Request, Response, Server }
|
|
import freeflowuniverse.herolib.hero.processor { ProcedureCall, ProcessParams, Processor }
|
|
import freeflowuniverse.herolib.core.redisclient
|
|
|
|
const spec_path = '${os.dir(@FILE)}/data/openapi.json'
|
|
const spec_json = os.read_file(spec_path) or { panic(err) }
|
|
|
|
// Main function to start the server
|
|
fn main() {
|
|
// Initialize the Redis client and RPC mechanism
|
|
mut redis := redisclient.new('localhost:6379')!
|
|
mut rpc := redis.rpc_get('procedure_queue')
|
|
|
|
// Initialize the server
|
|
mut server := &Server{
|
|
specification: openapi.json_decode(spec_json)!
|
|
handler: Handler{
|
|
processor: Processor{
|
|
rpc: rpc
|
|
}
|
|
}
|
|
}
|
|
|
|
// Start the server
|
|
veb.run[Server, Context](mut server, 8080)
|
|
}
|
|
|
|
pub struct Handler {
|
|
mut:
|
|
processor Processor
|
|
}
|
|
|
|
fn (mut handler Handler) handle(request Request) !Response {
|
|
// Convert incoming OpenAPI request to a procedure call
|
|
mut params := []string{}
|
|
|
|
if request.arguments.len > 0 {
|
|
params = request.arguments.values().map(it.str()).clone()
|
|
}
|
|
|
|
if request.body != '' {
|
|
params << request.body
|
|
}
|
|
|
|
if request.parameters.len != 0 {
|
|
mut param_map := map[string]Any{} // Store parameters with correct types
|
|
|
|
for param_name, param_value in request.parameters {
|
|
operation_param := request.operation.parameters.filter(it.name == param_name)
|
|
if operation_param.len > 0 {
|
|
param_schema := operation_param[0].schema as Schema
|
|
param_type := param_schema.typ
|
|
param_format := param_schema.format
|
|
|
|
// Convert parameter value to corresponding type
|
|
match param_type {
|
|
'integer' {
|
|
match param_format {
|
|
'int32' {
|
|
param_map[param_name] = param_value.int() // Convert to int
|
|
}
|
|
'int64' {
|
|
param_map[param_name] = param_value.i64() // Convert to i64
|
|
}
|
|
else {
|
|
param_map[param_name] = param_value.int() // Default to int
|
|
}
|
|
}
|
|
}
|
|
'string' {
|
|
param_map[param_name] = param_value // Already a string
|
|
}
|
|
'boolean' {
|
|
param_map[param_name] = param_value.bool() // Convert to bool
|
|
}
|
|
'number' {
|
|
match param_format {
|
|
'float' {
|
|
param_map[param_name] = param_value.f32() // Convert to float
|
|
}
|
|
'double' {
|
|
param_map[param_name] = param_value.f64() // Convert to double
|
|
}
|
|
else {
|
|
param_map[param_name] = param_value.f64() // Default to double
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
param_map[param_name] = param_value // Leave as string for unknown types
|
|
}
|
|
}
|
|
} else {
|
|
// If the parameter is not defined in the OpenAPI operation, skip or log it
|
|
println('Unknown parameter: ${param_name}')
|
|
}
|
|
}
|
|
|
|
// Encode the parameter map to JSON if needed
|
|
params << json.encode(param_map.str())
|
|
}
|
|
|
|
call := ProcedureCall{
|
|
method: request.operation.operation_id
|
|
params: '[${params.join(',')}]' // Keep as a string since ProcedureCall expects a string
|
|
}
|
|
|
|
// Process the procedure call
|
|
procedure_response := handler.processor.process(call, ProcessParams{
|
|
timeout: 30 // Set timeout in seconds
|
|
}) or {
|
|
// Handle ProcedureError
|
|
if err is processor.ProcedureError {
|
|
return Response{
|
|
status: http.status_from_int(err.code()) // Map ProcedureError reason to HTTP status code
|
|
body: json.encode({
|
|
'error': err.msg()
|
|
})
|
|
}
|
|
}
|
|
return error('Unexpected error: ${err}')
|
|
}
|
|
|
|
// Convert returned procedure response to OpenAPI response
|
|
return Response{
|
|
status: http.Status.ok // Assuming success if no error
|
|
body: procedure_response.result
|
|
}
|
|
}
|