├── CNAME ├── codegen ├── tester │ ├── resources │ │ ├── 3.txt │ │ ├── static │ │ │ ├── 1.txt │ │ │ └── sub │ │ │ │ └── 2.txt │ │ ├── embed-gen.go │ │ └── text.yaml │ ├── CLAUDE.md │ ├── AGENTS.md │ ├── doc.go │ ├── testerapi │ │ ├── xycoord.go │ │ └── xyline.go │ ├── version-gen.go │ └── version-gen_test.go ├── bundle │ ├── CLAUDE.md │ ├── service │ │ ├── CLAUDE.md │ │ ├── resources │ │ │ └── embed-gen.txt │ │ ├── api │ │ │ ├── type.txt │ │ │ └── imports-gen.txt │ │ ├── AGENTS.md │ │ ├── version-gen.txt │ │ ├── service_test.txt │ │ ├── version-gen_test.txt │ │ ├── service.txt │ │ ├── intermediate │ │ │ ├── intermediate-gen.configs.txt │ │ │ └── intermediate-gen.functions.txt │ │ └── service-gen.txt │ ├── main │ │ ├── config.yaml │ │ ├── env.yaml │ │ └── main.go_ │ ├── AGENTS.md │ ├── .vscode │ │ └── launch.json │ └── .claude │ │ └── skills │ │ └── microbus │ │ └── rm-any │ │ └── SKILL.md ├── spec │ ├── type.go │ ├── version.go │ ├── common.go │ └── general_test.go └── main.go ├── connector ├── testdata │ ├── res.html │ ├── res.txt │ └── text.yaml ├── doc.go └── control_test.go ├── env ├── testdata │ └── env.yaml └── env_test.go ├── examples ├── browser │ ├── CLAUDE.md │ ├── resources │ │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── version-gen.go │ └── version-gen_test.go ├── hello │ ├── CLAUDE.md │ ├── resources │ │ ├── bus.png │ │ ├── embed-gen.go │ │ └── text.yaml │ ├── AGENTS.md │ ├── doc.go │ ├── version-gen.go │ └── version-gen_test.go ├── login │ ├── CLAUDE.md │ ├── resources │ │ ├── embed-gen.go │ │ ├── admin-only.html │ │ └── manager-only.html │ ├── AGENTS.md │ ├── doc.go │ ├── version-gen.go │ └── version-gen_test.go ├── calculator │ ├── CLAUDE.md │ ├── resources │ │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── calculatorapi │ │ └── point.go │ ├── version-gen.go │ └── version-gen_test.go ├── directory │ ├── CLAUDE.md │ ├── resources │ │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── directoryapi │ │ └── personkey.go │ ├── version-gen.go │ └── version-gen_test.go ├── eventsink │ ├── CLAUDE.md │ ├── resources │ │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── version-gen.go │ └── version-gen_test.go ├── eventsource │ ├── CLAUDE.md │ ├── resources │ │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── version-gen.go │ └── version-gen_test.go ├── helloworld │ ├── CLAUDE.md │ ├── resources │ │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── version-gen.go │ └── version-gen_test.go └── messaging │ ├── CLAUDE.md │ ├── resources │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── version-gen.go │ └── version-gen_test.go ├── coreservices ├── control │ ├── CLAUDE.md │ ├── resources │ │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── version-gen.go │ └── version-gen_test.go ├── metrics │ ├── CLAUDE.md │ ├── resources │ │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── version-gen.go │ └── version-gen_test.go ├── configurator │ ├── CLAUDE.md │ ├── resources │ │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── version-gen.go │ └── version-gen_test.go ├── httpegress │ ├── CLAUDE.md │ ├── resources │ │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── version-gen.go │ └── version-gen_test.go ├── httpingress │ ├── CLAUDE.md │ ├── middleware │ │ ├── defaultfavicon.ico │ │ ├── noop.go │ │ ├── cachecontrol.go │ │ ├── group.go │ │ ├── blockedpaths.go │ │ ├── charsetutf8.go │ │ ├── secureredirect.go │ │ ├── internalheaders.go │ │ ├── xforwarded.go │ │ └── defaultfavicon.go │ ├── resources │ │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── version-gen.go │ ├── logwriter.go │ └── version-gen_test.go ├── openapiportal │ ├── CLAUDE.md │ ├── resources │ │ ├── embed-gen.go │ │ └── list.html │ ├── AGENTS.md │ ├── doc.go │ ├── version-gen.go │ └── version-gen_test.go ├── smtpingress │ ├── CLAUDE.md │ ├── resources │ │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── smtpingressapi │ │ └── email.go │ ├── version-gen.go │ └── version-gen_test.go └── tokenissuer │ ├── CLAUDE.md │ ├── resources │ └── embed-gen.go │ ├── AGENTS.md │ ├── doc.go │ ├── tokenissuerapi │ └── mapclaims.go │ ├── version-gen.go │ └── version-gen_test.go ├── docs ├── blocks │ ├── metrics-1.png │ ├── distrib-tracing-1.png │ ├── distrib-tracing-2.png │ ├── i18n.md │ ├── embedded-res.md │ ├── graceful-shutdown.md │ ├── lb.md │ ├── logging.md │ ├── connectivity-liveness-test.md │ ├── project-bootstrapping.md │ ├── multiplexed.md │ ├── discovery.md │ └── agents-md.md ├── howto │ ├── quick-start-1.png │ ├── first-microservice-1.png │ ├── self-explore.md │ └── new-project.md ├── structure │ ├── examples-hello-1.png │ ├── examples-directory-1.png │ ├── examples-directory-2.png │ ├── codegen.md │ ├── service.md │ ├── rand.md │ ├── trc.md │ ├── utils.md │ ├── examples-browser.md │ ├── coreservices-openapiportal.md │ ├── env.md │ ├── pub.md │ ├── openapi.md │ ├── coreservices-smtpingress.md │ ├── coreservices-control.md │ ├── sub.md │ ├── coreservices-metrics.md │ ├── dlru.md │ ├── examples-events.md │ ├── examples-helloworld.md │ ├── coreservices.md │ ├── cfg.md │ ├── examples.md │ └── coreservices-tokenissuer.md └── tech │ ├── json-vs-protobuf.md │ ├── out-of-scope.md │ ├── local-dev.md │ ├── short-circuit.md │ ├── deployments.md │ ├── encapsulation.md │ └── nats-connection.md ├── CLAUDE.md ├── AGENTS.md ├── .gitignore ├── doc.go ├── httpx ├── doc.go ├── bodyreader_test.go └── qargs_test.go ├── .vscode └── launch.json ├── utils ├── doc.go ├── sourcecodehash_test.go └── panic.go ├── dlru └── doc.go ├── mem └── doc.go ├── transport ├── doc.go ├── msg.go └── subscription.go ├── rand ├── doc.go └── rand_test.go ├── trc └── doc.go ├── pub ├── doc.go ├── response_test.go └── response.go ├── sub └── doc.go ├── application └── doc.go ├── cfg ├── doc.go └── config.go ├── errors ├── doc.go └── stackframe.go ├── copyright.go ├── .github ├── FUNDING.yml └── workflows │ └── test.yaml ├── main └── config.yaml ├── openapi └── endpoint.go ├── setup ├── grafana │ └── dashboards │ │ └── dashboards.yaml └── microbus.yaml └── .claude └── skills └── microbus └── rm-any └── SKILL.md /CNAME: -------------------------------------------------------------------------------- 1 | docs.microbus.io -------------------------------------------------------------------------------- /codegen/tester/resources/3.txt: -------------------------------------------------------------------------------- 1 | 333 -------------------------------------------------------------------------------- /codegen/tester/resources/static/1.txt: -------------------------------------------------------------------------------- 1 | 111 -------------------------------------------------------------------------------- /codegen/tester/resources/static/sub/2.txt: -------------------------------------------------------------------------------- 1 | 222 -------------------------------------------------------------------------------- /connector/testdata/res.html: -------------------------------------------------------------------------------- 1 | {{ . }} 2 | -------------------------------------------------------------------------------- /connector/testdata/res.txt: -------------------------------------------------------------------------------- 1 | {{ . }} 2 | -------------------------------------------------------------------------------- /env/testdata/env.yaml: -------------------------------------------------------------------------------- 1 | X5981245X: InFile 2 | x5981245x: infile -------------------------------------------------------------------------------- /codegen/bundle/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /examples/browser/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /examples/hello/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /examples/login/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /codegen/bundle/service/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /coreservices/control/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /coreservices/metrics/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /examples/calculator/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /examples/directory/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /examples/eventsink/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /examples/eventsource/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /examples/helloworld/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /examples/messaging/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /coreservices/configurator/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /coreservices/httpegress/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /coreservices/httpingress/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /coreservices/openapiportal/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /coreservices/smtpingress/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /coreservices/tokenissuer/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read `AGENTS.md`. 3 | -------------------------------------------------------------------------------- /codegen/bundle/main/config.yaml: -------------------------------------------------------------------------------- 1 | http.ingress.core: 2 | # Ports: 8080 3 | # TimeBudget: 20s 4 | -------------------------------------------------------------------------------- /connector/testdata/text.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | Hello: 3 | en: Hello 4 | en-AU: G'day 5 | it: Ciao 6 | -------------------------------------------------------------------------------- /docs/blocks/metrics-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microbus-io/fabric/HEAD/docs/blocks/metrics-1.png -------------------------------------------------------------------------------- /docs/howto/quick-start-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microbus-io/fabric/HEAD/docs/howto/quick-start-1.png -------------------------------------------------------------------------------- /examples/hello/resources/bus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microbus-io/fabric/HEAD/examples/hello/resources/bus.png -------------------------------------------------------------------------------- /docs/blocks/distrib-tracing-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microbus-io/fabric/HEAD/docs/blocks/distrib-tracing-1.png -------------------------------------------------------------------------------- /docs/blocks/distrib-tracing-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microbus-io/fabric/HEAD/docs/blocks/distrib-tracing-2.png -------------------------------------------------------------------------------- /docs/howto/first-microservice-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microbus-io/fabric/HEAD/docs/howto/first-microservice-1.png -------------------------------------------------------------------------------- /docs/structure/examples-hello-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microbus-io/fabric/HEAD/docs/structure/examples-hello-1.png -------------------------------------------------------------------------------- /docs/structure/examples-directory-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microbus-io/fabric/HEAD/docs/structure/examples-directory-1.png -------------------------------------------------------------------------------- /docs/structure/examples-directory-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microbus-io/fabric/HEAD/docs/structure/examples-directory-2.png -------------------------------------------------------------------------------- /docs/structure/codegen.md: -------------------------------------------------------------------------------- 1 | # Package `codegen` 2 | 3 | The `codegen` package implements the [code generation tool](../blocks/codegen.md). 4 | -------------------------------------------------------------------------------- /codegen/tester/CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read the instructions in `AGENTS.md` and respect them as if they were an integral part of `CLAUDE.md`. 3 | -------------------------------------------------------------------------------- /coreservices/httpingress/middleware/defaultfavicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microbus-io/fabric/HEAD/coreservices/httpingress/middleware/defaultfavicon.ico -------------------------------------------------------------------------------- /CLAUDE.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: Read the instructions in `AGENTS.md` and respect them as if they were an integral part of `CLAUDE.md`. 3 | 4 | **CRITICAL**: Read `AGENTS.md`. 5 | -------------------------------------------------------------------------------- /codegen/tester/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /examples/hello/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /examples/login/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /docs/structure/service.md: -------------------------------------------------------------------------------- 1 | # Package `service` 2 | 3 | Package `service` defines various interfaces of a microservice. The [`Connector`](connector.md) implements these interfaces. 4 | -------------------------------------------------------------------------------- /examples/browser/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /examples/calculator/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /examples/directory/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /examples/eventsink/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /examples/helloworld/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /examples/messaging/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /codegen/bundle/service/resources/embed-gen.txt: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /coreservices/control/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /coreservices/httpegress/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /coreservices/httpingress/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /coreservices/metrics/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /coreservices/smtpingress/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /coreservices/tokenissuer/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /examples/eventsource/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /coreservices/configurator/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /coreservices/openapiportal/resources/embed-gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package resources 4 | 5 | import "embed" 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /docs/structure/rand.md: -------------------------------------------------------------------------------- 1 | # Package `rand` 2 | 3 | The `rand` package is a utility that combines `crypto.rand` and `math.rand` for more secure random number generation with reduced performance impact. 4 | -------------------------------------------------------------------------------- /AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: This project follows a microservices architecture based on the Microbus framework. Run `go generate` at the root of the project, then read `AGENTS-MICROBUS.md` and follow the patterns and conventions of the Microbus framework. 3 | -------------------------------------------------------------------------------- /codegen/bundle/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: This project follows a microservices architecture based on the Microbus framework. Run `go generate` at the root of the project, then read `AGENTS-MICROBUS.md` and follow the patterns and conventions of the Microbus framework. 3 | -------------------------------------------------------------------------------- /codegen/bundle/service/api/type.txt: -------------------------------------------------------------------------------- 1 | package {{ .PackagePathSuffix }}api 2 | 3 | // {{ .Name }} 4 | type {{ .Name }} struct { 5 | // TO{{/**/}}DO: define fields of type {{ .Name }} 6 | // Field int `json:"field,omitzero" jsonschema:"description=Number,example=7,default=0,required=true"` 7 | } 8 | -------------------------------------------------------------------------------- /examples/hello/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /examples/login/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /coreservices/control/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /coreservices/metrics/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /examples/browser/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /examples/calculator/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /examples/directory/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /examples/eventsink/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /examples/eventsource/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /examples/helloworld/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /examples/messaging/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /codegen/bundle/service/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /coreservices/configurator/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /coreservices/httpegress/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /coreservices/httpingress/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /coreservices/smtpingress/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /coreservices/tokenissuer/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /coreservices/openapiportal/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file only apply when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` file located at the root of the project. If you haven't yet read the global `AGENTS.md` file, do so now. 3 | -------------------------------------------------------------------------------- /codegen/bundle/service/version-gen.txt: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package {{ .PackagePathSuffix }} 4 | 5 | const Version = {{ .Version }} 6 | const SourceCodeSHA256 = "{{ .SHA256 }}" 7 | const Timestamp = "{{ .Timestamp }}" 8 | 9 | /* { 10 | "ver": {{ .Version }}, 11 | "sha256": "{{ .SHA256 }}", 12 | "ts": "{{ .Timestamp }}" 13 | } */ 14 | -------------------------------------------------------------------------------- /docs/structure/trc.md: -------------------------------------------------------------------------------- 1 | # Package `trc` 2 | 3 | The `trc` package supports distributed tracing with OpenTelemetry. It defines various `Option`s that can be applied to the tracing span using the options pattern. This pattern is used in Go for expressing optional arguments. 4 | 5 | For example: 6 | 7 | ```go 8 | con.StartSpan(ctx, "Job", trc.String("name", "my job")) 9 | ``` 10 | -------------------------------------------------------------------------------- /codegen/tester/AGENTS.md: -------------------------------------------------------------------------------- 1 | 2 | **CRITICAL**: The instructions in this `AGENTS.md` file, if present, should only be applied when working on the microservice in the same directory, and should take precedence over instructions in the global `AGENTS.md` and `AGENTS-MICROBUS.md` files located at the root of the project. If you have not already read the global `AGENTS.md` or `AGENTS-MICROBUS.md` files, do so now. 3 | -------------------------------------------------------------------------------- /docs/structure/utils.md: -------------------------------------------------------------------------------- 1 | # Package `utils` 2 | 3 | Package `utils` includes various independent utilities. 4 | 5 | `SourceCodeSHA256` reads the content of a source code directory and generates a SHA256 of its relevant content. It is used by the code generator for change detection and automatic versioning. 6 | 7 | `SyncMap` is a thin wrapper over a subset of the operations of the standard `sync.Map`. It introduces generics to make these more type-safe. 8 | -------------------------------------------------------------------------------- /docs/structure/examples-browser.md: -------------------------------------------------------------------------------- 1 | # Package `examples/browser` 2 | 3 | The `browser.example` microservice implement a single endpoints, `/browse` that renders an HTML page with a form that takes in a URL and fetches the source code of the page. This example demonstrates how to use the [HTTP egress core microservice](../structure/coreservices-httpegress.md) as well as how to mock it in tests. 4 | 5 | Visit http://localhost:8080/browser.example/browse to play around with the simple UI. 6 | -------------------------------------------------------------------------------- /docs/structure/coreservices-openapiportal.md: -------------------------------------------------------------------------------- 1 | # Package `coreservices/openapiportal` 2 | 3 | All `Microbus` microservices [produce OpenAPI documents](../blocks/openapi.md) describing their endpoints. 4 | The OpenAPI portal core microservice renders an HTML portal page that lists all microservices that have an OpenAPI endpoint on the same port as the request. For example, the portal page at the internal `Microbus` address of `https://openapi:443` finds all microservices with open endpoints on port `:443`. 5 | -------------------------------------------------------------------------------- /docs/structure/env.md: -------------------------------------------------------------------------------- 1 | # Package `env` 2 | 3 | Package `env` manages the loading of environment variables. 4 | Variables are first searched for in an in-memory stack, then in a file `env.yaml` in the current working directory, and finally in the OS. 5 | The in-memory stack provides `Push` and `Pop` operations and is intended for modifying the environment during unit and integration testing. 6 | The YAML file allows the setting of environment variables in a file that can be shared and version-controlled. 7 | -------------------------------------------------------------------------------- /codegen/bundle/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Main", 9 | "type": "go", 10 | "request": "launch", 11 | "mode": "auto", 12 | "program": "${workspaceFolder}/main", 13 | "cwd": "${workspaceFolder}/main" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /docs/structure/pub.md: -------------------------------------------------------------------------------- 1 | # Package `pub` 2 | 3 | The `pub` package is used to enable the options pattern in `Connector.Publish`. This pattern is used in Go for expressing optional arguments. This package defines the various `Option`s as well as their collector `Request` which is not used directly but rather applies and collects the list of `Option`s behind the scenes. 4 | 5 | For example: 6 | 7 | ```go 8 | con.Publish( 9 | ctx, 10 | pub.GET("https://another.svc/bar"), 11 | pub.Body("foo"), 12 | ) 13 | ``` 14 | -------------------------------------------------------------------------------- /codegen/bundle/service/api/imports-gen.txt: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package {{ .PackagePathSuffix }}api 4 | 5 | import ( 6 | {{- range $i, $t := .Types }}{{ if not .Exists }}{{ if .PackagePath }} 7 | {{ .PackagePathSuffix }}_{{ Add $i 1 }} "{{ .PackagePath }}" 8 | {{- end }}{{ end }}{{ end }} 9 | ) 10 | 11 | {{- range $i, $t := .Types }}{{ if not .Exists }}{{ if .PackagePath }} 12 | 13 | type {{ .Name }} = {{ .PackagePathSuffix }}_{{ Add $i 1 }}.{{ .Name }} 14 | {{- end }}{{ end }}{{ end }} 15 | -------------------------------------------------------------------------------- /docs/structure/openapi.md: -------------------------------------------------------------------------------- 1 | # Package `openapi` 2 | 3 | All `Microbus` microservices [produce OpenAPI documents](../blocks/openapi.md) describing their endpoints. The `openapi` package is an internal package that supports the generation of these documents by: 4 | 5 | * Modeling the OpenAPI document using Go structs to facilitate marshaling it as YAML 6 | * Translating Go primitives to the corresponding OpenAPI types 7 | * Traversing the dependency tree of complex types (structs) using reflection and translating them into the corresponding OpenAPI components 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | nats-server 8 | 9 | # Test binary, built with `go test -c` 10 | *.test 11 | 12 | # Output of the go coverage tool, specifically when used with LiteIDE 13 | *.out 14 | 15 | # Dependency directories (remove the comment below to include it) 16 | # vendor/ 17 | 18 | # Ignore GoLand specific folders 19 | .idea/ 20 | 21 | # Other 22 | .DS_Store 23 | main/main 24 | main/__debug_bin* 25 | *.drawio.svg.bkp 26 | *.drawio.svg.dtmp 27 | *.drawio.bkp 28 | *.drawio.dtmp 29 | -------------------------------------------------------------------------------- /docs/structure/coreservices-smtpingress.md: -------------------------------------------------------------------------------- 1 | # Package `coreservices/smtpingress` 2 | 3 | The SMTP ingress microservice listens on port `:25` for incoming email messages. An app can listen to the appropriate event in order to process and act upon the email message. 4 | 5 | Use the following event sink in `service.yaml` to listen to the event: 6 | 7 | ```yaml 8 | sinks: 9 | - signature: OnIncomingEmail(mailMessage *Email) 10 | description: OnIncomingEmail is triggered when a new email message is received. 11 | source: github.com/microbus-io/fabric/coreservices/smtpingress 12 | ``` 13 | -------------------------------------------------------------------------------- /codegen/bundle/service/service_test.txt: -------------------------------------------------------------------------------- 1 | package {{ .PackagePathSuffix }} 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "net/http" 7 | "testing" 8 | 9 | "github.com/microbus-io/fabric/application" 10 | "github.com/microbus-io/fabric/connector" 11 | "github.com/microbus-io/fabric/frame" 12 | "github.com/microbus-io/fabric/pub" 13 | "github.com/microbus-io/testarossa" 14 | 15 | "{{ .PackageDir }}/{{ .PackageDirSuffix }}api" 16 | ) 17 | 18 | var ( 19 | _ context.Context 20 | _ io.Closer 21 | _ http.Handler 22 | _ testing.TB 23 | _ *application.Application 24 | _ *connector.Connector 25 | _ *frame.Frame 26 | _ pub.Option 27 | _ testarossa.TestingT 28 | _ *{{ .PackageDirSuffix }}api.Client 29 | ) 30 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package fabric 20 | -------------------------------------------------------------------------------- /httpx/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | Package httpx includes various HTTP utilities. 19 | */ 20 | package httpx 21 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Main Example", 9 | "type": "go", 10 | "request": "launch", 11 | "mode": "auto", 12 | "program": "${workspaceFolder}/main", 13 | "cwd": "${workspaceFolder}/main" 14 | }, 15 | { 16 | "name": "Codegen", 17 | "type": "go", 18 | "request": "launch", 19 | "mode": "auto", 20 | "program": "${workspaceFolder}/codegen", 21 | "cwd": "${workspaceFolder}/examples/calculator", 22 | "env": {"CODEGEN": "-f -v"} 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /codegen/tester/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package tester 20 | -------------------------------------------------------------------------------- /examples/hello/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package hello 20 | -------------------------------------------------------------------------------- /examples/login/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package login 20 | -------------------------------------------------------------------------------- /utils/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | Package utils is an assortment of independent utilities. 19 | */ 20 | package utils 21 | -------------------------------------------------------------------------------- /connector/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package connector implements the base class of all microservices. 18 | package connector 19 | -------------------------------------------------------------------------------- /examples/browser/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package browser 20 | -------------------------------------------------------------------------------- /coreservices/control/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package control 20 | -------------------------------------------------------------------------------- /coreservices/metrics/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package metrics 20 | -------------------------------------------------------------------------------- /examples/calculator/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package calculator 20 | -------------------------------------------------------------------------------- /examples/directory/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package directory 20 | -------------------------------------------------------------------------------- /examples/eventsink/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package eventsink 20 | -------------------------------------------------------------------------------- /examples/helloworld/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package helloworld 20 | -------------------------------------------------------------------------------- /examples/messaging/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package messaging 20 | -------------------------------------------------------------------------------- /coreservices/httpegress/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package httpegress 20 | -------------------------------------------------------------------------------- /coreservices/httpingress/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package httpingress 20 | -------------------------------------------------------------------------------- /coreservices/smtpingress/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package smtpingress 20 | -------------------------------------------------------------------------------- /coreservices/tokenissuer/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package tokenissuer 20 | -------------------------------------------------------------------------------- /examples/eventsource/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package eventsource 20 | -------------------------------------------------------------------------------- /coreservices/configurator/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package configurator 20 | -------------------------------------------------------------------------------- /coreservices/openapiportal/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/fabric/codegen 18 | 19 | package openapiportal 20 | -------------------------------------------------------------------------------- /dlru/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package dlru implements an LRU cache that is distributed among the peers of a microservice. 18 | package dlru 19 | -------------------------------------------------------------------------------- /mem/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package mem uses multiple sync pools of byte slices to provide allocation-free buffers of various sizes. 18 | package mem 19 | -------------------------------------------------------------------------------- /transport/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package transport implements the substrate used by microservices to communicate with each other. 18 | package transport 19 | -------------------------------------------------------------------------------- /rand/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | Package rand is a collection of utility functions for generating random numbers and identifiers. 19 | */ 20 | package rand 21 | -------------------------------------------------------------------------------- /trc/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package trc is used for working with tracing spans. 18 | // It contains the options to use in Connector.StartSpan 19 | package trc 20 | -------------------------------------------------------------------------------- /examples/directory/directoryapi/personkey.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package directoryapi 18 | 19 | // PersonKey is the primary key of the person. 20 | type PersonKey int 21 | -------------------------------------------------------------------------------- /pub/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | Package pub is used for the publishing of requests. 19 | It contains the options to use in Connector.Publish 20 | */ 21 | package pub 22 | -------------------------------------------------------------------------------- /sub/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | Package sub is used for subscribing to handle requests. 19 | It contains the options to use in Connector.Subscribe 20 | */ 21 | package sub 22 | -------------------------------------------------------------------------------- /application/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | Application is a collection of microservices that run in a single process and share the same lifecycle 19 | */ 20 | package application 21 | -------------------------------------------------------------------------------- /cfg/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | Package cfg is used for defining configuration properties. 19 | It contains the options to use in Connector.DefineConfig 20 | */ 21 | package cfg 22 | -------------------------------------------------------------------------------- /codegen/bundle/service/version-gen_test.txt: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | package {{ .PackagePathSuffix }} 4 | 5 | import ( 6 | "os" 7 | "testing" 8 | 9 | "github.com/microbus-io/fabric/utils" 10 | "github.com/microbus-io/testarossa" 11 | ) 12 | 13 | func Test{{ CapitalizeIdentifier .PackagePathSuffix }}_Versioning(t *testing.T) { 14 | t.Parallel() 15 | assert := testarossa.For(t) 16 | hash, err := utils.SourceCodeSHA256(".") 17 | if assert.NoError(err) { 18 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 19 | return 20 | } 21 | } 22 | buf, err := os.ReadFile("version-gen.go") 23 | if assert.NoError(err) { 24 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /errors/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | Package errors replaces the standard Go package, adding the ability to attach a stack trace 19 | and annotations to an error 20 | */ 21 | package errors 22 | -------------------------------------------------------------------------------- /docs/tech/json-vs-protobuf.md: -------------------------------------------------------------------------------- 1 | # JSON vs Protobuf 2 | 3 | `Microbus` uses JSON over HTTP as the default protocol with which input arguments are sent to functional endpoints, and conversely, output arguments are returned from functional endpoints. Albeit not as efficient as [Protobuf](https://protobuf.io), JSON was chosen for several reasons: 4 | 5 | * JSON is fully compatible with JavaScript-based clients such as React applications, making each endpoint easily exposed as a public API 6 | * JSON is the basis for the two common web API styles: [RPC over JSON and REST](../tech/rpc-vs-rest.md) 7 | * JSON is human-readable and more easily debuggable, contributing to engineering velocity 8 | * Like Protobuf, JSON is extensible 9 | * JSON is only about 2x slower than Protobuf, which in most cases is negligible compared to the network latency 10 | -------------------------------------------------------------------------------- /coreservices/tokenissuer/tokenissuerapi/mapclaims.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package tokenissuerapi 18 | 19 | import "github.com/golang-jwt/jwt/v4" 20 | 21 | // MapClaims is a set of JWT claims. 22 | type MapClaims = jwt.MapClaims 23 | -------------------------------------------------------------------------------- /coreservices/smtpingress/smtpingressapi/email.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package smtpingressapi 18 | 19 | import "github.com/mnako/letters" 20 | 21 | // Email is a message received by the email server, then parsed. 22 | type Email = letters.Email 23 | -------------------------------------------------------------------------------- /codegen/tester/testerapi/xycoord.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package testerapi 18 | 19 | // XYCoord is a non-primitive type holding X,Y coordinates. 20 | type XYCoord struct { 21 | X float64 `json:"x,omitzero"` 22 | Y float64 `json:"y,omitzero"` 23 | } 24 | -------------------------------------------------------------------------------- /copyright.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-yyyy Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | //go:generate go run github.com/microbus-io/copyrighter 18 | // - testdata/* 19 | // - .* 20 | // - /codegen/bundle/* 21 | // - resources/* 22 | 23 | package fabric 24 | 25 | import _ "github.com/microbus-io/copyrighter/i" 26 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | custom: ['https://www.microbus.io/contribute'] 15 | -------------------------------------------------------------------------------- /codegen/tester/testerapi/xyline.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package testerapi 18 | 19 | // XYLine is a non-primitive type with a nested non-primitive type. 20 | type XYLine struct { 21 | Start XYCoord `json:"start,omitzero"` 22 | End XYCoord `json:"end,omitzero"` 23 | } 24 | -------------------------------------------------------------------------------- /main/config.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023-2025 Microbus LLC and various contributors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | hello.example: 16 | Repeat: 3 17 | Greeting: Ciao 18 | 19 | http.ingress.core: 20 | # Ports: 8080 21 | # TimeBudget: 20s 22 | 23 | directory.example: 24 | SQL: "root:secret1234@tcp(127.0.0.1:3306)/microbus_examples" 25 | -------------------------------------------------------------------------------- /codegen/tester/resources/text.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023-2025 Microbus LLC and various contributors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | hello: 17 | en: Hello 18 | fr: Bonjour 19 | es: Hola 20 | it: Salve 21 | de: Guten Tag 22 | pt: Olá 23 | da: Goddag 24 | nl: Goedendag 25 | pl: Dzień dobry 26 | no: God dag 27 | tr: Merhaba 28 | sv: God dag 29 | -------------------------------------------------------------------------------- /docs/structure/coreservices-control.md: -------------------------------------------------------------------------------- 1 | # Package `coreservices/control` 2 | 3 | The `control.core` microservice provides no function and in fact will not start. It is the code generated clients in `controlapi` that are the essence of this package. These clients, and in particular the `controlapi.MulticastClient`, provide a programmatic interface to the [control subscriptions](../tech/control-subs.md) that all microservices support. 4 | 5 | For example, to ping and discover all microservices: 6 | 7 | ```go 8 | ch := controlapi.NewMulticastClient(svc).ForHost("all").Ping(ctx) 9 | for r := range ch { 10 | fromHost := frame.Of(r.HTTPResponse).FromHost() 11 | fromID := frame.Of(r.HTTPResponse).FromID() 12 | } 13 | ``` 14 | 15 | Overriding the host of the client via `ForHost` is required because the default host `control.core` does not exist. In the example above, the special hostname `all` is used to address all microservices. 16 | -------------------------------------------------------------------------------- /examples/hello/resources/text.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023-2025 Microbus LLC and various contributors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | Hello: 17 | en: Hello 18 | fr: Bonjour 19 | es: Hola 20 | it: Salve 21 | de: Guten Tag 22 | pt: Olá 23 | da: Goddag 24 | nl: Goedendag 25 | pl: Dzień dobry 26 | no: God dag 27 | tr: Merhaba 28 | sv: God dag 29 | -------------------------------------------------------------------------------- /examples/calculator/calculatorapi/point.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package calculatorapi 18 | 19 | // Point is a 2D (X,Y) coordinate. 20 | type Point struct { 21 | X float64 `json:"x,omitzero" jsonschema:"description=X coordinate,example=6"` 22 | Y float64 `json:"y,omitzero" jsonschema:"description=Y coordinate,example=8"` 23 | } 24 | -------------------------------------------------------------------------------- /docs/blocks/i18n.md: -------------------------------------------------------------------------------- 1 | # Internationalization 2 | 3 | The `Connector`'s `LoadResString` method loads and localizes strings stored in a [static resource](../blocks/embedded-res.md) named `text.yaml`. `LoadResString` extracts the request's locale from the `Accept-Language` header embedded in the context's [frame](../structure/frame.md), and returns the string in the language best matching it. 4 | 5 | ```go 6 | func (svc *Service) Localization(w http.ResponseWriter, r *http.Request) (err error) { 7 | ctx := r.Context() 8 | localizedStr, _ := svc.LoadResString(ctx, "stringKey") 9 | w.Write([]byte(localizedStr)) 10 | return nil 11 | } 12 | ``` 13 | 14 | `text.yaml` is expected to have the following format: 15 | 16 | ```yaml 17 | stringKey: 18 | default: Localized 19 | en: Localized 20 | en-GB: Localised 21 | fr: Localisée 22 | ``` 23 | 24 | If a default is not provided, English (en) is used as the fallback language. 25 | String keys and locale names are case sensitive. 26 | -------------------------------------------------------------------------------- /docs/blocks/embedded-res.md: -------------------------------------------------------------------------------- 1 | # Embedded Resources 2 | 3 | The `Connector` construct provides a read-only file system (`FS`) from which microservices can read static resources during runtime. The convenience methods `ReadResFile`, `ReadResTextFile`, `ServeResFile`, `ExecuteResTemplate` and `LoadResString` provide access to the file system. 4 | 5 | The `Connector`'s file system is initialized to the current working directory. Two microservices sharing the same app will therefore share the same working directory and their file systems will overlap. The `FS` can be set using the `Connector`'s `SetResFS` before the microservice is started. 6 | 7 | In the more common case, when a microservice is created using the code generator, the file system is initialized to an [embedded `FS`](https://pkg.go.dev/embed) pointing to the `resources` directory in the [source directory of the microservice](../blocks/uniform-code.md). Any source files placed in that directory are automatically made available via the `FS`. 8 | -------------------------------------------------------------------------------- /docs/blocks/graceful-shutdown.md: -------------------------------------------------------------------------------- 1 | # Graceful Shutdown 2 | 3 | Microservices are designed to run on cloud hardware that often shuts down at unpredictable times. When a microservice receives the signal to terminate, it first stops accepting new operations and attempts to end all pending operations gracefully. 4 | 5 | Graceful shutdown process: 6 | * Disable tickers so new iterations do not run 7 | * Stop accepting new requests 8 | * Wait 8 seconds for running tickers, pending requests and goroutines to end naturally 9 | * Cancel the lifetime `context.Context` of the microservice 10 | * Wait 4 more seconds for running tickers and pending requests, and goroutines to quit 11 | * Close the connection to the bus 12 | * Exit 13 | 14 | In order for goroutines to gracefully shut down, it is important to launch them using the `Connector`'s `Go` method rather than using the standard `go` keyword. When launched with `Go`, the goroutines are given the `context.Context` that gets canceled during termination. 15 | -------------------------------------------------------------------------------- /transport/msg.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package transport 18 | 19 | import "net/http" 20 | 21 | // MsgHandler is a function that processes a message. 22 | type MsgHandler = func(msg *Msg) 23 | 24 | // Msg is the data packet that is transmitted over the transport. 25 | type Msg struct { 26 | Data []byte 27 | Request *http.Request 28 | Response *http.Response 29 | } 30 | -------------------------------------------------------------------------------- /docs/tech/out-of-scope.md: -------------------------------------------------------------------------------- 1 | # Out of Scope 2 | 3 | `Microbus`'s focus is on building and operating microservices at scale. The following areas are currently out of scope: 4 | 5 | * __User interface__ - `Microbus` is a backend framework. Its link to the front-end are microservice endpoints that respond with JSON to single-page front-end applications, and an OpenAPI document that catalogs those endpoints. It is possible for microservices to generate HTML but `Microbus` provides no tooling in this area. 6 | * __SDLC automation__ - Automating the SDLC of `Microbus` solutions is currently out of scope. 7 | * __Databases__ - The choice of database depends heavily on the use case of the solution. As an enabling technology, `Microbus` takes no sides and does not offer tooling in the areas of data access and processing. 8 | * __AI__ - Artificial intelligence is currently out of scope. 9 | 10 | Some of these areas have room for contributors to step in. Contact us if you want to [get involved](../../README.md#-get-involved). 11 | -------------------------------------------------------------------------------- /openapi/endpoint.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package openapi 18 | 19 | // Endpoint describes a single endpoint of a microservice, such as an RPC function. 20 | type Endpoint struct { 21 | Type string 22 | Name string 23 | Path string 24 | Summary string 25 | Description string 26 | InputArgs any 27 | OutputArgs any 28 | Method string 29 | Actor string 30 | } 31 | -------------------------------------------------------------------------------- /docs/howto/self-explore.md: -------------------------------------------------------------------------------- 1 | # Explore on Your Own 2 | 3 | * Start NATS in debug and verbose modes `./nats-server -D -V`, run unit tests individually and look at the messages going over the bus 4 | * Modify `main/config.yaml` and witness the impact on the `hello.example` microservice. You'll have to restart the app for the configurator to pick up the new values 5 | * Add an endpoint `/increment` to the `calculator.example` microservice that returns the value of an input integer x plus 1 6 | * Add an endpoint `/calculate` to the `calculator.example` microservice that operates on decimal numbers, not just integers. Can you make `hello.example/calculator` work with decimals too? 7 | * Create your own microservice from scratch and add it to `main/main.go` 8 | * Put a breakpoint in any of the microservices of the example application and try debugging 9 | * Add a `/cache-delete` endpoint to the `messaging.example` 10 | * Create a second event sink microservice (name it differently though) and block registrations based on a configurable exclusion list 11 | -------------------------------------------------------------------------------- /setup/grafana/dashboards/dashboards.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023-2025 Microbus LLC and various contributors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # https://grafana.com/docs/grafana/latest/administration/provisioning/#dashboards 16 | 17 | apiVersion: 1 18 | 19 | providers: 20 | - name: 'Microbus' 21 | orgId: 1 22 | folder: '' 23 | type: file 24 | disableDeletion: false 25 | allowUiUpdates: true 26 | options: 27 | path: /otel-lgtm/grafana/conf/provisioning/dashboards 28 | -------------------------------------------------------------------------------- /codegen/bundle/service/service.txt: -------------------------------------------------------------------------------- 1 | package {{ .PackagePathSuffix }} 2 | 3 | import ( 4 | "context" 5 | "net/http" 6 | "time" 7 | 8 | "github.com/microbus-io/fabric/errors" 9 | 10 | "{{ .PackageDir }}/intermediate" 11 | "{{ .PackageDir }}/{{ .PackageDirSuffix }}api" 12 | ) 13 | 14 | var ( 15 | _ context.Context 16 | _ *http.Request 17 | _ time.Duration 18 | _ *errors.TracedError 19 | _ *{{ .PackagePathSuffix }}api.Client 20 | ) 21 | 22 | /* 23 | Service implements the {{ .General.Host }} microservice. 24 | {{- if .General.Description }} 25 | 26 | {{ .General.Description }} 27 | {{- end }} 28 | */ 29 | type Service struct { 30 | *intermediate.Intermediate // DO NOT REMOVE 31 | 32 | // Define microservice member variables here 33 | } 34 | 35 | // OnStartup is called when the microservice is started up. 36 | func (svc *Service) OnStartup(ctx context.Context) (err error) { 37 | return nil 38 | } 39 | 40 | // OnShutdown is called when the microservice is shut down. 41 | func (svc *Service) OnShutdown(ctx context.Context) (err error) { 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /utils/sourcecodehash_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "encoding/hex" 21 | "testing" 22 | 23 | "github.com/microbus-io/testarossa" 24 | ) 25 | 26 | func TestUtils_SourceCodeHash(t *testing.T) { 27 | t.Parallel() 28 | assert := testarossa.For(t) 29 | 30 | h, err := SourceCodeSHA256(".") 31 | assert.NoError(err) 32 | b, err := hex.DecodeString(h) 33 | assert.NoError(err) 34 | assert.Len(b, 256/8) 35 | } 36 | -------------------------------------------------------------------------------- /codegen/bundle/main/env.yaml: -------------------------------------------------------------------------------- 1 | # The deployment impacts certain aspects of the framework such as the log format and log verbosity level 2 | # PROD - production deployments 3 | # LAB - fully-functional non-production deployments such as dev integration, testing, staging, etc. 4 | # LOCAL - developing locally 5 | # TESTING - unit and integration testing 6 | MICROBUS_DEPLOYMENT: LOCAL 7 | 8 | # The plane of communication isolates communication among a group of microservices 9 | # MICROBUS_PLANE: microbus 10 | 11 | # Enable logging of debug-level messages 12 | # MICROBUS_LOG_DEBUG: 1 13 | 14 | # OpenTelemetry 15 | # https://opentelemetry.io/docs/specs/otel/protocol/exporter/ 16 | # https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/ 17 | # OTEL_EXPORTER_OTLP_PROTOCOL: grpc 18 | # OTEL_EXPORTER_OTLP_ENDPOINT: http://127.0.0.1:4317 19 | # OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 20 | # OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: 21 | 22 | # OTEL_METRIC_EXPORT_INTERVAL: 60000 23 | 24 | # Enable metric collection for Prometheus poll 25 | # MICROBUS_PROMETHEUS_EXPORTER: 1 26 | -------------------------------------------------------------------------------- /coreservices/httpingress/middleware/noop.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package middleware 18 | 19 | import ( 20 | "github.com/microbus-io/fabric/connector" 21 | ) 22 | 23 | // NoOp returns a middleware that delegates to the next middleware in the chain without taking any action. 24 | // It can be used to mark a position in the chain. 25 | func NoOp() Middleware { 26 | return func(next connector.HTTPHandler) connector.HTTPHandler { 27 | return next 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /codegen/tester/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package tester 20 | 21 | const Version = 186 22 | const SourceCodeSHA256 = "c9eee4d56617dcf3a6b4e822de7ec56e86c75b79392e2980efaae25a5174f56c" 23 | const Timestamp = "2025-11-08T21:18:35.196002Z" 24 | 25 | /* { 26 | "ver": 186, 27 | "sha256": "c9eee4d56617dcf3a6b4e822de7ec56e86c75b79392e2980efaae25a5174f56c", 28 | "ts": "2025-11-08T21:18:35.196002Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /examples/hello/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package hello 20 | 21 | const Version = 312 22 | const SourceCodeSHA256 = "389eb7c68911be1e88c58f481c0950f7395170eeef1379e58d2028119dc6e3a2" 23 | const Timestamp = "2025-11-08T21:18:37.264508Z" 24 | 25 | /* { 26 | "ver": 312, 27 | "sha256": "389eb7c68911be1e88c58f481c0950f7395170eeef1379e58d2028119dc6e3a2", 28 | "ts": "2025-11-08T21:18:37.264508Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /examples/login/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package login 20 | 21 | const Version = 80 22 | const SourceCodeSHA256 = "c013a7622db07668083117aa9b1a1c63144b7701253ecd646bf22b56d3fb7792" 23 | const Timestamp = "2025-11-29T02:31:02.051216Z" 24 | 25 | /* { 26 | "ver": 80, 27 | "sha256": "c013a7622db07668083117aa9b1a1c63144b7701253ecd646bf22b56d3fb7792", 28 | "ts": "2025-11-29T02:31:02.051216Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /coreservices/metrics/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package metrics 20 | 21 | const Version = 203 22 | const SourceCodeSHA256 = "2780d4af29d0ebd4ba598c0c71e1f466a03463c7246ff341ae28c4c9489bff54" 23 | const Timestamp = "2025-11-08T21:18:35.91453Z" 24 | 25 | /* { 26 | "ver": 203, 27 | "sha256": "2780d4af29d0ebd4ba598c0c71e1f466a03463c7246ff341ae28c4c9489bff54", 28 | "ts": "2025-11-08T21:18:35.91453Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /docs/blocks/lb.md: -------------------------------------------------------------------------------- 1 | # Load Balancing 2 | 3 | Microservices in `Microbus` are lightweight goroutines that pull (consume) messages off a messaging bus, in which a queue is maintained for each endpoint of each microservice. Replicas of the same microservice subscribe to the same queues and consume messages as they are published. Load balancing is achieved by virtue of the bus dispatching messages from the queue to only one random consumer at a time. A separate load balancer is therefore not required. 4 | 5 | 6 |

