notification-service
This is a notification service
You can find our high-level overview documents in our documents directory.
Prerequisites
- make
- go 1.21+
- docker latest
- swagger v1.16.3+
- golangci-lint
- gofumpt
- goimports
- mysql
- redis
Preparing the system
In the Makefile there are recipes to more easily handle the project:
Make sure you have installed everything go needs
make install-requirements
Fix or init your vendor dir
make deps
To format your code
make fmt
To then vet it
make vet
To then run linters
make lint
To then create the docs
make docs
You can manually validate the docs by starting a swagger service. Navigate to http://localhost and you are good to go!
docker pull swaggerapi/swagger-ui
docker run -p 80:8080 -e SWAGGER_JSON=$(pwd)/openapi/swagger.json -v $(pwd)/openapi:$(pwd)/openapi swaggerapi/swagger-ui
To then build it, note you can build a specific image, i.e. build-notification-server
build-notification-worker
make build-all
To then test it
make tests
You can also run the entire ci flow
make ci
Running the system
Before running the system make sure you have it configured first. You can run the system either locally or in a container.
- Make sure you have mysql and redis running.
# Add databases and tables
mysql
CREATE DATABASE IF NOT EXISTS `users`;
CREATE DATABASE IF NOT EXISTS `notifications`;
exit
mysql users < scripts/mysql/01-init-users.sql
mysql notifications < scripts/mysql/01-init-notifications.sql
Install the redis stack
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
sudo chmod 644 /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update
sudo apt-get install redis-stack-server
- Run the notification server:
# Run locally
go run cmd/notification-service/main.go
# Or in a container
VERSION=server-v0.0.7
docker network create my_network
docker run -p 12345:8080 --network=my_network -e QUEUE_ENDPOINT=host.docker.internal:6379 -e DB_LOCATION=host.docker.internal -e DB_PORT=3306 -v /app/secrets:/app/secrets lz1marine/notification-service:${VERSION}
- Run the notification worker:
export TYPE=email # or sms
# Run locally
go run cmd/notification-worker/main.go
# Or in a container
VERSION=worker-v0.0.3
docker network create my_network
docker run --network=my_network -e QUEUE_ENDPOINT=host.docker.internal:6379 -e DB_LOCATION=host.docker.internal -e DB_PORT=3306 -v /app/secrets:/app/secrets lz1marine/notification-service:${VERSION}
- Run the garbage collector:
# Run locally
go run cmd/notification-gc/main.go
# Or in a container
VERSION=gc-v0.0.1
docker network create my_network
docker run --network=my_network -e QUEUE_ENDPOINT=host.docker.internal:6379 -e DB_LOCATION=host.docker.internal -e DB_PORT=3306 -v /app/secrets:/app/secrets lz1marine/notification-service:${VERSION}
Examples
After having run the system, you can now play around with it. Here are some examples (note, change the port to 12345 if running the example containers):
email_template='{
"template_id": "1",
"template": "<!DOCTYPE html>\n<html>\n<body>\n <h3>Name:</h3><span>Hello {{.Name}}</span><br/><br/>\n <h3>Email:</h3><span>{{.Email}}</span><br/>\n <h3>Message:</h3><span>{{.Message}}</span><br/>\n</body>\n</html>",
"is_enabled": true
}'
redis-cli -n 10 SET "1" "$email_template"
- Get all of the available notifications and whether they are enabled or not
curl http://localhost:8080/api/v1/notifications --request "GET"
- Get all notifications channels that a specific user has subscribed for
curl http://localhost:8080/api/v1/notifications/sub/1 --request "GET"
- Subscribe user to specific notification channels
curl http://localhost:8080/api/v1/notifications/sub/1 \
--include \
--header "Content-Type: application/json" \
--request "PATCH" \
--data '{"channels":[{"name":"sms","is_enabled":false},{"name":"slack","is_enabled":false}]}'
- Subscribe user to specific notification channels
curl http://localhost:8080/api/v1/notifications/sub/1 \
--include \
--header "Content-Type: application/json" \
--request "PATCH" \
--data '{"channels":[{"name":"sms","is_enabled":false},{"name":"slack","is_enabled":false}]}'
curl http://localhost:8080/api/v1/internal/notifications/123456789 \
--include \
--header "Content-Type: application/json" \
--request "POST" \
--data '{"channel":"email","subject":"A test email","message":"This is a test message","topic_id":"1","template_id":"1"}'
curl http://localhost:8080/api/v1/internal/notifications/987654321 \
--include \
--header "Content-Type: application/json" \
--request "POST" \
--data '{"channel":"sms","message":"This is a test sms message","topic_id":"1"}'
Note: To enable sending a message if using two-factor, go to your google account in https://myaccount.google.com/. Then, search for "App password" and add yourself an app password, then copy it and use it (trim it first).
Configuration
View the notification server configuration.
View the notification worker configuration.
Next steps
Before going to production we have to make sure the following are also completed:
- We should add kubernetes helm charts to be able to deploy the system
- We should add tests to cover at least a percentage of our code/85%?
- We should add Slack channel
- We should handle the state of the message in the db
- We should change our fmt.Print statements with an actual logger
- We should add a Jenkins pipeline