Task managing API for managers and technicians
- What is Supervisor API
- Instructions
- Available Endpoints
- Testing and Coverage
Supervisor API is an API that allows CRUD operations on Tasks. This API leverages role based credentials configured and managed in an external Oauth2 authentication service has access permissions. Existing roles and allowed actions are differentiated by access control:
- Manager
- Create tasks
- Update own tasks
- Fetch any task by task identifier
- List any tasks by query parameters
- Technician
- Create tasks
- Update own tasks
- Fetch own task by task identifier
- List own tasks by query parameters
Available endpoints are show on this document api endpoint section. All endpoints have a CRUD interaction with the MySQL database, but the endpoint responsible by creating a new task also adds an event to the Redis queue (if available). There is no subscriber service to the queue, so in order to monitor queue activity, depending on the environment I suggest using the redis-cli in the redis development Docker container container or redis Docker Compose container.
[x] Task summary is constraint to 2500 characters
[x] Task summary is encrypted on database
[x] Task List endpoints query by "worker_name"
[x] Task List endpoints query by date "after"
[x] Task List endpoints query by date "before"
[x] Use Redis as message broker for newly created tasks
This API uses Auth0, an external authentication service. For testing porpuses, for the default environment variables present in the .env the service will use a set of configured test users.
User | Password | Role | |
---|---|---|---|
Robert | Robert1234 | [email protected] | Manager |
Joseph | Joseph1234 | [email protected] | Technician |
Cassandra | Cassandra1234 | [email protected] | Technician |
Any http client used with this service should use a "Resource Owner Password Credentials" Grant type with the following configurations:
Configuration | Value (for default Auth0 integration) |
---|---|
Username | User email |
Password | Password |
Access Token Url | https://dev-04detuv7.us.auth0.com/oauth/token |
Client ID | AUTH0_CLIENT_ID |
Client Secret | AUTH0_CLIENT_SECRET |
Scope | openid profile email |
Audience | https://dev-04detuv7.us.auth0.com/api/v2/ |
To facilitate the usage of this API an export of Insomnia endpoints configuration is provided in the project.
- Docker Destop running
- Go version 1.17+
Default environment variables are defined in the .env file. In this section I'll explain what they are:
Variable | Default | Description |
---|---|---|
MYSQL_USERNAME | user | DB username |
MYSQL_PASSWORD | password | DB password |
MYSQL_HOSTNAME | localhost | DB address |
MYSQL_PORT | 3306 | DB port |
MYSQL_DATABASE | sh_supervisor | DB name |
AUTH0_DOMAIN | dev-04detuv7.us.auth0.com | auth0 domain address |
AUTH0_CLIENT_ID | fmSt7Lf2b2mQr5LYpsSKglJYMy5YZiJd | auth0 clientID |
AUTH0_CLIENT_SECRET | zw78e03sMF7AqWzQ-ekzTZgqqL93YTxaPwzKxIYNr-KG5aih5eHq2R-rrgy6m-aJ | auth0 client Secret |
AUTH0_PUBLIC_KEY_URL | https://dev-04detuv7.us.auth0.com/.well-known/jwks.json | auth0 public key |
CRYPTO_KEY | skidMAhiçWdh34KlosQLP84GhT62smn | Encryption key for sensitive data |
REDIS_HOST | localhost | Redis address |
REDIS_PORT | 6379 | Redis Port |
REDIS_DB | 0 | Redis DB |
- Launch MySQL docker container (default environment variables already configured)
docker run --name sh_mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -e MYSQL_PASSWORD=password -e MYSQL_DATABASE=sh_supervisor -e MYSQL_USER=user -d mysql:5.7
- Launch Redis docker container
docker run -p 6379:6379 --name queue -d redis
- Git clone
git clone https://github.com/MrBolas/SupervisorAPI.git
- Navigate to folder and fetch external packages
go get -d -v ./...
- Install packages
go install -v ./...
- Build
go build
- Run executable
./SupervisorAPI
The SupervisorAPI configured port is 8080.
To validate incoming notifications we can use:
docker exec -it queue redis-cli -h localhost subscribe notifications
This command subscribes to the topic notifications in redis-cli inside the docker container queue, and will show received messages received for that topic.
- Docker Destop running
Default environment variables are defined in the .env-docker file. In this section I'll explain what they are:
Variable | Default | Description |
---|---|---|
MYSQL_USERNAME | user | DB username |
MYSQL_PASSWORD | password | DB password |
MYSQL_HOSTNAME | db | DB address |
MYSQL_PORT | 3306 | DB port |
MYSQL_DATABASE | sh_supervisor | DB name |
AUTH0_DOMAIN | dev-04detuv7.us.auth0.com | auth0 domain address |
AUTH0_CLIENT_ID | fmSt7Lf2b2mQr5LYpsSKglJYMy5YZiJd | auth0 clientID |
AUTH0_CLIENT_SECRET | zw78e03sMF7AqWzQ-ekzTZgqqL93YTxaPwzKxIYNr-KG5aih5eHq2R-rrgy6m-aJ | auth0 client Secret |
AUTH0_PUBLIC_KEY_URL | https://dev-04detuv7.us.auth0.com/.well-known/jwks.json | auth0 public key |
CRYPTO_KEY | skidMAhiçWdh34KlosQLP84GhT62smn | Encryption key for sensitive data |
REDIS_HOST | queue | Redis address |
REDIS_PORT | 6379 | Redis Port |
REDIS_DB | 0 | Redis DB |
The deployment orchestrated in the docker-compose.yaml. The deployment is composed of three diferent services:
Docker alias | Service Name |
---|---|
supervisorapi | Supervisor API |
db | MySql Database |
queue | Redis |
version: '3'
services:
supervisorapi:
build:
context: .
image: mrbolas/supervisorapi:0.1.0
ports:
- "8080:8080" # http
env_file:
- .env-docker
depends_on:
- db
- queue
restart: on-failure
db:
image: mysql:5.7
ports:
- "3306:3306"
environment:
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: sh_supervisor
volumes:
- db-data:/var/lib/mysql
restart: unless-stopped
queue:
image: redis
restart: always
ports:
- '6379:6379'
volumes:
db-data:
docker-compose up
The SupervisorAPI exposed configured port is 8080.
To validate incoming notifications we can use:
docker exec -it supervisorapi_queue_1 redis-cli -h localhost subscribe notifications
This command subscribes to the topic notifications in redis-cli inside the docker container supervisorapi_queue_1, and will show received messages received for that topic.
- Docker Destop running with K8s active
K8s deployment uses the same environment variables has docker-compose
K8s files are generated by kompose from the docker-compose file.
kompose --file docker-compose.yaml convert
These files are stored in the /k8s directory inside the project.
To deploy the project in Kubernetes navigate to supervisorapi/k8s apply the K8s configuration files generated by Komposer. This will expose the supervisorAPI endpoints on port 30080
kubectl apply -f supervisorapi-pod.yaml,db-data-persistentvolumeclaim.yaml,db-deployment.yaml,db-service.yaml,queue-deployment.yaml,queue-service.yaml,supervisorapi-pod.yaml,supervisorapi-service.yaml
Additionally, it's needed to create a config map for the env-docker file wherre we store the environment variables.
kubectl create configmap env-docker --from-env-file=.env-docker
The Supervisor API endpoints are depicted in the contract.yml according to the standard OpenApi and can be conveniently formated into html in swagger.
Fetches the Task with ID sent as Path parameter.
- Access:
- Manager:
- Technician: Can only access own tasks
- Verb: Get
- Parameters
- id: /v1/tasks/{task-id}
- format: uuid
- id: /v1/tasks/{task-id}
- Responses:
- 200:
- body:
{ "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "worker_name": "string", "summary": "string", "date": "string" }
- body:
- 401:
- 404:
- 200:
Fetches list of Tasks filtered by query parameters.
-
Access:
- Manager:
- Technician: Can only access own tasks
-
Verb: Get
-
Parameters
- worker_name: /v1/tasks?worker_name={worker_name}
- before: /v1/tasks?before={before_date}
- format: "2022-05-23 15:33:01"
- after: /v1/tasks?after={after_date}
- format: "2022-05-23 15:33:01"
- page: /v1/tasks?page={page_number}
- page_size: /v1/tasks?page_size={page_size_number}
- sort_by: /v1/tasks?sort_by={sort_field}
- sort_order: /v1/tasks?sort_order={sort_order}
-
Responses:
- 200:
- body:
{ "data": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "worker_name": "string", "summary": "string", "date": "string" } ], "metadata": { "page": 0, "page_size": 0 } }
- body:
- 401:
- 404:
- 200:
Creates a new Task and sends an event to queue.
- Access:
- Manager:
- Technician:
- Verb: Post
- Body:
{ "summary": "string", "date": "string" }
- Responses:
- 201:
- body:
{ "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "worker_name": "string", "summary": "string", "date": "string" }
- body:
- 400:
- 401:
- 409:
- 201:
Updates a Task by Id.
- Access:
- Manager:
- Technician: Can only access own tasks
- Verb: Put
- Parameters
- id: /v1/tasks/{task-id}
- format: uuid
- id: /v1/tasks/{task-id}
- Body:
{ "summary": "string", "date": "string" }
- Responses:
- 200:
- body:
{ "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "worker_name": "string", "summary": "string", "date": "string" }
- body:
- 400:
- 401:
- 404:
- 409:
- 200:
Deletes a Task.
- Access:
- Manager:
- Verb: Delete
- Parameters
- id: /v1/tasks/{task-id}
- format: uuid
- id: /v1/tasks/{task-id}
- Responses:
- 204:
- 401:
- 404:
- 409:
This code repository test coverage for the api codebase. There are several unit tests covering the code base. Additionaly there are integration tests for the MySql Database using Dockertest and Testify. To run the test in code coverage:
go test ./... -cover
Currently the output for the test cover:
? github.com/MrBolas/SupervisorAPI [no test files]
? github.com/MrBolas/SupervisorAPI/api [no test files]
ok github.com/MrBolas/SupervisorAPI/auth (cached) coverage: 31.0% of statements
ok github.com/MrBolas/SupervisorAPI/encryption (cached) coverage: 82.6% of statements
ok github.com/MrBolas/SupervisorAPI/handlers (cached) coverage: 76.6% of statements
ok github.com/MrBolas/SupervisorAPI/models (cached) coverage: 85.0% of statements
ok github.com/MrBolas/SupervisorAPI/repositories (cached) coverage: 79.7% of statements