7 | 8 | `Microbus` also allows for [multicast](../blocks/multicast.md) subscriptions in which all replicas receive all messages. 9 | 10 | 11 |

12 | 13 | When using the `Connector`'s `Subscribe` method directly, multicasting can be enabled via the `sub.NoQueue()` option. 14 | 15 | When using [`service.yaml`](../tech/service-yaml.md) and the [code generator](../blocks/codegen.md), the `queue: none` property is used to indicate a multicast subscription. 16 | 17 | [Events](../blocks/events.md) are by definition multicast. 18 | -------------------------------------------------------------------------------- /examples/browser/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package browser 20 | 21 | const Version = 124 22 | const SourceCodeSHA256 = "4405764854a0da9ae22ee6fade1537d50dbbf4238246217240ca167176ca4f88" 23 | const Timestamp = "2025-11-08T21:18:36.496685Z" 24 | 25 | /* { 26 | "ver": 124, 27 | "sha256": "4405764854a0da9ae22ee6fade1537d50dbbf4238246217240ca167176ca4f88", 28 | "ts": "2025-11-08T21:18:36.496685Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /examples/login/resources/admin-only.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | Admin Only 20 | 26 | 27 | 28 |

For Admin Eyes Only

29 | If you can see this page, you're an admin. 30 | 31 | -------------------------------------------------------------------------------- /examples/messaging/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package messaging 20 | 21 | const Version = 219 22 | const SourceCodeSHA256 = "8518a969fdd4406778244447fa56744f2deefc9251d1e5391edf929cdeef8ee5" 23 | const Timestamp = "2025-11-08T21:18:37.69888Z" 24 | 25 | /* { 26 | "ver": 219, 27 | "sha256": "8518a969fdd4406778244447fa56744f2deefc9251d1e5391edf929cdeef8ee5", 28 | "ts": "2025-11-08T21:18:37.69888Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /coreservices/control/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package control 20 | 21 | const Version = 226 22 | const SourceCodeSHA256 = "9fe7b885bf9393154ec1f4cfd79f87ac2fe865f1f5d4bb0dd5c91c40ee42dc39" 23 | const Timestamp = "2025-11-24T22:32:53.515963Z" 24 | 25 | /* { 26 | "ver": 226, 27 | "sha256": "9fe7b885bf9393154ec1f4cfd79f87ac2fe865f1f5d4bb0dd5c91c40ee42dc39", 28 | "ts": "2025-11-24T22:32:53.515963Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /examples/calculator/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package calculator 20 | 21 | const Version = 342 22 | const SourceCodeSHA256 = "d500148d4cd4e8c598e02e9da6d22a9410917d5f84fe2973eedc50955fca5abd" 23 | const Timestamp = "2025-11-08T21:18:36.637642Z" 24 | 25 | /* { 26 | "ver": 342, 27 | "sha256": "d500148d4cd4e8c598e02e9da6d22a9410917d5f84fe2973eedc50955fca5abd", 28 | "ts": "2025-11-08T21:18:36.637642Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /examples/directory/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package directory 20 | 21 | const Version = 268 22 | const SourceCodeSHA256 = "ab1fdfac4d9b2eb0abb7c14af054107f73effa370776de370d19f10de8af2ade" 23 | const Timestamp = "2025-11-08T21:18:36.783318Z" 24 | 25 | /* { 26 | "ver": 268, 27 | "sha256": "ab1fdfac4d9b2eb0abb7c14af054107f73effa370776de370d19f10de8af2ade", 28 | "ts": "2025-11-08T21:18:36.783318Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /examples/eventsink/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package eventsink 20 | 21 | const Version = 251 22 | const SourceCodeSHA256 = "07556062e9268da092451deee930daf11aeba206b2bfc3ea99e88f67e71b781e" 23 | const Timestamp = "2025-11-08T21:18:36.934932Z" 24 | 25 | /* { 26 | "ver": 251, 27 | "sha256": "07556062e9268da092451deee930daf11aeba206b2bfc3ea99e88f67e71b781e", 28 | "ts": "2025-11-08T21:18:36.934932Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /examples/eventsource/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package eventsource 20 | 21 | const Version = 260 22 | const SourceCodeSHA256 = "96fe759fff19e7aa13692c61959c8e4ea82ebf2564b1ac4c9327a84ee15f1e7f" 23 | const Timestamp = "2025-11-14T03:51:21.215545Z" 24 | 25 | /* { 26 | "ver": 260, 27 | "sha256": "96fe759fff19e7aa13692c61959c8e4ea82ebf2564b1ac4c9327a84ee15f1e7f", 28 | "ts": "2025-11-14T03:51:21.215545Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /examples/helloworld/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package helloworld 20 | 21 | const Version = 70 22 | const SourceCodeSHA256 = "8091944ea85f94c5a2281196e3d6ffd05c3af780e9d0a9b605e15c246aa74099" 23 | const Timestamp = "2025-11-08T21:18:37.404999Z" 24 | 25 | /* { 26 | "ver": 70, 27 | "sha256": "8091944ea85f94c5a2281196e3d6ffd05c3af780e9d0a9b605e15c246aa74099", 28 | "ts": "2025-11-08T21:18:37.404999Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /coreservices/httpegress/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package httpegress 20 | 21 | const Version = 147 22 | const SourceCodeSHA256 = "1ca92453213c3a3c6729920bf3bc3bc85c19ca6194ca79c7fa20d87e19dc634a" 23 | const Timestamp = "2025-11-25T01:46:34.789241Z" 24 | 25 | /* { 26 | "ver": 147, 27 | "sha256": "1ca92453213c3a3c6729920bf3bc3bc85c19ca6194ca79c7fa20d87e19dc634a", 28 | "ts": "2025-11-25T01:46:34.789241Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /coreservices/httpingress/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package httpingress 20 | 21 | const Version = 359 22 | const SourceCodeSHA256 = "976c74ff6cb37c048493a67867ef9e138a8472bd49016e2f5ffbfdaf67c0a76f" 23 | const Timestamp = "2025-12-10T14:27:03.570913Z" 24 | 25 | /* { 26 | "ver": 359, 27 | "sha256": "976c74ff6cb37c048493a67867ef9e138a8472bd49016e2f5ffbfdaf67c0a76f", 28 | "ts": "2025-12-10T14:27:03.570913Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /coreservices/smtpingress/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package smtpingress 20 | 21 | const Version = 172 22 | const SourceCodeSHA256 = "830afdeec4dbd4aa689001b29947e9c8555cfd183100cc00a3b93c1b9b8618db" 23 | const Timestamp = "2025-11-08T21:18:36.208364Z" 24 | 25 | /* { 26 | "ver": 172, 27 | "sha256": "830afdeec4dbd4aa689001b29947e9c8555cfd183100cc00a3b93c1b9b8618db", 28 | "ts": "2025-11-08T21:18:36.208364Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /coreservices/tokenissuer/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package tokenissuer 20 | 21 | const Version = 105 22 | const SourceCodeSHA256 = "2804716d09671e51bc6e7b01445c1daff40332985dfb78e8dd55fa512311ee3a" 23 | const Timestamp = "2025-11-29T13:03:56.487238Z" 24 | 25 | /* { 26 | "ver": 105, 27 | "sha256": "2804716d09671e51bc6e7b01445c1daff40332985dfb78e8dd55fa512311ee3a", 28 | "ts": "2025-11-29T13:03:56.487238Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /docs/tech/local-dev.md: -------------------------------------------------------------------------------- 1 | # Local Development 2 | 3 | In `Microbus`, microservices are not large memory-gobbling processes but rather compact worker goroutines that ultimately consume messages from a queue. Microservices also don’t listen on ports so there is no potential of a port conflict with other microservices. These two qualities allow `Microbus` to spin up a large multitude of microservices in a single executable, enabling engineers to run and debug an entire application in their IDE. In fact, starting or restarting an application takes only a second or two, allowing engineers to iterate on code change quickly. It is a huge productivity boost. 4 | 5 | Those same qualities also allow `Microbus` to spin a microservice along with all its downstream dependencies inside a single [application for testing](../blocks/integration-testing.md) purposes. Full-blown integration tests can then be run by `go test`, achieving a high-degree of code coverage. 6 | 7 | In addition, the compact footprint of a `Microbus` application also enables the front-end team to run it locally rather than depend on a remote integration environment. 8 | -------------------------------------------------------------------------------- /errors/stackframe.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package errors 18 | 19 | import ( 20 | "fmt" 21 | ) 22 | 23 | // StackFrame is a single stack location. 24 | type StackFrame struct { 25 | Function string `json:"func"` 26 | File string `json:"file"` 27 | Line int `json:"line"` 28 | } 29 | 30 | // String returns a string representation of the stack frame. 31 | func (t *StackFrame) String() string { 32 | return fmt.Sprintf("- %s\n %s:%d", t.Function, t.File, t.Line) 33 | } 34 | -------------------------------------------------------------------------------- /examples/login/resources/manager-only.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | Manager Only 20 | 26 | 27 | 28 |

