Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Floor Control API

A simple REST API for managing the "floor" (who's allowed to talk) in a push-to-talk radio group. Only one user can hold the floor per group at a time. If a holder doesn't release it manually, it auto-releases after a timeout.

Files

  • openapi.yaml — the API spec (contract). Describes the two endpoints, their inputs/outputs, and status codes. Not read by the code at runtime — it's the blueprint the server is built to match.

  • server0.js — the actual server, written in plain Node.js (no frameworks/libraries). Implements:

    • POST /groups/{groupId}/floor — obtain the floor. Returns 200 on success, 400 if userId is missing/invalid, 409 if someone else already holds it.
    • DELETE /groups/{groupId}/floor/{userId} — release the floor. Returns 200 on success, 403 if that user doesn't currently hold it.
    • State is kept in-memory (a Map of groupId -> { userId, timer }), reset whenever the server restarts.
    • Floor timeout: each obtain starts a 30s timer (FLOOR_TIMEOUT_MS) that auto-releases the floor if nobody releases it manually. Releasing manually cancels the timer.
  • test.sh — automated test script. Starts the server, sends a sequence of requests with curl, and checks the returned HTTP status codes match what's expected (200 → 409 → 403 → 200). Exits non-zero if any check fails — this is what CI runs.

  • Dockerfile — recipe to package the app into a container image: starts from a Node.js base image, copies server0.js in, and runs node server0.js on container start.

  • .github/workflows/ci.yml — GitHub Actions workflow. On every push or pull request, spins up a clean Ubuntu VM, checks out the code, installs Node, and runs test.sh. Fails the build if tests fail.

  • k8s-deployment.yaml — Kubernetes manifest with two objects:

    • a Deployment running one replica of the floor-control-api image on port 8080 (imagePullPolicy: Never, since the image is loaded locally rather than pulled from a registry)
    • a Service (NodePort) that exposes it inside the cluster on port 8080

Run locally

node server0.js

Server listens on http://localhost:8080.

Run tests

chmod +x test.sh
./test.sh

Run with Docker

docker build -t floor-control-api .
docker run -p 8080:8080 floor-control-api

Run on a local Kubernetes cluster (kind)

Requires Docker and kind, and kubectl.

# 1. Create a local cluster (one-time, unless already created)
kind create cluster --name floor-control

# 2. Build the image
docker build -t floor-control-api:latest .

# 3. Load the image into the kind cluster
#    (kind runs its own isolated container runtime, so it can't see
#    images that only exist in your regular Docker until you load them)
kind load docker-image floor-control-api:latest --name floor-control

# 4. Deploy
kubectl apply -f k8s-deployment.yaml

# 5. Check the pod is running
kubectl get pods

# 6. Forward a local port into the cluster so you can reach it
kubectl port-forward service/floor-control-api 8080:8080

With port-forward running, http://localhost:8080 behaves the same as running the container directly with Docker.

After changing code, redeploy with:

docker build -t floor-control-api:latest .
kind load docker-image floor-control-api:latest --name floor-control
kubectl rollout restart deployment floor-control-api

Useful commands:

kubectl get pods                          # pod status / restart count
kubectl logs -l app=floor-control-api     # container logs
kubectl logs -l app=floor-control-api -f  # follow logs live
kubectl describe pod -l app=floor-control-api  # crash reasons, events

Tear down:

kubectl delete -f k8s-deployment.yaml
kind delete cluster --name floor-control

Test it

# Obtain the floor
curl -X POST http://localhost:8080/groups/group-alpha-123/floor \
  -H "Content-Type: application/json" -d '{"userId":"user-456"}'

# Release the floor
curl -X DELETE http://localhost:8080/groups/group-alpha-123/floor/user-456

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages