implement openrpc and http interface generation for actor
This commit is contained in:
22
lib/baobab/generator/generate_interface.v
Normal file
22
lib/baobab/generator/generate_interface.v
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
module generator
|
||||||
|
|
||||||
|
import freeflowuniverse.herolib.core.code { Folder, IFile, VFile, CodeItem, File, Function, Import, Module, Struct, CustomCode }
|
||||||
|
import freeflowuniverse.herolib.core.texttools
|
||||||
|
import freeflowuniverse.herolib.schemas.openrpc
|
||||||
|
import freeflowuniverse.herolib.baobab.specification {ActorMethod, ActorSpecification}
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
|
fn generate_openrpc_interface_file() !VFile {
|
||||||
|
return VFile {
|
||||||
|
name: 'interface_openrpc'
|
||||||
|
items: [CustomCode{$tmpl('./templates/interface_openrpc.v.template')}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_http_interface_file() !VFile {
|
||||||
|
return VFile {
|
||||||
|
name: 'interface_http'
|
||||||
|
items: [CustomCode{$tmpl('./templates/interface_http.v.template')}]
|
||||||
|
}
|
||||||
|
}
|
||||||
33
lib/baobab/generator/templates/actor.v copy.template
Normal file
33
lib/baobab/generator/templates/actor.v copy.template
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import os
|
||||||
|
import freeflowuniverse.herolib.baobab.actor {IActor, RunParams}
|
||||||
|
import freeflowuniverse.herolib.schemas.openapi
|
||||||
|
|
||||||
|
const openapi_spec_path = '@{dollar}{os.dir(@@FILE)}/specs/openapi.json'
|
||||||
|
const openapi_spec_json = os.read_file(openapi_spec_path) or { panic(err) }
|
||||||
|
const openapi_specification = openapi.json_decode(openapi_spec_json)!
|
||||||
|
|
||||||
|
struct @{actor_name_pascal}Actor {
|
||||||
|
actor.Actor
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new() !@{actor_name_pascal}Actor {
|
||||||
|
return @{actor_name_pascal}Actor {
|
||||||
|
actor.new('@{actor_name_snake}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run() ! {
|
||||||
|
mut a_ := new()!
|
||||||
|
mut a := IActor(a_)
|
||||||
|
a.run()!
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_server(params RunParams) ! {
|
||||||
|
mut a := new()!
|
||||||
|
mut server := actor.new_server(
|
||||||
|
redis_url: 'localhost:6379'
|
||||||
|
redis_queue: a.name
|
||||||
|
openapi_spec: openapi_specification
|
||||||
|
)!
|
||||||
|
server.run(params)
|
||||||
|
}
|
||||||
17
lib/baobab/generator/templates/interface_http.v.template
Normal file
17
lib/baobab/generator/templates/interface_http.v.template
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import freeflowuniverse.herolib.schemas.openapi { OpenAPI }
|
||||||
|
import freeflowuniverse.herolib.baobab.actor {Client, ClientConfig}
|
||||||
|
import freeflowuniverse.herolib.schemas.openrpc { OpenRPC }
|
||||||
|
import freeflowuniverse.herolib.baobab.interfaces { HTTPServer, Context }
|
||||||
|
import veb
|
||||||
|
|
||||||
|
pub fn new_http_server() !&HTTPServer {
|
||||||
|
mut s := interfaces.new_http_server()!
|
||||||
|
mut openrpc_controller := new_openrpc_http_controller()!
|
||||||
|
s.register_controller[openrpc.HTTPController, Context]('/openrpc', mut openrpc_controller)!
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_http_server() ! {
|
||||||
|
mut server := new_http_server()!
|
||||||
|
veb.run[HTTPServer, Context](mut server, 8082)
|
||||||
|
}
|
||||||
20
lib/baobab/generator/templates/interface_openrpc.v.template
Normal file
20
lib/baobab/generator/templates/interface_openrpc.v.template
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import freeflowuniverse.herolib.baobab.interfaces
|
||||||
|
import freeflowuniverse.herolib.schemas.openrpc
|
||||||
|
|
||||||
|
const specification_path = os.join_path(os.dir(@@FILE), '/testdata/openrpc.json')
|
||||||
|
const specification = openrpc.new(path: specification_path)!
|
||||||
|
|
||||||
|
pub fn new_openrpc_interface() !&interfaces.OpenRPCInterface {
|
||||||
|
// create OpenRPC Handler with actor's client
|
||||||
|
client := new_client()!
|
||||||
|
return interfaces.new_openrpc_interface(client.Client)
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates HTTP controller with the actor's OpenRPC Handler
|
||||||
|
// and OpenRPC Specification
|
||||||
|
pub fn new_openrpc_http_controller() !&openrpc.HTTPController {
|
||||||
|
return openrpc.new_http_controller(
|
||||||
|
specification: specification
|
||||||
|
handler: new_openrpc_interface()!
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,77 +1,77 @@
|
|||||||
module actor
|
module interfaces
|
||||||
|
|
||||||
import veb
|
import veb
|
||||||
import freeflowuniverse.herolib.schemas.openapi { Context, Controller, OpenAPI, Request, Response }
|
import freeflowuniverse.herolib.schemas.openapi { Context, Controller, OpenAPI, Request, Response }
|
||||||
import freeflowuniverse.herolib.baobab.action { ProcedureError }
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
import x.json2
|
import x.json2
|
||||||
import net.http
|
import net.http
|
||||||
import freeflowuniverse.herolib.schemas.jsonschema
|
import freeflowuniverse.herolib.schemas.jsonschema
|
||||||
import freeflowuniverse.herolib.clients.redisclient
|
import freeflowuniverse.herolib.core.redisclient
|
||||||
|
|
||||||
pub struct OpenAPIProxy {
|
// pub struct OpenAPIProxy {
|
||||||
client Client
|
// pub:
|
||||||
specification OpenAPI
|
// client Client
|
||||||
}
|
// specification OpenAPI
|
||||||
|
// }
|
||||||
|
|
||||||
// creates and OpenAPI Proxy Controller
|
// // creates and OpenAPI Proxy Controller
|
||||||
pub fn new_openapi_proxy(proxy OpenAPIProxy) OpenAPIProxy {
|
// pub fn new_openapi_proxy(proxy OpenAPIProxy) OpenAPIProxy {
|
||||||
return proxy
|
// return proxy
|
||||||
}
|
// }
|
||||||
|
|
||||||
// creates and OpenAPI Proxy Controller
|
// // creates and OpenAPI Proxy Controller
|
||||||
pub fn (proxy OpenAPIProxy) controller() &Controller {
|
// pub fn (proxy OpenAPIProxy) controller() &Controller {
|
||||||
// Initialize the server
|
// // Initialize the server
|
||||||
mut controller := &Controller{
|
// mut controller := &Controller{
|
||||||
specification: proxy.specification
|
// specification: proxy.specification
|
||||||
handler: Handler{
|
// handler: Handler{
|
||||||
client: proxy.client
|
// client: proxy.client
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return controller
|
// return controller
|
||||||
}
|
// }
|
||||||
|
|
||||||
@[params]
|
// @[params]
|
||||||
pub struct RunParams {
|
// pub struct RunParams {
|
||||||
pub:
|
// pub:
|
||||||
port int = 8080
|
// port int = 8080
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn (proxy OpenAPIProxy) run(params RunParams) {
|
// fn (proxy OpenAPIProxy) run(params RunParams) {
|
||||||
mut controller := proxy.controller()
|
// mut controller := proxy.controller()
|
||||||
veb.run[Controller, Context](mut controller, params.port)
|
// veb.run[Controller, Context](mut controller, params.port)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub struct Handler {
|
// pub struct Handler {
|
||||||
pub mut:
|
// pub mut:
|
||||||
client Client
|
// client Client
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn (mut handler Handler) handle(request Request) !Response {
|
// fn (mut handler Handler) handle(request Request) !Response {
|
||||||
// Convert incoming OpenAPI request to a procedure call
|
// // Convert incoming OpenAPI request to a procedure call
|
||||||
call := rpc.openapi_request_to_procedure_call(request)
|
// call := rpc.openapi_request_to_procedure_call(request)
|
||||||
|
|
||||||
// Process the procedure call
|
// // Process the procedure call
|
||||||
procedure_response := handler.client.dialogue(call, Params{
|
// procedure_response := handler.client.dialogue(call, Params{
|
||||||
timeout: 30 // Set timeout in seconds
|
// timeout: 30 // Set timeout in seconds
|
||||||
}) or {
|
// }) or {
|
||||||
// Handle ProcedureError
|
// // Handle ProcedureError
|
||||||
if err is ProcedureError {
|
// if err is ProcedureError {
|
||||||
return Response{
|
// return Response{
|
||||||
status: http.status_from_int(err.code()) // Map ProcedureError reason to HTTP status code
|
// status: http.status_from_int(err.code()) // Map ProcedureError reason to HTTP status code
|
||||||
body: json.encode({
|
// body: json.encode({
|
||||||
'error': err.msg()
|
// 'error': err.msg()
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return error('Unexpected error: ${err}')
|
// return error('Unexpected error: ${err}')
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Convert returned procedure response to OpenAPI response
|
// // Convert returned procedure response to OpenAPI response
|
||||||
return Response{
|
// return Response{
|
||||||
status: http.Status.ok // Assuming success if no error
|
// status: http.Status.ok // Assuming success if no error
|
||||||
body: procedure_response.result
|
// body: procedure_response.result
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
module interfaces
|
module interfaces
|
||||||
|
|
||||||
|
import freeflowuniverse.herolib.baobab.actor {Client}
|
||||||
|
import freeflowuniverse.herolib.schemas.jsonrpc
|
||||||
|
import freeflowuniverse.herolib.baobab.actions
|
||||||
|
|
||||||
// handler for test echoes JSONRPC Request as JSONRPC Response
|
// handler for test echoes JSONRPC Request as JSONRPC Response
|
||||||
fn handler(request jsonrpc.Request) !jsonrpc.Response {
|
fn handler(request jsonrpc.Request) !jsonrpc.Response {
|
||||||
return jsonrpc.Response {
|
return jsonrpc.Response {
|
||||||
|
|||||||
43
lib/baobab/interfaces/server_http.v
Normal file
43
lib/baobab/interfaces/server_http.v
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
module interfaces
|
||||||
|
|
||||||
|
import freeflowuniverse.herolib.schemas.openapi { OpenAPI }
|
||||||
|
import freeflowuniverse.herolib.baobab.actor {Client, ClientConfig}
|
||||||
|
import freeflowuniverse.herolib.schemas.openrpc { OpenRPC }
|
||||||
|
import veb
|
||||||
|
|
||||||
|
pub struct HTTPServer {
|
||||||
|
veb.Controller
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Context {
|
||||||
|
veb.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct HTTPServerConfig {
|
||||||
|
ClientConfig
|
||||||
|
pub:
|
||||||
|
openapi_specification OpenAPI
|
||||||
|
openrpc_specification OpenRPC
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_http_server() !&HTTPServer {
|
||||||
|
mut s := &HTTPServer{}
|
||||||
|
|
||||||
|
// client := actor.new_client(cfg.ClientConfig)!
|
||||||
|
|
||||||
|
// openapi_proxy := new_openapi_proxy(
|
||||||
|
// client: new_client(cfg.ClientConfig)!
|
||||||
|
// specification: cfg.openapi_spec
|
||||||
|
// )
|
||||||
|
|
||||||
|
// mut openrpc_controller := openrpc.new_http_controller(
|
||||||
|
// specification: cfg.openrpc_specification
|
||||||
|
// handler: new_openrpc_interface(client)
|
||||||
|
// )
|
||||||
|
// s.register_controller[openrpc.HTTPController, Context]('/openrpc', mut openrpc_controller)!
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut server HTTPServer) run() {
|
||||||
|
veb.run[HTTPServer, Context](mut server, 8082)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user