For Manager Eyes Only

29 | If you can see this page, you're a manager. 30 | 31 | -------------------------------------------------------------------------------- /codegen/bundle/main/main.go_: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/microbus-io/fabric/application" 8 | "github.com/microbus-io/fabric/coreservices/configurator" 9 | "github.com/microbus-io/fabric/coreservices/httpegress" 10 | "github.com/microbus-io/fabric/coreservices/httpingress" 11 | "github.com/microbus-io/fabric/coreservices/openapiportal" 12 | ) 13 | 14 | /* 15 | main runs the application. 16 | */ 17 | func main() { 18 | app := application.New() 19 | app.Add( 20 | // Configurator should start first 21 | configurator.NewService(), 22 | ) 23 | app.Add( 24 | // Core microservices 25 | httpegress.NewService(), 26 | openapiportal.NewService(), 27 | // metrics.NewService(), 28 | // tokenissuer.NewService(), 29 | ) 30 | app.Add( 31 | // Add solution microservices here 32 | ) 33 | app.Add( 34 | // When everything is ready, begin to accept external requests 35 | httpingress.NewService(), 36 | // smtpingress.NewService(), 37 | ) 38 | err := app.Run() 39 | if err != nil { 40 | fmt.Fprintf(os.Stderr, "%+v", err) 41 | os.Exit(19) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /coreservices/configurator/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package configurator 20 | 21 | const Version = 241 22 | const SourceCodeSHA256 = "61cabb357d9eb4dab9c40c91c743bbd1200737f7fba5b9d19b53c00be1faf7d6" 23 | const Timestamp = "2025-11-08T21:18:35.337784Z" 24 | 25 | /* { 26 | "ver": 241, 27 | "sha256": "61cabb357d9eb4dab9c40c91c743bbd1200737f7fba5b9d19b53c00be1faf7d6", 28 | "ts": "2025-11-08T21:18:35.337784Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /coreservices/openapiportal/version-gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package openapiportal 20 | 21 | const Version = 149 22 | const SourceCodeSHA256 = "b26a19245ac2d3d358cbf4f44bafe9984df027f6fd47235d15cacc81da5ab0bd" 23 | const Timestamp = "2025-11-08T21:18:36.056724Z" 24 | 25 | /* { 26 | "ver": 149, 27 | "sha256": "b26a19245ac2d3d358cbf4f44bafe9984df027f6fd47235d15cacc81da5ab0bd", 28 | "ts": "2025-11-08T21:18:36.056724Z" 29 | } */ 30 | -------------------------------------------------------------------------------- /docs/tech/short-circuit.md: -------------------------------------------------------------------------------- 1 | # Short-Circuit Transport 2 | 3 | The short-circuit is an alternative transport that enables microservices to communicate in-memory rather than over the network. It kicks in only among microservices that are bundled together in the same executable, reducing the latency of service-to-service calls by a factor of 10. Not all communication can be short-circuited. Communication with remote microservices still occurs over the messaging bus. Multicasts too require using the messaging bus in order for all potential subscribers to be reached. 4 | 5 | 6 |

