diff --git a/README.md b/README.md index 018882b6..12b8167a 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,9 @@ You can read more details about it in our series of blog posts - [100X Faster: How We Supercharged Netflix Maestro's Workflow Engine](https://netflixtechblog.com/100x-faster-how-we-supercharged-netflix-maestros-workflow-engine-028e9637f041) - [Incremental Processing using Netflix Maestro and Apache Iceberg](https://netflixtechblog.com/incremental-processing-using-netflix-maestro-and-apache-iceberg-b8ba072ddeeb) +## Architecture +- High-level architecture diagram: [`docs/architecture.md`](docs/architecture.md) + # Get started ## Prerequisite - Git @@ -55,6 +58,44 @@ You can read more details about it in our series of blog posts - `curl --header "user: tester" -X POST 'http://127.0.0.1:8080/api/v3/workflows' -H "Content-Type: application/json" -d @maestro-server/src/test/resources/samples/sample-kubernetes-wf.json` - `curl --header "user: tester" -X POST 'http://127.0.0.1:8080/api/v3/workflows/sample-kubernetes-wf/versions/latest/actions/start' -H "Content-Type: application/json" -d '{"initiator": {"type": "manual"}}'` + +## Local debugging tips (macOS / VS Code) +- Ensure Java 21 is selected in your IDE/workspace runtime. +- If debug startup fails with security-manager errors, add VM arg: `-Djava.security.manager=allow`. +- If startup fails with `Port 8080 was already in use`, stop the existing process: `lsof -nP -iTCP:8080 -sTCP:LISTEN`. +- Verify server health before API calls: `curl -v http://127.0.0.1:8080/actuator/health` (expect `{"status":"UP"}`). + +## Minimal one-step workflow example +Create `tiny-wf.json`: + +```json +{ + "properties": { + "owner": "tester", + "run_strategy": "sequential" + }, + "workflow": { + "id": "tiny-wf-1", + "name": "Tiny Workflow", + "description": "One-step NoOp workflow", + "steps": [ + { + "step": { + "id": "job.1", + "type": "NoOp", + "transition": {} + } + } + ] + } +} +``` + +Create and run it: +- `curl --header "user: tester" -X POST 'http://127.0.0.1:8080/api/v3/workflows' -H "Content-Type: application/json" -d @tiny-wf.json` +- `curl --header "user: tester" -X POST 'http://127.0.0.1:8080/api/v3/workflows/tiny-wf-1/versions/latest/actions/start' -H "Content-Type: application/json" -d '{"initiator":{"type":"manual"}}'` +- `curl -X GET 'http://127.0.0.1:8080/api/v3/workflows/tiny-wf-1/instances/1/runs/1'` + ## Python SDK client ### Installation @@ -119,3 +160,6 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +## Contributing this change upstream +For step-by-step instructions to open a PR against `Netflix/maestro`, see [`docs/raise-pr.md`](docs/raise-pr.md). diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 00000000..14086423 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,65 @@ +# Maestro Architecture Overview + +This repository is a multi-module Gradle project for **Maestro**, a workflow orchestration platform. +At runtime, `maestro-server` composes the core engine, persistence, trigger systems, and pluggable step runtimes. + +## What the repo does (high-level) + +- Exposes REST APIs to register workflows, start runs, inspect state, and operate instances. +- Stores workflow definitions, instances, and execution metadata in SQL-backed persistence. +- Executes workflows through a DAG/flow engine with internal queue-based job dispatch. +- Supports trigger-driven starts (time-based and signal-based). +- Supports pluggable runtime executors for step types (e.g., Kubernetes, HTTP). +- Includes optional AWS integrations (SQS/SNS based producers/queues). + +## Architecture picture + +```mermaid +flowchart TB + U[Users / SDK / CI] --> API[maestro-server\nSpring Boot API + wiring] + + API --> DSL[maestro-dsl\nWorkflow DSL parsing] + API --> ENG[maestro-engine\nWorkflow orchestration] + API --> TRIG[maestro-timetrigger + maestro-signal\nTrigger processing] + API --> RT[Runtime Modules\nmaestro-kubernetes / maestro-http] + + ENG --> FLOW[maestro-flow\nIn-memory flow progression] + ENG --> Q[maestro-queue\nDB-backed internal job queue] + ENG --> SEL[netflix-sel\nExpression evaluation] + ENG --> DB[maestro-database\nDAO + JDBC layer] + + TRIG --> DB + Q --> DB + API --> DB + DB --> SQL[(Postgres / CockroachDB)] + + RT --> EXT[External systems\nKubernetes API / HTTP endpoints] + + AWS[maestro-aws\nOptional AWS adapters] -. provides .-> TRIG + AWS -. provides .-> Q +``` + +## Module map + +- **maestro-server**: app entrypoint, Spring configuration, REST controllers, request interceptors. +- **maestro-engine**: workflow runtime logic, job processors, action handlers, orchestration services. +- **maestro-flow**: high-performance flow progression primitive used by engine. +- **maestro-queue**: internal queue abstraction and workers for asynchronous event/job handling. +- **maestro-signal**: signal trigger/dependency model, DAOs, processors, queue producer interfaces. +- **maestro-timetrigger**: delayed trigger scheduling and execution processing. +- **maestro-database**: DB abstraction and shared JDBC helper/DAO support. +- **maestro-dsl**: workflow DSL model + parsing. +- **netflix-sel**: sandboxed expression language used in dynamic parameters/conditions. +- **maestro-kubernetes / maestro-http**: step runtime implementations. +- **maestro-aws**: optional implementations using AWS services (e.g., SNS/SQS). +- **maestro-common**: shared models, validation, utility classes, and exceptions. + +## Typical execution path + +1. Client submits workflow definition or action through `maestro-server` REST APIs. +2. Workflow definition is parsed/validated (`maestro-dsl`, `maestro-common`). +3. Engine persists state and enqueues/internal-dispatches job events (`maestro-engine`, `maestro-queue`, `maestro-database`). +4. Flow progression executes steps (`maestro-flow`), evaluating expressions via `netflix-sel`. +5. Step runtimes execute against external systems (`maestro-kubernetes`, `maestro-http`, etc.). +6. Trigger modules (`maestro-timetrigger`, `maestro-signal`) can start new runs or unblock steps. + diff --git a/docs/raise-pr.md b/docs/raise-pr.md new file mode 100644 index 00000000..39ba7743 --- /dev/null +++ b/docs/raise-pr.md @@ -0,0 +1,36 @@ +## Raise this change as a GitHub PR + +You cannot open a PR directly from this environment unless your GitHub credentials are configured with push access. +Use this standard fork-and-PR flow against `https://github.com/Netflix/maestro`: + +1. Fork `Netflix/maestro` on GitHub to your account. +2. Add your fork as `origin` and Netflix repo as `upstream`: + ```bash + git remote rename origin upstream + git remote add origin git@github.com:/maestro.git + ``` +3. Push your current branch: + ```bash + git push -u origin $(git branch --show-current) + ``` +4. Open a PR in GitHub UI: + - Base repo: `Netflix/maestro` + - Base branch: `main` + - Compare repo: `/maestro` + - Compare branch: your pushed branch +5. Reuse this PR title/body: + - **Title:** `Add architecture overview and diagram for the Maestro repository` + - **Body:** summarize motivation, docs added, and testing notes. + +### Optional: create PR via GitHub CLI + +If you have `gh` authenticated: + +```bash +gh pr create \ + --repo Netflix/maestro \ + --base main \ + --head :$(git branch --show-current) \ + --title "Add architecture overview and diagram for the Maestro repository" \ + --body "Add architecture overview docs and Mermaid diagram; include validation notes." +```