-
Notifications
You must be signed in to change notification settings - Fork 11
CDI Microservice Provider
CDI Microservice Provider is one of the most important components of SilverWare since it provides an easy way to manage and connect different microservices. It allows developers to use CDI in their applications and uses Weld SE as the underlying CDI container.
To be able to use this provider, you need to be familiar with CDI (Contexts and Dependency Injection).
If you want CDI container to manage your microservices, you will have to annotate them with @Microservice annotation. This way your microservice will become a managed bean with microservice scope (read Internals for more details).
@Microservice
public class MyService {
...
}
Such microservices can then be injected into others using @MicroserviceReference qualifier.
...
@Inject
@MicroserviceReference
private MyService myService;
...
You can use any CDI mechanisms when working with your microservices — alternatives, qualifiers, specializations, etc.
The following paragraphs describe how CDI Microservice Provider works under the hood. Although it is not completely necessary to know these things if you just want to use this provider for simple use cases, it is highly recommended to read this part in order to fully understand what SilverWare does with your microservices in the background. You may also find this information useful if you want to alter the default behavior.
SilverWare implements its own CDI extension which takes care of all @MicroserviceScoped beans. This scope is automatically assigned to every bean with @Microservice annotation and means that such a bean can be discovered both locally and from other instances of SilverWare in clustered setup.
All microservice beans are scanned by this extension and a new proxy bean is created for every injection point that has unique qualifiers and contains @MicroserviceReference qualifier as well. This proxy bean is then added to the CDI container as a new bean and takes care of creating a unique proxy for each injection point where a microservice is injected.
As mentioned earlier, microservice proxies are what get injected into all injection points with @MicroserviceReference qualifier instead of the actual microservice bean. This allows SilverWare to look up a microservice dynamically at the time it is really needed.
When a microservice method is called on this proxy, it will first go through a chain of method handlers where the last one will try to look up an instance of this service and then invoke the method on it.
Microservice proxies can use various strategies to look up microservices.
SilverWare provides a way to alter microservice method calls.
When a microservice method is called, a chain of method handlers ordered by their priorities is executed.
Unless it is prevented by other method handlers, DefaultMethodHandler
is always executed as the last one and invokes a method on an actual instance of a microservice.
You can implement your own method handler by extending MicroserviceMethodHandler
class. SilverWare will automatically find it and use it. To make it work, you need to follow these rules:
- Set the priority by adding @Priority annotation.
The value selection is completely up to you.
Note that
DefaultMethodHandler
has priority set toInteger.MAX_VALUE
andHystrixMethodHandler
has priority set to0
. If you do not specify priority, the default value (100
) will be used. If two method handlers have the same priority, their execution order will be undefined. - Provide a public constructor with a single parameter of type
MicroserviceMethodHandler
. This is the next method handler which should be executed after yours. - Implement
invoke
method. You can do basically anything in this method but you should eventually call the same method on the next method handler. - Implement
getProxyBean
method and return the proxy bean from the next method handler. You can use this proxy bean to get any additional information about the microservice being called.
@Priority(42)
public class MyMethodHandler extends MicroserviceMethodHandler {
private final MicroserviceMethodHandler methodHandler;
public MyMethodHandler(final MicroserviceMethodHandler methodHandler) {
this.methodHandler = methodHandler;
}
@Override
public Object invoke(final Method method, final Object... args) throws Exception {
// do something
return methodHandler.invoke(method, args);
}
@Override
public MicroserviceProxyBean getProxyBean() {
return methodHandler.getProxyBean();
}
}