7 | 8 | Tightly-coupled microservices that communicate on a [request/response](../blocks/unicast.md) basis, such as the [HTTP ingress proxy](../structure/coreservices-httpingress.md) and the [token issuer](../structure/coreservices-tokenissuer.md), should see the most benefit when bundled together in the same executable. 9 | 10 | The `MICROBUS_SHORT_CIRCUIT` [environment variable](../tech/envars.md) can be used to disable the short-circuit transport and force all communication to go over the messaging bus. 11 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/actions/use-cases-and-examples/building-and-testing/building-and-testing-go 2 | 3 | name: Test 4 | on: 5 | pull_request: 6 | types: [opened, reopened, edited] 7 | push: 8 | branches: 9 | - "main" 10 | 11 | jobs: 12 | test: 13 | runs-on: ubuntu-latest 14 | name: Run tests 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: Setup NATS server 18 | uses: onichandame/nats-action@master 19 | with: 20 | port: 4222 21 | - uses: actions/setup-go@v4 22 | with: 23 | go-version-file: 'go.mod' 24 | cache: true 25 | cache-dependency-path: go.sum 26 | - name: Go version 27 | run: go version 28 | - name: Run tests (NATS only) 29 | run: MICROBUS_SHORT_CIRCUIT=0 go test -count 1 -timeout 30s -cover ./... 30 | - name: Run tests (short-circuit only) 31 | run: go test -count 1 -timeout 30s -cover ./... 32 | - name: Run tests (NATS and short-circuit) 33 | run: MICROBUS_NATS=nats://127.0.0.1:4222 go test -count 1 -timeout 30s -cover ./... 34 | -------------------------------------------------------------------------------- /codegen/spec/type.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package spec 18 | 19 | import "strings" 20 | 21 | // Type is a complex type used in a function. 22 | type Type struct { 23 | Name string 24 | Exists bool 25 | PackagePath string 26 | } 27 | 28 | // PackagePathSuffix returns only the last portion of the full package path. 29 | func (t *Type) PackagePathSuffix() string { 30 | p := strings.LastIndex(t.PackagePath, "/") 31 | if p < 0 { 32 | return t.PackagePath 33 | } 34 | return t.PackagePath[p+1:] 35 | } 36 | -------------------------------------------------------------------------------- /docs/blocks/logging.md: -------------------------------------------------------------------------------- 1 | # Structured Logging 2 | 3 | Logging is one of the pillars of observability alongside [distributed tracing](../blocks/distrib-tracing.md) and [metrics](../blocks/metrics.md). `Microbus` uses Go's standard `log/slog` for logging with output directed to `stderr`. 4 | 5 | Logs are printed in human-friendly format in the `LOCAL` and `TESTING` [deployment environments](../tech/deployments.md) and in JSON in `PROD` and `LAB`. 6 | 7 | Logs are automatically enriched with the microservice's hostname, version number and ID, as well by the distributed trace ID, if applicable. 8 | 9 | In addition, logs are metered on a per-message basis to make them visible in Grafana. For this reason, the message part should be a fixed string, and all variable parts added as arguments. 10 | 11 | The `Connector` supports 4 methods for logging at different severity levels: `LogDebug`, `LogInfo`, `LogWarn` and `LogError`. Debug logs are ignored unless the `MICROBUS_LOG_DEBUG` [environment variable](../tech/envars.md) is set. 12 | 13 | Example: 14 | 15 | ```go 16 | c.LogInfo(ctx, "Fixed message", 17 | "key1", "value", 18 | "key2", 1234, 19 | ) 20 | ``` 21 | -------------------------------------------------------------------------------- /codegen/spec/version.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package spec 18 | 19 | import ( 20 | "path/filepath" 21 | ) 22 | 23 | // Version keeps the versioning information of the code. 24 | type Version struct { 25 | PackagePath string 26 | Version int `json:"ver"` 27 | SHA256 string `json:"sha256"` 28 | Timestamp string `json:"ts"` 29 | } 30 | 31 | // PackagePathSuffix returns only the last portion of the full package path. 32 | func (v *Version) PackagePathSuffix() string { 33 | return filepath.Base(v.PackagePath) 34 | } 35 | -------------------------------------------------------------------------------- /setup/microbus.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023-2025 Microbus LLC and various contributors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | services: 16 | lgtm: 17 | image: grafana/otel-lgtm 18 | ports: 19 | - "3000:3000" 20 | - "4317:4317" 21 | - "4318:4318" 22 | networks: 23 | - microbus-network 24 | volumes: 25 | - ./grafana/dashboards:/otel-lgtm/grafana/conf/provisioning/dashboards 26 | nats: 27 | image: nats:2-alpine 28 | ports: 29 | - "8222:8222" 30 | - "4222:4222" 31 | networks: 32 | - microbus-network 33 | networks: 34 | microbus-network: 35 | -------------------------------------------------------------------------------- /utils/panic.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "reflect" 21 | 22 | "github.com/microbus-io/fabric/errors" 23 | ) 24 | 25 | // CatchPanic calls the given function and returns any panic as a standard error. 26 | // Deprecated: Use [errors.CatchPanic] instead. 27 | func CatchPanic(f func() error) (err error) { 28 | return errors.CatchPanic(f) 29 | } 30 | 31 | // IsNil returns true if x is nil or an interface holding nil. 32 | func IsNil(x any) bool { 33 | defer func() { recover() }() 34 | return x == nil || reflect.ValueOf(x).IsNil() 35 | } 36 | -------------------------------------------------------------------------------- /docs/blocks/connectivity-liveness-test.md: -------------------------------------------------------------------------------- 1 | # Connectivity Liveness Test 2 | 3 | In `Microbus`, each microservice uses a single bi-directional [persistent connection](../blocks/multiplexed.md) for both incoming and outgoing messages. Consequently, that connection is the single source of truth of its liveness. If the connection drops, the microservice can no longer send messages to other microservices. In addition, once the messaging bus detects the failed connection, it deletes the microservice's subscriptions and no longer delivers any messages to it. Messages will be delivered to the microservice's replicas instead. 4 | 5 | In rare situations, if the messaging bus doesn't realize that a connection dropped, it might still attempt to deliver messages to the disconnected microservice. These messages will be lost and the upstream microservice will receive an [ack timeout](../blocks/ack-or-fail.md). The situation will rectify itself when the messaging bus realizes that the downstream microservice is not responding to pings, or when the microservice reconnects. 6 | 7 | Microservices are responsible for establishing and maintaining the connection to the messaging bus. When a connection drops, they do their best to reconnect. 8 | -------------------------------------------------------------------------------- /docs/structure/sub.md: -------------------------------------------------------------------------------- 1 | # Package `sub` 2 | 3 | The `sub` package defines the internal `Subscription` struct that facilitates the endpoint subscriptions of the microservice. It transforms the partial path specification in `Connector.Subscribe` to produce a fully-qualified URL. 4 | 5 | | Path specification | Fully-qualified URL | 6 | | - | - | 7 | | (empty) | https://example.host | 8 | | / | https://example.host/ | 9 | | :1080 | https://example.host:1080 | 10 | | :1080/ | https://example.host:1080/ | 11 | | :1080/path | https://example.host:1080/path | 12 | | /path/with/slash | https://example.host:443/path/with/slash | 13 | | path/with/no/slash | https://example.host:443/path/with/no/slash | 14 | | /path/{argument}/or/{suffix+} | https://example.host:443/path/{argument}/or/{suffix+} | 15 | | https://another.host/path | https://another.host:443/path | 16 | | https://another.host:1080/path | https://another.host:1080/path | 17 | 18 | This package also defines various `Option`s that can be applied to the `Subscription` using the options pattern. This pattern is used in Go for expressing optional arguments. 19 | 20 | For example: 21 | 22 | ```go 23 | con.Subscribe("GET", "/path", handler, sub.NoQueue()) 24 | ``` 25 | -------------------------------------------------------------------------------- /codegen/spec/common.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package spec 18 | 19 | import ( 20 | "strings" 21 | ) 22 | 23 | // conformDesc cleans up the description by removing back-quotes and extra spaces and setting a default if empty. 24 | func conformDesc(desc string, ifEmpty string) string { 25 | desc = strings.TrimSpace(desc) 26 | if desc == "" { 27 | desc = ifEmpty 28 | } 29 | desc = strings.ReplaceAll(desc, "`", "'") 30 | split := strings.Split(desc, "\n") 31 | for i := range split { 32 | split[i] = strings.TrimRight(split[i], " \r\t") 33 | } 34 | return strings.Join(split, "\n") 35 | } 36 | -------------------------------------------------------------------------------- /pub/response_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package pub 18 | 19 | import ( 20 | "errors" 21 | "net/http" 22 | "testing" 23 | 24 | "github.com/microbus-io/testarossa" 25 | ) 26 | 27 | func TestPub_Response(t *testing.T) { 28 | t.Parallel() 29 | assert := testarossa.For(t) 30 | 31 | myErr := errors.New("my error") 32 | r := NewErrorResponse(myErr) 33 | res, err := r.Get() 34 | assert.Nil(res) 35 | assert.Equal(&myErr, &err) 36 | 37 | var myRes http.Response 38 | r = NewHTTPResponse(&myRes) 39 | res, err = r.Get() 40 | assert.NoError(err) 41 | assert.Equal(&myRes, res) 42 | } 43 | -------------------------------------------------------------------------------- /docs/structure/coreservices-metrics.md: -------------------------------------------------------------------------------- 1 | # Package `coreservices/metrics` 2 | 3 | The metrics core microservice provides a single endpoint that lets [Prometheus](https://prometheus.io) scrape [metrics](../blocks/metrics.md) from all microservices at once. Prometheus pulls metrics from the metrics core microservice, which in turn pulls and aggregates metrics from all microservices it can reach on the messaging bus. 4 | 5 | 6 |

