KIE Server Router was built to cover two main areas:
- hide the complexity of many KIE Server instances hosting different projects (kjars)
- aggregate information from different KIE Servers regardless if they share the same db or host the same projects (kjars)
As described in previous articles, it can find the correct KIE Server instance for the incoming request based on container information that is sent through router. So the basic logic is that router keeps information (routing table) that have following information:
- container id mapped to KIE Server location (url)
- container alias mapped to KIE Server location (url)
- server id mapped to KIE Server location (url)
in the context of this article, only first two are relevant. They are used to find the right server (or one of them) to forward the requests to.
The KIE Servers (Kjar 1 and Kjar 2) can have as many instances as they need that will be connected to the same db and will use the same set of containers deployed to them.
Whenever new request comes in, router will try to find if it contains container information and if so will attempt to find the route to the server that supports it. The situation is very simple if the request comes with container id (as opposed to container alias). As container ids are unique (and should be versioned to provide maximum flexibility) so the look up of the route is easy – just get it from routing table.
A bit more complex scenario is when the alias is used. Obviously this is more appealing to end users (client apps) as they don’t have to change the URL whenever new container is deployed. So instead of using container id in the URL, container alias can be used to make the client less coupled with the constantly changing environment.
By default KIE Server Router deals with container aliases same way as for container ids. Looks them up in the routing table to find the server location. Then it’s the individual KIE Server that is responsible to find out concrete container that should be used to deal with that request. That is perfectly fine as long as there is no alias shared across different KIE Server – by different I mean KIE Server that host different kjars (usually different versions of the kjar).
As illustrated at the above diagram in such case, Kjar 2 should then take over entire responsibility for given container alias and host both versions of the project. As soon as it up and running the Kjar 1 server should be removed and then the Kjar 2 takes over entire load.
This architecture promotes reusability of the runtime environment for the same domain – usually the version of given project are incremental updates that stays in the same domain. So that is what is available by default and the logic to find the proper container is within the KIE Server itself.
… but real world is not as simple …
There are more options for deployments that would then put more responsibility in the KIE Server Router instead. Like for example taking the action to find out the latest container for an alias across all available containers. For example, if we want our clients to always start with latest available version of a process then client will use alias for container and router should resolve it before forwarding to KIE Server. That would mean that the architecture is that each KIE Server hosts single kjar and each version will bring in new KIE Server instance connected to the router but all of them will share the same alias.
The above setup is not covered by default in KIE Server router because the alias can be resolved to different servers that might not have the kjar deployed that given request is targeting. To allow to cover this use case KIE Server Router was enhanced to allow certain components pluggable:
- ContainerResolver – component responsible for finding the container id to be used when interacting with backend servers
- RestrictionPolicy – component responsible for disallowing certain endpoints from being used via KIE Server Router
- ConfigRepository – component responsible for keeping KIE Server Router configuration, mainly related to the routing table
Since KIE Server Router can run in various environments these components can be replaced or enhanced compared to the defaults. For instance to support the described scenario – router to be responsible to find the latest container and then forward it to that kie server. This can be done by implementing custom ContainerResolver and plug it into the router.
Implementations are discovered by router via ServiceLoader utility so the jar archives bringing in the new implementation need to have included service descriptor:
A sample implementation of all these components can be found in this project at github.
Since default KIE Server Router is ran as executable jar, to provide it the extensions the execution needs to slightly change:
java -cp LOCATION/router-ext-0.0.1-SNAPSHOT.jar:kie-server-router-proxy-7.0.0-SNAPSHOT.jar org.kie.server.router.KieServerRouter
once the server is started you will see log output stating what implementation is used for various components:
Mar 01, 2017 1:47:10 PM org.kie.server.router.KieServerRouter <init>
INFO: KIE Server router repository implementation is InMemoryConfigRepository
Mar 01, 2017 1:47:10 PM org.kie.server.router.proxy.KieServerProxyClient <init>
INFO: Using ‘LatestVersionContainerResolver’ container resolver and restriction policy ‘ByPassUserNotAllowedRestrictionPolicy’
Mar 01, 2017 1:47:10 PM org.xnio.Xnio <clinit>
INFO: XNIO version 3.3.6.Final
Mar 01, 2017 1:47:10 PM org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.3.6.Final
Mar 01, 2017 1:47:11 PM org.kie.server.router.KieServerRouter start
INFO: KieServerRouter started on localhost:9000 at Wed Mar 01 13:47:11 CET 2017
So that would be all for this article. Stay tuned for more updates and hopefully more out of the box implementations for KIE Server Router.