The Ultimate Application Config tool:
A Realtime SDK and Web Admin Solution
What's the first task we're assigned to when we join any project?
Setup our Development Environment (Yeah!...)
Ok. We've configured our local DB host, port, adjusted file paths, ENV VARS, services URLs..
we've all been there. And the problem is we're still there!
We start our server - get our first exceptions - and the cycles of "Adjust - Restart" to find out we missed some paths, "max-this", "max-that" -
Configurations!...
But we're heroes! eventually. We nail it, start our server and stair with jaw dropped at the log:
"...Dude, you did it! Server successfully started at 3:12am. Go home!".
Great :)
Next morning we want to run some tests. (Yeah!...)
But, now what? Unit Tests works on different DB so the main will not get dirty.
Integration Tests run against different service URLs and file paths like those deployed on a Staging or QA machine.
The "standard" solution - Let the server read its configuration from a file. In SpringBoot for example: application.properties
But how to read those properties? What is the format the keys and values must comply to?
YAML format must have the correct indentation!
application.proprties has the format "key: value"
And, I don't want to talk about XMLs. No Sir!
Gladly I'll SKIP that as we'll see shortly how to completely avoid config files all together!
So, let's even assume we have some "util" class that read and get config values by their key name.
For example:
MyConfig cfg = MyConfig.getInstance();
String dbHost = cfg.get("dbHost");
int dbPort = cfg.getInt("dbPort"); // Also e.g: cfg.getTimestamp("modifiedAt");
That's Nice! We prepare different config files per environment or running mode like main, unit tests, CICD Pipeline Integration Tests, etc.
Changing Config Values
But, what if we want to change a config value due to external service URL or API that recently changed?
For example:
Key : user-service.health-api
Value: https://staging.acme-hospital.com/api/is-ready/
Value Changed to:
https://qa-1.acme-hospital.com/api/is-alive/
No problem - we modify the URL value in the config file, restart the server and our config class will get the new value.
Can we do that WITHOUT restarting our server? Yes!. Let's improve it:
No Restarts
We can either:
- Option A: Reload the config file on every "get" call. Latest value on any "get".. but read the entire file everytime?
- Option B: Periodically realod it, say every minute or every 20 seconds, depending on how fast we want changes to our configs to take effect.
Not bad, we now don't have to restart the server! but performance is bad.
Can we get the latest config value, without restart and better performance? Sure! Let's improve:
Better Performance
We can either:
- Option A: Implement some cache or use some cache library so only when the config file changes, it will be reloaded.
- Cache is great! unless we expect config changes frequently.
- Option B: Save the config data in DB. Fetch specific values by their key-name. And use some cache library.
- "Much better! thank you" we fetch only specific values only and with a cache library we took care for performance.
Concurrent Config Access
What if multiple users modify the config item? Will the file be corrupted or the latest update overrides correctly?
- With file system files, it's unclear in what mode the file is opened, but we can assume our server opened it as ReadOnly.
- With DB, we need to make sure writes are done in a DB Transaction, and setting correctly the "Isolation Level" allows us to read values only when transaction is completed.
Permissions
What about permissions?
- Anyone in your team can write to the config file?
- Any config values you wish to hide from specific teams or specific memebers in your team?
- Any config values you wish only DevOps should be allowed to read or even know they exists?
So, with DB we can define roles, but we need to split them into teams so QA and Dev teams can both access the DB, but should not access each other team's config values.
We can probably define that resolution in modern DBs.
But, were can we maintain all that?
- The cache behavior, the permissions, the multiple environments, multiple teams, etc?
So we want a Config Class, that always have the latest config values, without performance costs, with permissions based on right user role, team and environment to access, with a centralized web page that users can modify config items, based on their role, team, environment and updates are dispatched in realtime to all relevant applications or servers and users of that team.
Meet: Kiponos.io
The service that brings you all that (and much more!).
A Java SDK and a beautiful Web Admin both interact in realtime!
Technically, the SDK has a class that always have the latest config values, in realtime, with virtually zero performance costs! How?
Kiponos uses WebSockets to communicate to all its componenets. The SDK is subscribed and listens on any config change either done on the web or by another SDK.
The updates are dispatched only as "Delta Change" so they are tiny updates distributed in realtime to all subscribed listeners.
WebSockets
The WebSocket protocol keeps the connection alive with bi-directional communication always ready, which is far more performant than traditional http/REST calls that opens a connection on every call!
Web Admin
The web provides a centralized management place, controlling and handling the access to only allowed roles, team membership, and associated active environment only!
GIFT FOR YOU
The Single Developer plan on Kiponos.io is always Free and to celebrate our first post on Dev.to, I've asked Kiponos management that the "Team Starter" plan would be for free as well... they agreed for anyone signing up until April-16.
Yes!
Wish you all happiness and good life!
Feel free to follow up here with any questions or how you use Kiponos in your project.
Respectfully yours,
David.
Top comments (0)