7 | 8 | The endpoint to obtain metrics from the metrics microservice is `https://localhost:8080/metrics.core/collect`. An optional argument `service` can be used to obtain the metrics of an individual service. The `secretkey` argument is mandatory except in local development and testing. It must match the value set for the `SecretKey` configuration property or else the request will be denied. 9 | 10 | Metrics can also be obtained from a microservice directly at `https://localhost:8080/hello.example:888/metrics`. 11 | 12 | The metrics core microservice is unnecessary if metrics are pushed to an OpenTelemetry collector, rather than pulled. 13 | 14 | Prometheus metric collection must be explicitly enabled by setting the `MICROBUS_PROMETHEUS_EXPORTER` [environment variable](../tech/envars.md). 15 | -------------------------------------------------------------------------------- /httpx/bodyreader_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package httpx 18 | 19 | import ( 20 | "io" 21 | "testing" 22 | 23 | "github.com/microbus-io/testarossa" 24 | ) 25 | 26 | func TestHttpx_BodyReader(t *testing.T) { 27 | t.Parallel() 28 | assert := testarossa.For(t) 29 | 30 | bin := []byte("Lorem Ipsum") 31 | br := NewBodyReader(bin) 32 | bout, err := io.ReadAll(br) 33 | assert.NoError(err) 34 | assert.Equal(bin, bout) 35 | assert.Equal(bin, br.Bytes()) 36 | br.Reset() 37 | bout, err = io.ReadAll(br) 38 | assert.NoError(err) 39 | assert.Equal(bin, bout) 40 | assert.Equal(bin, br.Bytes()) 41 | err = br.Close() 42 | assert.NoError(err) 43 | } 44 | -------------------------------------------------------------------------------- /docs/structure/dlru.md: -------------------------------------------------------------------------------- 1 | # Package `dlru` 2 | 3 | The `dlru` package implements a [distributed LRU cache](../blocks/distrib-cache.md) that is shared among all peer replicas of a microservice. The cache uses pub/sub over NATS to communicate and synchronize. 4 | 5 | By default, a DLRU is created and assigned for each microservice and made available using `svc.DistribCache()`. 6 | 7 | ```go 8 | var obj MyObject 9 | ok, err := svc.DistribCache().Get(ctx, cacheKey, &obj) 10 | if err != nil { 11 | return errors.Trace(err) 12 | } 13 | if !ok { 14 | obj, err = svc.loadObjectFromDatabase(ctx, objKey) 15 | if err != nil { 16 | return errors.Trace(err) 17 | } 18 | err = svc.DistribCache().Set(ctx, cacheKey, obj) 19 | if err != nil { 20 | return errors.Trace(err) 21 | } 22 | } 23 | ``` 24 | 25 | Additional DLRU caches can be created manually. 26 | The constructor requires a microservice in order to be able to communicate with NATS, and the path of the NATS subscription to use for synchronization among peers. The cache's capacity and TTL can be configured as well. 27 | 28 | ```go 29 | myCache, err := dlru.NewCache(ctx, svc, ":444/my-cache") 30 | if err != nil { 31 | return errors.Trace(err) 32 | } 33 | myCache.SetMaxMemoryMB(5) 34 | myCache.SetMaxAge(time.Hour) 35 | ``` 36 | -------------------------------------------------------------------------------- /coreservices/httpingress/middleware/cachecontrol.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package middleware 18 | 19 | import ( 20 | "net/http" 21 | 22 | "github.com/microbus-io/fabric/connector" 23 | ) 24 | 25 | // CacheControl returns a middleware that sets the Cache-Control header if not otherwise specified. 26 | func CacheControl(defaultValue string) Middleware { 27 | return func(next connector.HTTPHandler) connector.HTTPHandler { 28 | return func(w http.ResponseWriter, r *http.Request) (err error) { 29 | err = next(w, r) 30 | if w.Header().Get("Cache-Control") == "" { 31 | w.Header().Set("Cache-Control", defaultValue) 32 | } 33 | return err // No trace 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /transport/subscription.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package transport 18 | 19 | import ( 20 | "github.com/microbus-io/fabric/errors" 21 | "github.com/nats-io/nats.go" 22 | ) 23 | 24 | // Subscription is an expression of interest in a subject. 25 | type Subscription struct { 26 | conn *Conn 27 | next *Subscription 28 | prev *Subscription 29 | shortCircuitUnsub func() 30 | natsSub *nats.Subscription 31 | done bool 32 | } 33 | 34 | // Unsubscribe removes interest in the subject of the subscription. 35 | func (s *Subscription) Unsubscribe() (err error) { 36 | err = s.conn.unsubscribe(s) 37 | return errors.Trace(err) 38 | } 39 | -------------------------------------------------------------------------------- /docs/tech/deployments.md: -------------------------------------------------------------------------------- 1 | # Deployments 2 | 3 | `Microbus` recognizes four deployment environments: 4 | 5 | * `PROD` represents a production deployment 6 | * `LAB` represents a fully-functional non-production deployments such as dev integration, testing, staging, etc. 7 | * `LOCAL` represents development on an engineer's local machine 8 | * `TESTING` represents a unit test running a testing application 9 | 10 | The deployment environment impacts certain aspects of the framework such as [structured logging](../blocks/logging.md) and [distributed tracing](../blocks/distrib-tracing.md). 11 | 12 | | |`PROD`|`LAB`|`LOCAL`|`TESTING`| 13 | |--------|----|---|-----|----------| 14 | |Logging level|INFO|DEBUG|DEBUG|DEBUG| 15 | |Logging format|JSON|JSON|Human-friendly|Human-friendly| 16 | |Logging errors|Standard|Standard|Emphasized|Emphasized| 17 | |Distributed tracing|Selective|Everything|Everything|Everything| 18 | |Configurator|Enabled|Enabled|Enabled|Disabled| 19 | |Tickers|Enabled|Enabled|Enabled|Disabled| 20 | |Error output|Redacted|Stack trace|Stack trace|Stack trace| 21 | 22 | The deployment environment is set according to the value of the `MICROBUS_DEPLOYMENT` [environment variable](../tech/envars.md). If not specified, `PROD` is assumed, unless connecting to NATS on `nats://localhost:4222` or `nats://127.0.0.1:4222` in which case `LOCAL` is assumed. 23 | -------------------------------------------------------------------------------- /coreservices/openapiportal/resources/list.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 26 | 27 | 28 |

OpenAPI:{{ .Port }}

29 | {{ range .Infos }} 30 |

31 |

{{ .Host }}

32 | {{ .Description }} 33 |

