Skip to content

feat: add RabbitMQ message broker node type with security policy enfo…#49

Open
NureniJamiu wants to merge 350 commits into
Derssa:mainfrom
NureniJamiu:feat/add-rabbitmq-node
Open

feat: add RabbitMQ message broker node type with security policy enfo…#49
NureniJamiu wants to merge 350 commits into
Derssa:mainfrom
NureniJamiu:feat/add-rabbitmq-node

Conversation

@NureniJamiu

@NureniJamiu NureniJamiu commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Description

This PR implements and integrates the RabbitMQ message broker node type into the system architecture canvas.

closes #45

Why is this needed?

Previously, users were unable to practice designing systems with asynchronous queues, publish-subscribe topologies, or message routing keys on the canvas. Adding a dedicated RabbitMQ broker node enables these learning flows with an integrated management dashboard and interactive cheat sheets.


Key Features

  1. Official RabbitMQ Integration: Pulls and provisions rabbitmq:3-management containers, enabling the AMQP protocol on port 5672 and the HTTP management web interface on port 15672.
  2. Network Bridge Persistence: Adjusts the dockerNetworkProvider.ts policy mapping so RabbitMQ containers retain their connection to the default akal-lab-network bridge. This prevents port forwarding/mapped host links (http://localhost:<mapped_port>) from being disconnected by subnet isolation policies.
  3. Interactive Inspection Modal: Features a two-tab drawer (RabbitMqModal.tsx):
    • Details: Exposes node state, dynamic console ports, default administrative credentials (guest / guest), and a launch button.
    • Cheat Sheet: Explains core concepts (Exchanges, Queues, Bindings) and provides copy-pasteable client code snippets for Node.js (amqplib) and Python (pika).
  4. UX Tooltips & Connection Warnings:
    • Includes a state-driven, instant hover tooltip built with React next to the inbound firewall warning directing users where to configure security rules.
    • Alerts users of container boot latency (~15 seconds) and the list of ports that must be opened in security groups (port 15672 for host console access, and port 5672 for client applications in other subnets).
  5. Security Group Validation: Registers rabbitmq as a sensitive infrastructure type in the architectureValidator.ts engine, flagging warnings if placed in a public subnet or directly exposed to 0.0.0.0/0.

Changed Files

Backend

  • backend/src/infrastructure/docker/ContainerManager.ts (RabbitMQ image constants, pull helper, and container options configuration)
  • backend/src/modules/network/providers/dockerNetworkProvider.ts (Bridged network policy retention and reconnect exemptions)

Frontend

  • frontend/src/features/nodes/RabbitMqNode/RabbitMqNode.tsx [NEW] (RabbitMQ card component composing BaseNode layout)
  • frontend/src/features/nodes/RabbitMqNode/RabbitMqModal.tsx [NEW] (Inspector overlay with details, warnings, and code cheat sheets)
  • frontend/src/features/nodes/RabbitMqNode/data/rabbitmqCheatSheet.json [NEW] (Concepts definitions and client developer snippets)
  • frontend/src/pages/CanvasPage/components/NodeLibrary.tsx (Added a new "Message Brokers" category for palette placement)
  • frontend/src/pages/CanvasPage/CanvasPage.tsx (Wired node type hooks, inspected modals hooks, drop defaults)
  • frontend/src/shared/types/index.ts (Extended ContainerData type union to include 'rabbitmq')
  • frontend/src/shared/utils/architectureValidator.ts (Added rabbitmq type to sensitiveTypes array)

Localization / Resources

  • frontend/src/locales/en.json (English translation keys for tabs, labels, and tooltips)
  • frontend/src/locales/fr.json (French translation keys matching English specifications)

Pull Request Checklist

  • type string is lowercase and identical across palette, nodeTypes, API, labels, and unions.
  • Backend: image tag, ensure<X>Image(), image selection branch, port mapping, ContainerInfo union.
  • Frontend: <X>Node.tsx (via BaseNode), nodeTypes, NodeLibrary, ContainerData union, drop placeholder.
  • Inspector modal & backend explorer wired (or intentionally omitted).
  • Both frontend and backend build; tests pass.
  • Manually verified the full lifecycle.
  • Manually ran npm run lint on frontend & backend and verified that there are no lint warnings
  • Conventional Commit message.

Derssa and others added 30 commits June 18, 2026 14:51
…te-then-insert pattern to prevent Docker bridge override
…s and display subnet details in node options
OthmaneZ05 and others added 27 commits July 13, 2026 10:42
…-validation

Feature/cidr persistence and validation
* feat(backend): add roadmap format JSON Schema (schemaVersion 1) and TS types

* feat(roadmaps): add reference example roadmap

* feat(backend): add roadmap schema validation function, tests and CLI

* feat(frontend): add roadmap types (documented copy of backend source of truth)

* docs: add roadmap format reference (fields, validators, i18n, versioning policy)
* refactor(frontend): unify network topology types in shared/types/network.ts

* refactor(frontend): extract canvas grid and hit-test geometry into pure canvasGeometry module

* refactor(frontend): extract security-rule and firewall-edge logic into pure securityRules module

* refactor(frontend): extract network config transforms into pure networkConfigOps module

* refactor(frontend): move network config state, save path and audit into useNetworkConfig hook

* refactor(frontend): move drag/drop/delete canvas handlers into useCanvasDragDrop hook

* refactor(frontend): consolidate the six inspector modal states into one InspectorState union

* refactor(frontend): relocate the canvas modal blocks into CanvasModals and CreateNodeModal
…dals (Derssa#56)

* feat(frontend): add shared DB inspector building blocks (modal shell, tabs, explorer hook)

* refactor(frontend): rebuild the Postgres/NoSql/Redis inspector modals on the shared components

Deduplicates the three near-identical modals (~3700 lines down to ~800 plus
shared components): identical shell/tabs/styles/fetch-retry/cheat-sheet/query
console now live in features/nodes/components. The genuinely per-DB parts
(simulation topologies, query handlers, explorer shapes) stay per node.

Behavior changes (approved): the NoSql explorer gains the Retry button the
other two already had, and the Postgres/NoSql startup auto-retry timers no
longer leak or stack (they adopt the Redis retryTimerRef pattern via
useExplorerData).
* feat(learning): add the validator execution engine

Runs the declarative validators of a roadmap step against the real state
of the project's containers. Dispatch by type through a single registry,
per-validator error isolation (an unknown type, invalid params or an
unreachable Docker daemon produce an 'error' result for that validator
and the others still run), infrastructure errors classified through the
existing dockerErrors taxonomy, and a lazy memoized container list (one
Docker call per step run). Ships the first validator, container_running.

* feat(learning): expose roadmap loading and step validation over REST

- GET /api/learning/roadmaps — catalogue of the valid roadmap files
  found in roadmaps/ (invalid files are logged and never served)
- GET /api/learning/roadmaps/:id — full roadmap for the player
- POST /api/learning/validate — runs every validator of a step for a
  project and returns one structured result per validator
  ({status, message, errorCode?, expected?, observed?} + stepPassed)

Roadmap files are re-read on each request (hot reload for authors) and
resolved from __dirname, never process.cwd(): the CLI spawns the server
without a cwd. Infrastructure failures answer 200 with per-validator
'error' results — 4xx/5xx are reserved for request problems.

* chore: ship the roadmaps directory in the published npm package

The learning engine loads roadmap files from roadmaps/ at the repo
root; without this entry the published CLI would start with an empty
catalogue.

* docs: document the learning validation API

Contract of the three /api/learning endpoints for the player (P-1/P-2):
pass/fail/error semantics and their intended UI mapping, errorCode
table, the 'Docker down answers 200 with error results' policy, a curl
walkthrough (pass and fail) against the example roadmap, and the recipe
for adding a validator type.
Implements the 7 remaining validator types (table_exists, redis_key_exists,
mongo_collection_exists, edge_exists, lb_upstreams, port_denied,
asg_replicas) alongside the existing container_running, so roadmap steps
can check real Postgres/Redis/Mongo state, network connectivity and ASG
replica counts, not just container liveness.

Reuses existing infrastructure rather than duplicating it: DB validators go
through containerProvider's exec* commands (same idiom as the explorers),
edge_exists/port_denied reuse NetworkService's security-group rule
expansion (now exposed publicly) instead of re-deriving connectivity, and
asg_replicas/lb_upstreams read directly off ContainerInfo's asgId/isAsgInstance
fields. A shared resolveRunningContainer/resolveSourceAndTarget helper keeps
node targeting and pedagogical fail messages consistent across validators.

Each validator ships with pass/fail/degraded-case unit tests, and the
existing example roadmap already exercises 4 of them end to end.
…eal containers (Derssa#60)

* test(learning): integration suite for the 8 validators against real containers

Unit tests mock every Docker/DB call, so they prove validator logic but never
contact with reality (container timing, DB readiness, real ASG label
resolution). Adds engine.itest.ts: one disposable project with real
containers, run through runStepValidators' default (real) dependencies for
all 8 validators, pass and fail, from a single static fixture so nothing is
mutated between assertions.

* fix(learning): create the shared Docker network if missing in integration tests

CI failed with "network akal-lab-network not found": createContainer attaches
every container to that network, but it's normally created once at server
startup (DockerInitializer.ensureSharedNetwork) and this suite never boots the
server, so a fresh Docker daemon doesn't have it yet.
* fix(learning): 400 on missing JSON body and deterministic (id, language) roadmap selection

Two API fixes ahead of the roadmap player (its first real consumer):

- POST /api/learning/validate without a JSON Content-Type left req.body
  undefined, so the destructuring threw and the endpoint answered 500;
  it now falls through the existing per-field checks and returns 400.
- Translations share a roadmap id and differ by language, so
  getRoadmap(id) returned whichever file readdir listed first and the
  selection was nondeterministic. The key is now (id, language):
  GET /roadmaps/:id accepts ?language= (exact match or 404), the
  language-less form picks deterministically (sorted), and /validate
  stays language-neutral since steps and validators are shared across
  translations. Contract documented in docs/learning-api.md.

Also fixes the example roadmap's first hint: the node library sits on
the right side of the canvas, not the left.

* feat(learning): roadmap player side panel (P-1)

New frontend/src/features/learning: a sidebar that turns the empty
canvas into a guided session. It lists the roadmap catalogue
(GET /api/learning/roadmaps), opens a roadmap by (id, language), shows
every step with the current one highlighted, and a Validate button that
runs POST /api/learning/validate against the real containers and
renders the per-validator report (raw rendering for now — P-2 owns the
rich pass/fail/error presentation).

- useLearningPlayer holds the play-through state: clamped navigation,
  per-step results kept in memory when navigating (persistence is P-4),
  a ref-based guard so double-clicking Validate sends one request.
- Network failures render inline with a retry action; per the learning
  API contract, non-2xx is a request/server problem and is never shown
  as a learner failure.
- Minimal CanvasPage surface: one showLearning state, one topbar
  button, one conditional sibling in the body row. Closed panel means
  nothing is mounted and no learning endpoint is touched (tested).
- Labels in en/fr via i18next; styling on the shared CSS variables.

* refactor(learning): apply self-review findings on the player

- Render RoadmapCatalog at a single JSX position so a failed roadmap
  load no longer remounts it (which re-fired its catalogue fetch).
- Lift readErrorMessage to shared/utils and reuse it from
  useContainers and useLearningPlayer instead of duplicating it.
- Guard openRoadmap against out-of-order resolutions (latest request
  wins) and against a malformed 200 body (steps must be a non-empty
  array) so a bad payload surfaces as a load error, not a render crash.
- estimatedMinutes uses a null check: a value of 0 rendered a stray
  "0" text node in the catalogue card.
- Pluralize the step-count label (steps_one/steps_other) so a
  single-step roadmap doesn't read "1 steps".
- Name the requested language in the 404 when a roadmap id exists but
  the translation doesn't, instead of claiming the id is unknown.
- Derive Previous/Next bounds once (atFirstStep/atLastStep).
* fix(learning): restrict edgeExists and portDenied validators to inbound rules

* docs(learning): align roadmap instructions with UI node labels

* feat(learning): add http_get_contains validator, copy block actions, and step 5 instructions

* fix(learning): resolve TypeScript compilation errors in frontend and backend tests

* test(learning): fix integration tests security group configuration to use inbound target rules
…states (Derssa#64)

* feat(learning): pedagogical validation feedback with pass/fail/error states

* refactor(learning): centralize status presets and apply review findings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add support for RabbitMQ message broker node

3 participants