ri-redis-hackathon-2021
Configuration-as-a-Service (CaaS)
CaaS provides a service-oriented-architecture for configuring templates containing default application settings. Once a settings template is defined and saved to the Redis Data Store, any client (of any type, game, web application, thick client, etc) can retrieve a default settings template to drive default behavior within the application. Users of the application can change the values as desired and save their own versions of the template to satisfy personal customizations needs.
Another valueable use-case of this service could be in the deployment of microservices. An Administrator could define application settings templates per environment that the microservice could then retrieve over HTTP for real-time service configuration.
Finally, the CaaS API provides real-time template updates over a websocket so connected clients can be notified in real-time about any settings template modifications made by an Administrator.
The React UI is fronted by an NGINX service. The UI talks directly to a SpringBoot microservice to perform authentication against the Keycloak service as well as to perform CRUD operations against the Redis microservice.
We use JRedisJSON (https://github.com/RedisJSON/JRedisJSON) in the SpringBoot API to perform the following operations against the Redis instance:
- JSON.DEL
- JSON.GET
- JSON.SET
- JSON.TYPE
- PUBLISH
- SUBSCRIBE
- James Caple
- Brandon Beiler
- Eric Offermann
- Brian Broerman
Redismod Github: https://github.com/RedisLabsModules/redismod
Redis-Insight GUI: https://redislabs.com/redis-enterprise/redis-insight/
cd redis
docker-compose up- Download RedisInsight from the link above
- Install and run the app.
- Navigate to http://localhost:8001.
- Select "I already have a database"
- Select "Connect to a Redis Database using hostname and port"
- Enter the following values
- host: localhost
- port: 6379
- name: anything you want here
- Now, select the redis database you just created in the UI
Make sure REDIS docker container is started first as the API service will try to connect to it.
cd api
gradle build
gradle bootRunPostman scripts are in the postman directory.
Swagger UI: http://localhost:8081/swagger-ui.html
POST http://localhost:8081/api/v1/admin/template/create
{
"settingsId": "James",
"templateName": "Test",
"templateSettings": {
"first_name":"fname",
"last_name":"lname"
}
}
POST http://localhost:8081/api/v1/users/auth
{
"username": "hackerboi",
"password": "zer0daylulz"
}
Response:
{
"username": "hackerboi",
"password": "zer0daylulz",
"authenticated": true,
"jwt": "35434534kjdfzgkjdfg"
}
To enable security on /api/v1/admin API endpoints, uncomment the following line in the SecurityConfiguration.java file:
//.antMatchers("/api/v1/admin/**").authenticated()
API requests will then require a Bearer Token header with a valid JWT Token as a value.
Keycloak docker compose and configuration artifacts are in the keycloak directory.
- Make the keycloak directory your working dir.
- Make the 'kcdb' directory to persist keycloak data in:
mkdir kcdbchmod -R 777 kcdb
- Set admin credentials in environment variables:
export kcadmin=adminexport kcadmin_password=admin
- Start the keycloak docker container
docker-compose up
- Navigate web browser to http://localhost:8080
- Log in as admin
- Click 'Add Realm' to add the CaaS Realm
- Import the CaaS Realm from the caa-real-export.json file in this directory to create the realm.
- Create a user account and set the password in the Credentials Tab (turn off Temporary)
- The Authentication and JWT Verify Token API Endpoints examples are postman scripts in ./api/postman.
Running below should start the react app on port 3000
cd app
npm install
npm startIn the /app dir, there is a Dockerfile and docker-compose.yml.
Open the docker-compose.yml and point to this directory in the volume mount.
You can auto build/start this by running.
cd /app
sh local_run.sh
You can now use websocket to subscribe to Template updates and receive updates as they occur in real-time. On update, a JSON string object is sent to subscribers in the CaaSTemplateUpdate class format:
CaaSTemplateUpdate
{
"settingsId": "caas_dev_c779f6be_e58b_4b23_b085_037c8c47f5d2",
"name": "new template name",
//what was the name updated to
"templateSettings": {
//object with key-values for which settings updated
"setting1": "newSettingValue",
"setting9": "anotherNewValue"
},
"updateType": TemplateUpdateType,
"updateField": TemplateUpdateField
}
TemplateUpdateType Enum{
NAME,
SETTINGS,
OBJECT
}
TemplateUpdateField Enum{
CREATE,
UPDATE,
DELETE
}The websocket endpoint sits at: /api/v1/updates
Query Parameters are used in the connection string to configure the update listener. Some are required and some are optional.
| Query Param | required? | Description | Accepted Values |
|---|---|---|---|
| settingsId | yes | a single template settingsId to track (maybe multiple in the future) | a single settingsId string |
| templateUpdateField | no | The fields to listen for for updates. Comma-seperated for multiple. Empty listens for all changes | NAME, SETTINGS, OBJECT |
| templateUpdateType | no | What type of updates to listen for, such as create, update, and or delete. Comma-seperated for multiple. Empty listens for all changes | CREATE, UPDATE, DELETE |
Example Websocket Connection
| Query Param | Value |
|---|---|
| settingsId | caas_dev_c779f6be_e58b_4b23_b085_037c8c47f5d2 |
| templateUpdateField | NAME,SETTINGS |
| templateUpdateType | CREATE,UPDATE |
ws://localhost:8081/api/v1/updates?templateUpdateType=CREATE%2CUPDATE&templateUpdateField=NAME%2CSETTINGS&settingsId=caas_dev_c779f6be_e58b_4b23_b085_037c8c47f5d2- Build the UI docker image
- See steps above to ensure the code successfully built
- docker build -t caas-ui:latest .
- Build the API docker image
- Ensure the java project is successfully built
- docker build -t caas-api:latest .
- Run docker-compose to bring up the stack
- docker-compose -f caas-docker-stack.yml up -d