34 | {{ end }} 35 | {{ if eq (len .Infos) 0 }}No OpenAPI endpoints{{ end }} 36 | 37 | -------------------------------------------------------------------------------- /docs/structure/examples-events.md: -------------------------------------------------------------------------------- 1 | # Package `examples/eventsource` and Package `examples/eventsink` 2 | 3 | The `eventsource.example` and `eventsink.example` demonstrate how [events reverse the dependency between two microservices](../blocks/events.md). The event source microservice is unaware and independent of the event sink microservice, event though technically it is the initiator of a request to the event sink. Rather, it is the event sink that is aware of and dependent on the event source. 4 | 5 | In this example, the `eventsource.example` mocks a simple user registration microservice that fires events to see if any filtering microservices wish to block the registration. The `eventsink.example` microservice acts as a filter provider for the `eventsource.example` microservice and disallows certain registrations. Other such filter providers may be added in the future without requiring changes to the `eventsource.example`. 6 | 7 | Try the following URLs in order: 8 | 9 | * http://localhost:8080/eventsource.example/register?email=peter@example.com : example.com domain is allowed. 10 | * http://localhost:8080/eventsource.example/register?email=mary@example.com : example.com domain is allowed. 11 | * http://localhost:8080/eventsource.example/register?email=paul@gmail.com : gmail.com domain is disallowed. 12 | * http://localhost:8080/eventsource.example/registered 13 | -------------------------------------------------------------------------------- /coreservices/httpingress/middleware/group.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package middleware 18 | 19 | import ( 20 | "net/http" 21 | 22 | "github.com/microbus-io/fabric/connector" 23 | ) 24 | 25 | // Group returns a middleware that nested middleware together and is often used in conjunction 26 | // with the `OnRoute` middleware to apply a group of middleware to a specific route. 27 | func Group(nested ...Middleware) Middleware { 28 | return func(next connector.HTTPHandler) connector.HTTPHandler { 29 | handler := next 30 | for n := len(nested) - 1; n >= 0; n-- { 31 | handler = nested[n](handler) 32 | } 33 | return func(w http.ResponseWriter, r *http.Request) (err error) { 34 | return handler(w, r) // No trace 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/structure/examples-helloworld.md: -------------------------------------------------------------------------------- 1 | # Package `examples/helloworld` 2 | 3 | The `helloworld.example` microservice demonstrates the classic minimalist example. 4 | 5 | http://localhost:8080/helloworld.example/hello-world simply prints `Hello, World!`. 6 | 7 | The code looks rather daunting but practically all of it is code generated. The manually-coded pieces are: 8 | 9 | The definition of the microservice and its single endpoint `HelloWorld` in `service.yaml`: 10 | 11 | ```yaml 12 | general: 13 | host: helloworld.example 14 | description: The HelloWorld microservice demonstrates the classic minimalist example. 15 | 16 | webs: 17 | - signature: HelloWorld() 18 | description: HelloWorld prints the classic greeting. 19 | ``` 20 | 21 | The implementation of the `HelloWorld` endpoint in `service.go`: 22 | 23 | ```go 24 | w.Write([]byte("Hello, World!")) 25 | return nil 26 | ``` 27 | 28 | A test of `TestHelloworld_HelloWorld` in `service_test.go`: 29 | 30 | ```go 31 | res, err := client.HelloWorld(ctx, "") 32 | if assert.NoError(err) && assert.Expect(res.StatusCode, http.StatusOK) { 33 | body, err := io.ReadAll(res.Body) 34 | assert.Expect(body, []string("Hello, World!"), err, nil) 35 | } 36 | ``` 37 | 38 | And finally, the addition of the microservice to the app in `main/main.go`. 39 | 40 | ```go 41 | app.Add( 42 | helloworld.NewService(), 43 | ) 44 | ``` 45 | -------------------------------------------------------------------------------- /pub/response.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package pub 18 | 19 | import "net/http" 20 | 21 | // Response is a union of an http.Response and an error. 22 | // Only one or the other is valid 23 | type Response struct { 24 | res *http.Response 25 | err error 26 | } 27 | 28 | // Get returns the http.Response or error stored in the composite Response 29 | func (r *Response) Get() (*http.Response, error) { 30 | return r.res, r.err 31 | } 32 | 33 | // NewErrorResponse creates a new response containing an error 34 | func NewErrorResponse(err error) *Response { 35 | return &Response{err: err} 36 | } 37 | 38 | // NewResponse creates a new response containing an http.Response 39 | func NewHTTPResponse(res *http.Response) *Response { 40 | return &Response{res: res} 41 | } 42 | -------------------------------------------------------------------------------- /docs/blocks/project-bootstrapping.md: -------------------------------------------------------------------------------- 1 | # Project Bootstrapping 2 | 3 | The code generator facilitates the creation of a new `Microbus` project. 4 | 5 | Initialize the project: 6 | 7 | ```shell 8 | cd mysolution 9 | go mod init github.com/mycompany/mysolution 10 | go get github.com/microbus-io/fabric/codegen 11 | ``` 12 | 13 | Create `doc.go` in the root of the project next to `go.mod`: 14 | 15 | ```go 16 | package root 17 | 18 | //go:generate go run github.com/microbus-io/fabric/codegen 19 | ``` 20 | 21 | Use `go generate` to create the initial project structure: 22 | 23 | ```shell 24 | go generate 25 | ``` 26 | 27 | Your project structure will now look like this: 28 | 29 | ``` 30 | mysolution/ 31 | ├── .claude/ # Claude setup 32 | │ └── skills/ 33 | ├── .vscode/ 34 | │ └── launch.json # VSCode launch file 35 | ├── main/ 36 | │ ├── config.yaml # Configuration file 37 | │ ├── env.yaml # Environment settings 38 | │ └── main.go # Main application 39 | ├── AGENTS-MICROBUS.md # Instructions to coding agents for Microbus 40 | ├── AGENTS.md # Instructions to coding agents for this project 41 | ├── CLAUDE.md # Refer Claude to AGENTS.md 42 | ├── doc.go 43 | ├── go.mod 44 | └── go.sum 45 | ``` 46 | 47 | Refresh the dependencies: 48 | 49 | ```shell 50 | go mod tidy 51 | ``` 52 | -------------------------------------------------------------------------------- /httpx/qargs_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package httpx 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/microbus-io/testarossa" 23 | ) 24 | 25 | func TestHttpx_QArgs(t *testing.T) { 26 | t.Parallel() 27 | assert := testarossa.For(t) 28 | 29 | assert.Equal("b=true&i=123&s=String", QArgs{ 30 | "s": "String", 31 | "i": 123, 32 | "b": true, 33 | }.Encode()) 34 | assert.Equal("b=true&i=123&s=String", QArgs{ 35 | "s": "String", 36 | "i": 123, 37 | "b": true, 38 | }.String()) 39 | 40 | urlValues := QArgs{ 41 | "s": "String", 42 | "i": 123, 43 | "b": true, 44 | }.URLValues() 45 | assert.Equal([]string{"String"}, urlValues["s"]) 46 | assert.Equal([]string{"123"}, urlValues["i"]) 47 | assert.Equal([]string{"true"}, urlValues["b"]) 48 | } 49 | -------------------------------------------------------------------------------- /coreservices/httpingress/logwriter.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package httpingress 18 | 19 | import ( 20 | "log" 21 | "strings" 22 | ) 23 | 24 | // logWriter captures logs generated by the HTTP servers and directs them to the service's logger. 25 | type logWriter struct { 26 | svc *Service 27 | } 28 | 29 | // Write sends the output to the service's logger. 30 | func (lw *logWriter) Write(p []byte) (n int, err error) { 31 | msg := string(p) 32 | if !strings.Contains(msg, "TLS handshake error") { 33 | lw.svc.LogError(lw.svc.Lifetime(), msg) 34 | } 35 | return len(p), nil 36 | } 37 | 38 | // newHTTPLogger creates a logger that redirects output to the service's logger. 39 | func newHTTPLogger(svc *Service) *log.Logger { 40 | return log.New(&logWriter{svc}, "", 0) 41 | } 42 | -------------------------------------------------------------------------------- /codegen/tester/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package tester 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestTester_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/hello/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package hello 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestHello_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/login/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package login 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestLogin_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/browser/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package browser 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestBrowser_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /coreservices/control/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package control 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestControl_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /coreservices/metrics/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package metrics 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestMetrics_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/directory/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package directory 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestDirectory_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/eventsink/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package eventsink 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestEventsink_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/messaging/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package messaging 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestMessaging_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/calculator/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package calculator 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestCalculator_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/eventsource/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package eventsource 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestEventsource_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/helloworld/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package helloworld 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestHelloworld_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /coreservices/httpegress/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package httpegress 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestHttpegress_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /coreservices/httpingress/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package httpingress 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestHttpingress_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /coreservices/smtpingress/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package smtpingress 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestSmtpingress_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /coreservices/tokenissuer/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package tokenissuer 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestTokenissuer_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /docs/blocks/multiplexed.md: -------------------------------------------------------------------------------- 1 | # Persistent Multiplexed Connections 2 | 3 | A persistent multiplexed connection is a TCP connection that is kept open and allows bi-directional streaming exchange of requests and responses at any time. Unlike HTTP/1.1, there is no restriction to have only one request and one response for the lifetime of the connection. A multiplexed connection can transport multiple requests and responses at the same time, interwoven on the timeline, and out of order. HTTP/2 and gRPC are a multiplexed connection. 4 | 5 | Three concurrent HTTP/1.1 requests utilize three TCP connections: 6 | 7 | 8 |

9 | 10 | A multiplexed connection on the other hand can serve the three requests on a single TCP connection: 11 | 12 | 13 |

14 | 15 | The benefits of a persistent multiplexed connection are: 16 | * A single multiplexed connection is more memory efficient when compared to multiple HTTP/1.1 connections open concurrently 17 | * There is almost no risk of running out of the approx 50,000 ephemeral ports needed to maintain a TCP connection, allowing a practically-unlimited number of concurrent requests 18 | * The overhead of establishing the connection, especially if it is a secure connection, is incurred only once 19 | * A connection that is persistent reduces churn in the network routing table, lending to a more stable networking topology 20 | -------------------------------------------------------------------------------- /coreservices/configurator/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package configurator 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestConfigurator_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /coreservices/openapiportal/version-gen_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by Microbus. DO NOT EDIT. 18 | 19 | package openapiportal 20 | 21 | import ( 22 | "os" 23 | "testing" 24 | 25 | "github.com/microbus-io/fabric/utils" 26 | "github.com/microbus-io/testarossa" 27 | ) 28 | 29 | func TestOpenapiportal_Versioning(t *testing.T) { 30 | t.Parallel() 31 | assert := testarossa.For(t) 32 | hash, err := utils.SourceCodeSHA256(".") 33 | if assert.NoError(err) { 34 | if !assert.Equal(hash, SourceCodeSHA256, "SourceCodeSHA256 is not up to date, run 'go generate'") { 35 | return 36 | } 37 | } 38 | buf, err := os.ReadFile("version-gen.go") 39 | if assert.NoError(err) { 40 | assert.Contains(string(buf), hash, "SHA256 in version-gen.go is not up to date, run 'go generate'") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /codegen/spec/general_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package spec 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/microbus-io/testarossa" 23 | "gopkg.in/yaml.v3" 24 | ) 25 | 26 | func TestSpec_General(t *testing.T) { 27 | t.Parallel() 28 | assert := testarossa.For(t) 29 | 30 | var gen General 31 | 32 | err := yaml.Unmarshal([]byte(` 33 | host: super.service 34 | description: foo 35 | `), &gen) 36 | assert.NoError(err) 37 | 38 | err = yaml.Unmarshal([]byte(` 39 | host: $uper.$ervice 40 | description: foo 41 | `), &gen) 42 | assert.Contains(err, "invalid host") 43 | 44 | err = yaml.Unmarshal([]byte(` 45 | host: 46 | description: foo 47 | `), &gen) 48 | assert.Contains(err, "invalid host") 49 | 50 | err = yaml.Unmarshal([]byte(` 51 | description: foo 52 | `), &gen) 53 | assert.Contains(err, "invalid host") 54 | } 55 | -------------------------------------------------------------------------------- /docs/structure/coreservices.md: -------------------------------------------------------------------------------- 1 | # Package `coreservices` 2 | 3 | The `coreservices` package is a collection of microservices that implement common functionality required by most if not all `Microbus` applications. 4 | 5 | * The [configurator](../structure/coreservices-configurator.md) is responsible for delivering configuration values to microservices that define configuration properties. Such microservices will not start if they cannot reach the configurator 6 | * [Control](../structure/coreservices-control.md) is not actually a microservice but rather a stub microservice used to generate a client for the `:888` [control subscriptions](../tech/control-subs.md) 7 | * The [HTTP egress proxy](../structure/coreservices-httpegress.md) relays HTTP requests to non-`Microbus` URLs 8 | * The [HTTP ingress proxy](../structure/coreservices-httpingress.md) bridges the gap between HTTP clients and the microservices running on `Microbus` 9 | * The [metrics](../structure/coreservices-metrics.md) microservice aggregates metrics from all microservices in response to a request from Prometheus 10 | * The [OpenAPI portal](../structure/coreservices-openapiportal.md) microservice renders a catalog of the OpenAPI endpoints of all microservices. 11 | * The [SMTP ingress](../structure/coreservices-smtpingress.md) microservice transforms incoming emails to actionable events 12 | * The [token issuer](../structure/coreservices-tokenissuer.md) microservice issues and validates tokens in the form of JWTs. 13 | -------------------------------------------------------------------------------- /.claude/skills/microbus/rm-any/SKILL.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Removing a Feature of a Microservice 3 | description: Removes a configuration property, functional endpoint, event source, event sink, web handler endpoint, ticker or metric, from a microservice. Use when explicitly asked by the user to remove a feature of a microservice. 4 | --- 5 | 6 | ## Workflow 7 | 8 | Copy this checklist and track your progress: 9 | 10 | ``` 11 | Removing a part of a microservice: 12 | - [ ] Step 1: Remove Definition From service.yaml 13 | - [ ] Step 2: Remove Implementation 14 | - [ ] Step 3: Remove Test 15 | - [ ] Step 4: Remove Unused Custom Types 16 | - [ ] Step 5: Update Boilerplate code 17 | - [ ] Step 6: Document the Microservice 18 | ``` 19 | 20 | #### Step 1: Remove Definition From `service.yaml` 21 | 22 | Remove the definition from `service.yaml`. 23 | 24 | #### Step 2: Remove Implementation 25 | 26 | Remove any implementation code from `service.go`. 27 | 28 | #### Step 3: Remove Test 29 | 30 | Remove the corresponding test fom `service_test.go`. 31 | 32 | #### Step 4: Remove Unused Custom Types 33 | 34 | If the deleted definition was using non-primitive custom types that are no longer used elsewhere, remove the definition of the unused types from the API directory. 35 | 36 | #### Step 5: Update Boilerplate Code 37 | 38 | Run `go generate` to update the boilerplate code. 39 | 40 | #### Step 6: Update Documentation 41 | 42 | Update the microservice's local `AGENTS.md` to reflect the removal. 43 | -------------------------------------------------------------------------------- /docs/blocks/discovery.md: -------------------------------------------------------------------------------- 1 | # Dynamic Service Discovery 2 | 3 | In traditional microservice architectures, microservices are implemented as web servers. Upstream clients who wish to make a request to a downstream microservice must know its location (IP address and port). This is further complicated when multiple replicas of the downstream microservice exist and load balancing is added to the mix. A typical solution is to have the upstream client contact a service discovery or DNS for the location (IP and port) of the downstream microservice, before making (pushing) its request. In this setup, the service discovery is a separate system from the transport layer (HTTP) and inconsistencies may occur if it is not in sync with the current state of any of the microservices. 4 | 5 | In `Microbus`, microservices are not web servers. Instead, they are lightweight goroutines that pull (consume) messages off [carefully-crafted subscriptions](../blocks/unicast.md#notes-on-subscription-subjects) from a messaging bus. A microservice's subscriptions on the messaging bus are how it is discovered by clients (publishers). When a subscription is established, such as when the microservice starts up, the microservice becomes immediately discoverable. When the subscription is closed, such as when the microservice shuts down, the microservice is not longer discoverable. The messaging bus is in effect the service discovery. An external service discovery system is not required. 6 | 7 | 8 |

9 | -------------------------------------------------------------------------------- /coreservices/httpingress/middleware/blockedpaths.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package middleware 18 | 19 | import ( 20 | "net/http" 21 | 22 | "github.com/microbus-io/fabric/connector" 23 | "github.com/microbus-io/fabric/errors" 24 | ) 25 | 26 | // BlockedPaths returns a middleware that returns a 404 error for requests with paths matching the predicate. 27 | // The path passed to the matcher is the full path of the URL, without query arguments. 28 | func BlockedPaths(isBlocked func(path string) bool) Middleware { 29 | return func(next connector.HTTPHandler) connector.HTTPHandler { 30 | notFound := errors.New("", http.StatusNotFound) 31 | return func(w http.ResponseWriter, r *http.Request) error { 32 | if isBlocked(r.URL.Path) { 33 | w.WriteHeader(http.StatusNotFound) 34 | return notFound 35 | } 36 | return next(w, r) // No trace 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /codegen/bundle/.claude/skills/microbus/rm-any/SKILL.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Removing a Feature of a Microservice 3 | description: Removes a configuration property, functional endpoint, event source, event sink, web handler endpoint, ticker or metric, from a microservice. Use when explicitly asked by the user to remove a feature of a microservice. 4 | --- 5 | 6 | ## Workflow 7 | 8 | Copy this checklist and track your progress: 9 | 10 | ``` 11 | Removing a part of a microservice: 12 | - [ ] Step 1: Remove Definition From service.yaml 13 | - [ ] Step 2: Remove Implementation 14 | - [ ] Step 3: Remove Test 15 | - [ ] Step 4: Remove Unused Custom Types 16 | - [ ] Step 5: Update Boilerplate code 17 | - [ ] Step 6: Document the Microservice 18 | ``` 19 | 20 | #### Step 1: Remove Definition From `service.yaml` 21 | 22 | Remove the definition from `service.yaml`. 23 | 24 | #### Step 2: Remove Implementation 25 | 26 | Remove any implementation code from `service.go`. 27 | 28 | #### Step 3: Remove Test 29 | 30 | Remove the corresponding test fom `service_test.go`. 31 | 32 | #### Step 4: Remove Unused Custom Types 33 | 34 | If the deleted definition was using non-primitive custom types that are no longer used elsewhere, remove the definition of the unused types from the API directory. 35 | 36 | #### Step 5: Update Boilerplate Code 37 | 38 | Run `go generate` to update the boilerplate code. 39 | 40 | #### Step 6: Update Documentation 41 | 42 | Update the microservice's local `AGENTS.md` to reflect the removal. 43 | -------------------------------------------------------------------------------- /docs/blocks/agents-md.md: -------------------------------------------------------------------------------- 1 | # `AGENTS.md` 2 | 3 | An `AGENTS.md` file is the de-facto standard for providing coding agents with context about a project or a part thereof. `Microbus` utilizes this concept to train [coding agents](../blocks/coding-agents.md) how to work correctly on a `Microbus` solution in general, and on each individual microservice. 4 | 5 | A global `AGENTS.md` file at the root of the project includes context that is applicable to the project as a whole. The first instruction in that file points the coding agent to `AGENTS-MICROBUS.md`. 6 | 7 | The `AGENTS-MICROBUS.md` file (also located at the root of the project) includes instructions for working on a `Microbus` solution in general. This file may be updated with each release of `Microbus` and should not be edited by hand. Use the [code generator](../blocks/codegen.md) to refresh this file in your project with each new release of `Microbus`. 8 | 9 | The `.claude/skills` directory is a collection of workflows that guide the coding agent when working on complex multi-step tasks. These skills are referenced in `AGENTS-MICROBUS.md`. 10 | 11 | An `AGENTS.md` file placed in the directory of each microservice keeps context that is applicable to that single microservice alone. This local `AGENTS.md` is maintained by the coding agent itself as it works on the microservice, but it can also be edited by hand. 12 | 13 | Since Claude may not recognize `AGENTS.md`, next to each `AGENTS.md` file you'll find a simple `CLAUDE.md` file that tells Claude to read `AGENTS.md`. 14 | -------------------------------------------------------------------------------- /coreservices/httpingress/middleware/charsetutf8.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package middleware 18 | 19 | import ( 20 | "net/http" 21 | "strings" 22 | 23 | "github.com/microbus-io/fabric/connector" 24 | ) 25 | 26 | // CharsetUTF8 returns a middleware that augments the Content-Type header of text/* and application/json with the UTF-8 charset. 27 | func CharsetUTF8() Middleware { 28 | return func(next connector.HTTPHandler) connector.HTTPHandler { 29 | return func(w http.ResponseWriter, r *http.Request) (err error) { 30 | err = next(w, r) 31 | contentType := strings.ToLower(w.Header().Get("Content-Type")) 32 | if contentType == "application/json" || 33 | (strings.HasPrefix(contentType, "text/") && !strings.Contains(contentType, ";")) { 34 | w.Header().Set("Content-Type", w.Header().Get("Content-Type")+"; charset=utf-8") 35 | } 36 | return err // No trace 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /coreservices/httpingress/middleware/secureredirect.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package middleware 18 | 19 | import ( 20 | "net/http" 21 | "strings" 22 | 23 | "github.com/microbus-io/fabric/connector" 24 | ) 25 | 26 | // SecureRedirect returns a middleware that redirects requests from HTTP port :80 to HTTPS port :443, if appropriate. 27 | func SecureRedirect(isSecurePort443 func() bool) Middleware { 28 | return func(next connector.HTTPHandler) connector.HTTPHandler { 29 | return func(w http.ResponseWriter, r *http.Request) (err error) { 30 | if r.TLS == nil && r.Method == "GET" && r.URL.Port() == "80" && isSecurePort443() { 31 | u := *r.URL 32 | u.Scheme = "https" 33 | u.Host, _, _ = strings.Cut(u.Host, ":") 34 | s := u.String() 35 | http.Redirect(w, r, s, http.StatusTemporaryRedirect) 36 | return nil 37 | } 38 | return next(w, r) // No trace 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /docs/structure/cfg.md: -------------------------------------------------------------------------------- 1 | # Package `cfg` 2 | 3 | The `cfg` package is used to enable the options pattern in `Connector.DefineConfig`. This pattern is used in Go for expressing optional arguments. This package defines the various `Option`s as well as their collector `Config` which is not used directly but rather applies and collects the list of `Option`s behind the scenes. 4 | 5 | For example: 6 | 7 | ```go 8 | con.DefineConfig("Database", cfg.Validation("url"), cfg.Secret()) 9 | ``` 10 | 11 | The following options are supported: 12 | 13 | * `cfg.DefaultValue` specifies a default value for the property when one is not provided by the configurator 14 | * `cfg.Validation` uses a pattern to validate values before they are set 15 | * `str` - Plain text, no validation 16 | * `str ^[a-zA-Z0-9]+$` - Text with regexp validation 17 | * `bool` - Must be `true` or `false` 18 | * `int` - An integer, no validation 19 | * `int [0,60]` - An integer in range 20 | * `float` - A decimal number, no validation 21 | * `float [0.0,1.0)` - A decimal number in range 22 | * `dur` - A duration such as `7h3m45s500ms300us100ns` 23 | * `dur (0s,24h]` - A duration in range 24 | * `set Red|Green|Blue` - A set of explicit options separated by `|` 25 | * `url` - A URL 26 | * `email` - An email address, either `Joe ` or just `joe@example.com` 27 | * `json` - A valid JSON string 28 | * `cfg.Secret` indicates that the value of this property is a secret and should not be logged 29 | * `cfg.Description` is intended to explain the purpose of the config property and how it will impact the microservice 30 | -------------------------------------------------------------------------------- /docs/structure/examples.md: -------------------------------------------------------------------------------- 1 | # Package `examples` 2 | 3 | The `examples` package holds several examples that demonstrate how the `Microbus` framework is used to create microservices. When studying an example, start by looking at the `service.yaml` to get a quick overview of the functionality of the microservice. Then go deep into the code in `service.go`. All files with `-gen` in their name are code generated and can be ignored until you're ready to go deep into the internals of `Microbus`. 4 | 5 | * [HelloWorld](../structure//examples-helloworld.md) demonstrates the classic minimalist example 6 | * [Hello](../structure/examples-hello.md) demonstrates the key capabilities of the framework 7 | * [Calculator](../structure/examples-calculator.md) demonstrates functional handlers 8 | * [Messaging](../structure/examples-messaging.md) demonstrates load-balanced unicast, multicast and direct addressing messaging 9 | * [Event source and sink](../structure/examples-events.md) shows how events can be used to reverse the dependency between two microservices 10 | * [Directory](../structure/examples-directory.md) is an example of a microservice that provides a CRUD API backed by a database 11 | * [Browser](../structure/examples-browser.md) is an example of a microservice that uses the [HTTP egress core microservice](../structure/coreservices-httpegress.md) 12 | * [Login](../structure/examples-login.md) employs authentication and authorization to restrict access to certain endpoints 13 | 14 | In case you missed it, the [quick start guide](../howto/quick-start.md) explains how to setup your system to run the examples. 15 | -------------------------------------------------------------------------------- /docs/tech/encapsulation.md: -------------------------------------------------------------------------------- 1 | # Encapsulation Pattern 2 | 3 | `Microbus` employs the principle of information hiding and opts to encapsulate the underlying technologies behind its own simplified interfaces. There are various reasons for this pattern: 4 | 5 | * Providing a cohesive experience to developers 6 | * Enforcing uniformity across all microservices brings familiarity when looking at someone else's code, lowers the learning curve, and ultimately increases velocity 7 | * The underlying technology can be changed with little impact to the microservices 8 | * Oftentimes the underlying technology is more extensive than the basic functionality that is needed by the framework. Encapsulating the underlying API enables exposing only certain functions to the developer 9 | * The framework is in control of when and how the underlying technology is initialized 10 | * The framework is able to seamlessly integrate building blocks together. This will take shape as more building blocks are introduced 11 | * Bugs or CVEs in the underlying technologies are quicker to fix because there is only one source of truth. A bug such as [Log4Shell CVE-2021-44228](https://logging.apache.org/log4j/2.x/security.html) would require no code changes to the microservices, only to the framework 12 | 13 | One example of this pattern is with the configuration of microservices. Rather than leave things up to each individual developer how to fetch config values, the `Connector` defines an interface that encapsulates the underlying implementation. Today, the framework looks for config values in a `config.yaml` file. In the future, it might be extended to fetch configs from a remote location. 14 | -------------------------------------------------------------------------------- /docs/tech/nats-connection.md: -------------------------------------------------------------------------------- 1 | # NATS Connection Settings 2 | 3 | NATS is the communication medium of microservices and all microservices must first and foremost be connected to NATS in order to send and receive messages. By default, microservices attempt to connect to NATS on `nats://127.0.0.1:4222` using a plain (unsecure) TCP connection. The `MICROBUS_NATS` [environment variable](../tech/envars.md) is used to customize this connection URL. 4 | 5 | NATS supports [various authentication methods](https://docs.nats.io/using-nats/developer/connecting) for connecting to the NATS cluster. The `Microbus` framework is exposing some of these via [environment variables](../tech/envars.md) and certificate files. 6 | 7 | The `MICROBUS_NATS_USER` and `MICROBUS_NATS_PASSWORD` [environment variables](../tech/envars.md), when present, are used to authenticate with simple [username and password](https://docs.nats.io/using-nats/developer/connecting/userpass) credentials. 8 | 9 | The `MICROBUS_NATS_TOKEN` [environment variable](../tech/envars.md), when present, is used to authenticate with an [API token](https://docs.nats.io/using-nats/developer/connecting/token#connecting-with-a-token) credential. 10 | 11 | NATS needs a public certificate and a private key in order to [secure the connection to NATS with TLS](https://docs.nats.io/using-nats/developer/connecting/tls). `Microbus` looks for the certs in the current working directory under the names `cert.pem` and `key.pem`. 12 | 13 | A root certificate authority (CA) certificate may be required by NATS to trust other certificates. `Microbus` looks for the CA certificate file in the current working directory under the name `ca.pem`. 14 | -------------------------------------------------------------------------------- /codegen/bundle/service/intermediate/intermediate-gen.configs.txt: -------------------------------------------------------------------------------- 1 | 2 | // doOnConfigChanged is called when the config of the microservice changes. 3 | func (svc *Intermediate) doOnConfigChanged(ctx context.Context, changed func(string) bool) (err error) { 4 | {{- range .Configs}}{{ if .Callback}} 5 | if changed("{{ .Name}}") { 6 | err := svc.impl.OnChanged{{ .Name}}(ctx) 7 | if err != nil { 8 | return err // No trace 9 | } 10 | } 11 | {{- end}}{{- end}} 12 | return nil 13 | } 14 | {{ range .Configs}} 15 | /* 16 | {{ .Description }} 17 | */ 18 | func (svc *Intermediate) {{ .Name }}() ({{ .Out "name type" }}) { 19 | _val := svc.Config("{{ .Name }}") 20 | 21 | {{- with index .Signature.OutputArgs 0}} 22 | 23 | {{- if eq .Type "string"}} 24 | return _val{{ end }} 25 | 26 | {{- if eq .Type "int"}} 27 | _i, _ := strconv.ParseInt(_val, 10, 64) 28 | return int(_i){{ end }} 29 | 30 | {{- if eq .Type "bool"}} 31 | _b, _ := strconv.ParseBool(_val) 32 | return _b{{ end }} 33 | 34 | {{- if eq .Type "time.Duration"}} 35 | _dur, _ := time.ParseDuration(_val) 36 | return _dur{{ end }} 37 | 38 | {{- if eq .Type "float64"}} 39 | _f64, _ := time.ParseFloat(_val, 64) 40 | return _f64{{ end }} 41 | 42 | {{- end }} 43 | } 44 | 45 | /* 46 | Set{{ .Name }} sets the value of the configuration property. 47 | This action is restricted to the TESTING deployment in which the fetching of values from the configurator is disabled. 48 | 49 | {{ .Description }} 50 | */ 51 | func (svc *Intermediate) Set{{ .Name }}({{ .Out "name type" }}) error { 52 | return svc.SetConfig("{{ .Name }}", utils.AnyToString({{ (index .Signature.OutputArgs 0).Name }})) 53 | } 54 | {{ end }} -------------------------------------------------------------------------------- /coreservices/httpingress/middleware/internalheaders.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package middleware 18 | 19 | import ( 20 | "net/http" 21 | "strings" 22 | 23 | "github.com/microbus-io/fabric/connector" 24 | "github.com/microbus-io/fabric/frame" 25 | ) 26 | 27 | // InternalHeaders returns a middleware that filters internal headers from entering or exiting. 28 | func InternalHeaders() Middleware { 29 | return func(next connector.HTTPHandler) connector.HTTPHandler { 30 | return func(w http.ResponseWriter, r *http.Request) (err error) { 31 | // Do not accept internal headers 32 | for h := range r.Header { 33 | if strings.HasPrefix(h, frame.HeaderPrefix) || h == "Traceparent" || h == "Tracestate" { 34 | r.Header.Del(h) 35 | } 36 | } 37 | err = next(w, r) 38 | // Do not leak internal headers 39 | for h := range w.Header() { 40 | if strings.HasPrefix(h, frame.HeaderPrefix) || h == "Traceparent" || h == "Tracestate" { 41 | w.Header().Del(h) 42 | } 43 | } 44 | return err // No trace 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /coreservices/httpingress/middleware/xforwarded.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package middleware 18 | 19 | import ( 20 | "net/http" 21 | 22 | "github.com/microbus-io/fabric/connector" 23 | ) 24 | 25 | // XForwarded returns a middleware that sets the `X-Forwarded` headers pertaining to the request, if not already set. 26 | // These headers are used by downstream microservices to compose absolute URLs when necessary. 27 | func XForwarded() Middleware { 28 | return func(next connector.HTTPHandler) connector.HTTPHandler { 29 | return func(w http.ResponseWriter, r *http.Request) (err error) { 30 | if r.Header.Get("X-Forwarded-Host") == "" { 31 | r.Header.Set("X-Forwarded-Host", r.Host) 32 | r.Header.Set("X-Forwarded-For", r.RemoteAddr) 33 | if r.TLS != nil { 34 | r.Header.Set("X-Forwarded-Proto", "https") 35 | } else { 36 | r.Header.Set("X-Forwarded-Proto", "http") 37 | } 38 | r.Header.Set("X-Forwarded-Prefix", "") 39 | } 40 | r.Header.Set("X-Forwarded-Path", r.URL.Path) 41 | return next(w, r) // No trace 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /codegen/bundle/service/service-gen.txt: -------------------------------------------------------------------------------- 1 | // Code generated by Microbus. DO NOT EDIT. 2 | 3 | /* 4 | Package {{ .PackagePathSuffix }} implements the {{ .General.Host }} microservice. 5 | {{- if .General.Description }} 6 | 7 | {{ .General.Description }} 8 | {{- end }} 9 | */ 10 | package {{ .PackagePathSuffix }} 11 | 12 | import ( 13 | "context" 14 | "net/http" 15 | "time" 16 | 17 | "github.com/microbus-io/fabric/errors" 18 | "github.com/microbus-io/fabric/service" 19 | 20 | "{{ .PackageDir }}/intermediate" 21 | "{{ .PackageDir }}/{{ .PackageDirSuffix }}api" 22 | ) 23 | 24 | var ( 25 | _ context.Context 26 | _ *http.Request 27 | _ time.Duration 28 | _ service.Service 29 | _ *errors.TracedError 30 | _ *{{ .PackagePathSuffix }}api.Client 31 | ) 32 | 33 | // Hostname is the default hostname of the microservice: {{ .General.Host }}. 34 | const Hostname = "{{ .General.Host }}" 35 | 36 | // NewService creates a new {{ .General.Host }} microservice. 37 | func NewService() *Service { 38 | s := &Service{} 39 | s.Intermediate = intermediate.NewService(s, Version) 40 | return s 41 | } 42 | 43 | // Mock is a mockable version of the {{ .General.Host }} microservice, allowing functions, event sinks and web handlers to be mocked. 44 | type Mock = intermediate.Mock 45 | 46 | // New creates a new mockable version of the microservice. 47 | func NewMock() *Mock { 48 | return intermediate.NewMock() 49 | } 50 | 51 | /* 52 | Init enables a single-statement pattern for initializing the microservice. 53 | 54 | svc.Init(func(svc Service) { 55 | svc.SetGreeting("Hello") 56 | }) 57 | */ 58 | func (svc *Service) Init(initializer func(svc *Service)) *Service { 59 | initializer(svc) 60 | return svc 61 | } 62 | -------------------------------------------------------------------------------- /coreservices/httpingress/middleware/defaultfavicon.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package middleware 18 | 19 | import ( 20 | _ "embed" 21 | "net/http" 22 | 23 | "github.com/microbus-io/fabric/connector" 24 | "github.com/microbus-io/fabric/errors" 25 | "github.com/microbus-io/fabric/httpx" 26 | ) 27 | 28 | //go:embed defaultfavicon.ico 29 | var busIcon []byte 30 | 31 | // DefaultFavIcon returns a middleware that responds to /favicon.ico, if the app does not. 32 | func DefaultFavIcon() Middleware { 33 | return func(next connector.HTTPHandler) connector.HTTPHandler { 34 | return func(w http.ResponseWriter, r *http.Request) (err error) { 35 | err = next(w, r) 36 | if err != nil && r.URL.Path == "/favicon.ico" && errors.StatusCode(err) == http.StatusNotFound { 37 | w.Header().Set("Content-Type", "image/x-icon") 38 | w.Header().Set("Cache-Control", "public, max-age=86400") // 24hr 39 | if ww, ok := w.(*httpx.ResponseRecorder); ok { // Always true 40 | ww.ClearBody() 41 | } 42 | w.Write(busIcon) 43 | err = nil 44 | } 45 | return err // No trace 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /codegen/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "flag" 21 | "os" 22 | "strings" 23 | 24 | "github.com/microbus-io/fabric/env" 25 | ) 26 | 27 | // main is executed when "go generate" is run in the current working directory. 28 | func main() { 29 | // Load flags from environment variable because can't pass arguments to code-generator 30 | var flagForce bool 31 | var flagVerbose bool 32 | envVal := env.Get("MICROBUS_CODEGEN") 33 | if envVal == "" { 34 | envVal = env.Get("CODEGEN") 35 | } 36 | flags := flag.NewFlagSet("", flag.ContinueOnError) 37 | flags.BoolVar(&flagForce, "f", false, "Force processing even if no change detected") 38 | flags.BoolVar(&flagVerbose, "v", false, "Verbose output") 39 | _ = flags.Parse(strings.Split(envVal, " ")) 40 | 41 | // Run generator 42 | gen := NewGenerator() 43 | gen.Force = flagForce 44 | gen.Printer = &Printer{ 45 | Verbose: flagVerbose, 46 | } 47 | err := gen.Run() 48 | if err != nil { 49 | if flagVerbose { 50 | gen.Printer.Error("%+v", err) 51 | } else { 52 | gen.Printer.Error("%v", err) 53 | } 54 | os.Exit(-1) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /rand/rand_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package rand 18 | 19 | import ( 20 | "regexp" 21 | "testing" 22 | 23 | "github.com/microbus-io/testarossa" 24 | ) 25 | 26 | func BenchmarkRand_AlphaNum64(b *testing.B) { 27 | for b.Loop() { 28 | AlphaNum64(16) 29 | } 30 | // goos: darwin 31 | // goarch: arm64 32 | // pkg: github.com/microbus-io/fabric/rand 33 | // cpu: Apple M1 Pro 34 | // BenchmarkRand_AlphaNum64-10 41181684 27.45 ns/op 16 B/op 1 allocs/op 35 | } 36 | 37 | func TestRand_AlphaNum64(t *testing.T) { 38 | t.Parallel() 39 | assert := testarossa.For(t) 40 | 41 | re := regexp.MustCompile(`^[a-zA-Z0-9]+$`) 42 | for i := 1; i < 1024; i++ { 43 | an64 := AlphaNum64(i) 44 | assert.Len(an64, i) 45 | match := re.MatchString(an64) 46 | assert.True(match) 47 | } 48 | } 49 | 50 | func TestRand_AlphaNum32(t *testing.T) { 51 | t.Parallel() 52 | assert := testarossa.For(t) 53 | 54 | re := regexp.MustCompile(`^[A-Z0-9]+$`) 55 | for i := 1; i < 1024; i++ { 56 | an32 := AlphaNum32(i) 57 | assert.Len(an32, i) 58 | match := re.MatchString(an32) 59 | assert.True(match) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /docs/structure/coreservices-tokenissuer.md: -------------------------------------------------------------------------------- 1 | # Package `coreservices/tokenissuer` 2 | 3 | The token issuer core microservice issues and validates tokens in the form of [JWTs](https://jwt.io/introduction). JWTs enable the authentication of actors and the authorization of their requests based on a set of claims. 4 | 5 | The `IssueToken` endpoint creates a JWT with a set of claims and signs it using the `HMAC-SHA512` algorithm with a configurable `SecretKey`. The `roles` and `groups` claims are [commonly used](https://www.iana.org/assignments/jwt/jwt.xhtml) but the JWT's schema is flexible and claims may be of any valid JSON type. 6 | 7 | ```json 8 | { 9 | "name": "Harry Potter", 10 | "roles": "student wizard", 11 | "groups": ["Gryffindor"], 12 | "whatever": "anything goes here", 13 | } 14 | ``` 15 | 16 | JWTs created by the token issuer core microservice include a `validator` claim with the hostname `tokenissuer.core` to inform the authorization [middleware](../structure/coreservices-httpingress-middleware.md) where to validate the token. 17 | 18 | The `ValidateToken` endpoint checks a JWT for validity and returns the actor associated with it. To be considered valid, the JWT's `iss` claim must match, it must not have expired, and its signature must match either `SecretKey` or `AltSecretKey`. 19 | 20 | The token issuer only serves to manage JWTs. A different microservice, such as the [login example](../structure/examples-login.md) microservice, is responsible for authentication and the association of the JWT with the user. 21 | 22 | You may need to implement a [custom token issuer](../howto/enabling-auth.md#step-2-token-issuer-and-validator) if for example you'd like it to support the revocation of tokens or use a different signature method. 23 | -------------------------------------------------------------------------------- /connector/control_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package connector 18 | 19 | import ( 20 | "context" 21 | "testing" 22 | 23 | "github.com/microbus-io/fabric/pub" 24 | "github.com/microbus-io/testarossa" 25 | ) 26 | 27 | func TestConnector_Ping(t *testing.T) { 28 | t.Parallel() 29 | assert := testarossa.For(t) 30 | 31 | ctx := context.Background() 32 | 33 | // Create the microservice 34 | con := New("ping.connector") 35 | 36 | // Startup the microservice 37 | err := con.Startup() 38 | assert.NoError(err) 39 | defer con.Shutdown() 40 | 41 | // Send messages 42 | for r := range con.Publish(ctx, pub.GET("https://ping.connector:888/ping")) { 43 | _, err := r.Get() 44 | assert.NoError(err) 45 | } 46 | for r := range con.Publish(ctx, pub.GET("https://"+con.id+".ping.connector:888/ping")) { 47 | _, err := r.Get() 48 | assert.NoError(err) 49 | } 50 | for r := range con.Publish(ctx, pub.GET("https://all:888/ping")) { 51 | _, err := r.Get() 52 | assert.NoError(err) 53 | } 54 | for r := range con.Publish(ctx, pub.GET("https://"+con.id+".all:888/ping")) { 55 | _, err := r.Get() 56 | assert.NoError(err) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /env/env_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package env 18 | 19 | import ( 20 | "os" 21 | "testing" 22 | 23 | "github.com/microbus-io/fabric/errors" 24 | "github.com/microbus-io/testarossa" 25 | ) 26 | 27 | func TestEnv_FileOverridesOS(t *testing.T) { 28 | // No parallel 29 | assert := testarossa.For(t) 30 | 31 | os.Chdir("testdata") 32 | defer os.Chdir("..") 33 | 34 | // File overrides OS 35 | os.Setenv("X5981245X", "InOS") 36 | defer os.Unsetenv("X5981245X") 37 | assert.Equal("InOS", os.Getenv("X5981245X")) 38 | assert.Equal("InFile", Get("X5981245X")) 39 | 40 | // Case sensitive keys 41 | assert.Equal("infile", Get("x5981245x")) 42 | assert.NotEqual(Get("X5981245X"), os.Getenv("x5981245x")) 43 | 44 | // Push/pop 45 | Push("X5981245X", "Pushed") 46 | assert.Equal("Pushed", Get("X5981245X")) 47 | Pop("X5981245X") 48 | assert.Equal("InFile", Get("X5981245X")) 49 | err := errors.CatchPanic(func() error { 50 | Pop("X5981245X") 51 | return nil 52 | }) 53 | assert.Error(err) 54 | 55 | // Lookup 56 | _, ok := Lookup("X5981245X") 57 | assert.True(ok) 58 | _, ok = Lookup("x5981245x") 59 | assert.True(ok) 60 | _, ok = Lookup("Y5981245Y") 61 | assert.False(ok) 62 | } 63 | -------------------------------------------------------------------------------- /docs/howto/new-project.md: -------------------------------------------------------------------------------- 1 | # Bootstrapping a New Project 2 | 3 | Follow these steps to create a new project based on the `Microbus` framework. 4 | 5 | #### Step 1: Init the Go Project 6 | 7 | Make a directory to hold your projects files. 8 | 9 | ```shell 10 | mkdir mysolution 11 | ``` 12 | 13 | Init the Go project with the name of the package of your project, for example `github.com/mycompany/mysolution`. 14 | 15 | ```shell 16 | cd mysolution 17 | go mod init github.com/mycompany/mysolution 18 | ``` 19 | 20 | #### Step 2: Code Generate the Project Structure 21 | 22 | Add `Microbus`'s code generator to `go.mod` using: 23 | 24 | ```shell 25 | go get github.com/microbus-io/fabric/codegen 26 | ``` 27 | 28 | Create `doc.go` in the root of the project next to `go.mod`. 29 | 30 | ```go 31 | package root 32 | 33 | //go:generate go run github.com/microbus-io/fabric/codegen 34 | ``` 35 | 36 | Use the code generator to create the project structure. 37 | 38 | ```shell 39 | go generate 40 | ``` 41 | 42 | ``` 43 | mysolution/ 44 | ├── .claude/ # Claude Code setup 45 | │ └── skills/ # Claude Code skills 46 | ├── .vscode/ 47 | │ └── launch.json # VSCode launch file 48 | ├── main/ 49 | │ ├── config.yaml # Configuration file 50 | │ ├── env.yaml # Environment settings 51 | │ └── main.go # Main application 52 | ├── AGENTS-MICROBUS.md # Instructions to coding agents for Microbus 53 | ├── AGENTS.md # Instructions to coding agents for this project 54 | └── CLAUDE.md # Refer Claude to AGENTS.md 55 | ``` 56 | 57 | Fetch the dependencies. 58 | 59 | ```shell 60 | go mod tidy 61 | ``` 62 | 63 | #### Step 3: Create Microservices 64 | 65 | [Create a microservice](../howto/create-microservice.md), rinse and repeat. 66 | -------------------------------------------------------------------------------- /cfg/config.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2023-2025 Microbus LLC and various contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cfg 18 | 19 | import ( 20 | "github.com/microbus-io/fabric/errors" 21 | "github.com/microbus-io/fabric/utils" 22 | ) 23 | 24 | // Config is a property used to configure a microservice. 25 | // Although technically public, it is used internally and should not be constructed by microservices directly. 26 | type Config struct { 27 | Name string 28 | Description string 29 | DefaultValue string 30 | Validation string 31 | Secret bool 32 | 33 | Value string 34 | } 35 | 36 | // NewConfig creates a new config property. 37 | func NewConfig(name string, options ...Option) (*Config, error) { 38 | if err := utils.ValidateConfigName(name); err != nil { 39 | return nil, errors.Trace(err) 40 | } 41 | 42 | c := &Config{ 43 | Name: name, 44 | Validation: "str", 45 | } 46 | err := c.Apply(options...) 47 | if err != nil { 48 | return nil, err 49 | } 50 | return c, nil 51 | } 52 | 53 | // Apply the provided options to the config. 54 | func (c *Config) Apply(options ...Option) error { 55 | for _, opt := range options { 56 | err := opt(c) 57 | if err != nil { 58 | return errors.Trace(err) 59 | } 60 | } 61 | return nil 62 | } 63 | -------------------------------------------------------------------------------- /codegen/bundle/service/intermediate/intermediate-gen.functions.txt: -------------------------------------------------------------------------------- 1 | {{ $shortPackage := .PackagePathSuffix }}{{ range .Functions}} 2 | // do{{ .Name }} handles marshaling for the {{ .Name }} function. 3 | func (svc *Intermediate) do{{ .Name }}(w http.ResponseWriter, r *http.Request) error { 4 | var i {{ $shortPackage }}api.{{ .Name }}In 5 | var o {{ $shortPackage }}api.{{ .Name }}Out 6 | pathArgs, err := httpx.PathValues(r, httpx.JoinHostAndPath("host", `{{ .Path }}`)) 7 | if err != nil { 8 | return errors.Trace(err) 9 | } 10 | err = httpx.DecodeDeepObject(pathArgs, &i) 11 | if err != nil { 12 | return errors.Trace(err) 13 | } 14 | err = httpx.ParseRequestBody(r, &i{{- if .Signature.InputArg "httpRequestBody" }}.{{ CapitalizeIdentifier "httpRequestBody" }}{{ end }}) 15 | if err != nil { 16 | return errors.Trace(err) 17 | } 18 | err = httpx.DecodeDeepObject(r.URL.Query(), &i) 19 | if err != nil { 20 | return errors.Trace(err) 21 | } 22 | {{ range .Signature.OutputArgs }}o.{{ CapitalizeIdentifier .Name }}, {{ end }}err = svc.impl.{{ .Name }}( 23 | r.Context(), 24 | {{- range .Signature.InputArgs }} 25 | i.{{ CapitalizeIdentifier .Name }}, 26 | {{- end}} 27 | ) 28 | if err != nil { 29 | return err // No trace 30 | } 31 | w.Header().Set("Content-Type", "application/json") 32 | {{- if .Signature.OutputArg "httpStatusCode" }} 33 | w.WriteHeader(o.{{ CapitalizeIdentifier "httpStatusCode" }}) 34 | {{- end}} 35 | encoder := json.NewEncoder(w) 36 | if svc.Deployment() == connector.LOCAL { 37 | encoder.SetIndent("", " ") 38 | } 39 | {{- if .Signature.OutputArg "httpResponseBody" }} 40 | err = encoder.Encode(o.{{ CapitalizeIdentifier "httpResponseBody" }}) 41 | {{- else }} 42 | err = encoder.Encode(o) 43 | {{- end }} 44 | if err != nil { 45 | return errors.Trace(err) 46 | } 47 | return nil 48 | } 49 | {{ end}} --------------------------------------------------------------------------------