Dynamic target for declarative service in OSGI - java

Given a consumer which uses a service, how can this consumer select a specific provider dynamically using declarative service ?
Example
Service.java
public interface Service {
public void do();
}
Provider1.java
public class Provider1 implements Service {
#Override
public void do(){
//a way
}
}
Provider2.java
public class Provider2 implements Service {
#Override
public void do(){
//another way
}
}
Consumer.java
public class Consumer {
private Service myService;
protected void bindService(Service s){ // Actually it's Provider1
myService = s;
}
protected void unbindService(Service s){
myService = null;
}
public void useThisKindOfService(String s){
// Do something crazy
}
}
So, what I would like it's instead of "Do something crazy", to find a way to reconfigure the consumer in order to release Provider1 and ask for Provider2.
Is it possible ?
Update related to "Duplicate Question"
OSGI/Felix Declarative services: How to filter the services to be bound
In my context I cannot use the declarative target because the value of the target has to be know at build time, in my case the target could be defined by a user at runtime.

Components of Declarative Services can be configured via ConfigurationAdmin. By doing that, the configuration of the component can be changed at runtime.
You can also change the configuration of myService.target via ConfigurationAdmin at runtime. If you do that, another reference will be bound to your component.
If the policy of the reference of your component is dynamic, the new reference will be bound without reactivating your component.
For more information, see the Declarative Services chapter of the OSGi Compendium specification.

Related

Spring boot - task on startup preventing application interface exposure

Is it possible to somehow in Spring boot application achieve some startup procedure that blocks every exposure of endpoints (and possibly other application public interfaces) until the startup procedure is completed?
I mean something like
#Component
public class MyBlockingStartupRunner implements ApplicationRunner {
#Override
public void run(ApplicationArguments args) {
// doing some task, calling external API, processing return values, ...
startTask();
// at this point app should be available for rest calls, scheduled tasks etc.
someObject.appIsReadyToGo(); // alternatively app would be ready at the end of the method
}
}
Problem with this approach of using ApplicationRunner is there might be some API calls to the server that I am unable to serve and therefore I would need to add some check at every API endpoint to prevent this. Or, alternatively, create some interceptor that would "block" all public communication and which would probably read some property from some service which tells it if app is ready or not. But thats not the approach I would like and I wonder if Spring implemented this somehow.
If it is acceptable to run your start-up tasks before the web server instance has started at all, you could use SmartLifecycle to add a start task.
#Component
class MyStartup implements SmartLifecycle {
private final ServletWebServerApplicationContext ctx;
private final Log logger = LogFactory.getLog(MyStartup.class);
#Autowired
MyStartup(ServletWebServerApplicationContext ctx) {
this.ctx = ctx;
}
#Override
public void start() {
logger.info("doing start stuff: " + ctx.getWebServer());
startTask();
}
#Override
public void stop() {}
#Override
public boolean isRunning() {
return false;
}
#Override
public int getPhase() {
return 100;
}
}
Because the task runs before the web server has started (rather than blocking access) this might be a different approach.

how to rewrite this code to avoid switches/casting

Simplified example to give you an idea, hope it's be clear.
I've already added inheritance for Service class to avoid switches I'm having now
class Config {}
class ConfigA extends Config {}
class ConfigB extends Config {}
// service class - different implementation for configA and ConfigB
// normally it would look like
class ServiceA {
public String run(ConfigA configA) {}
}
thus next then I need sth like
class ServiceRunner {
public String run(Config config) {
// if or switch doesn't matter now
if (config instanceof ConfigA) {
return serviceA.run((ConfigA)config);
}
}
}
// main
Config config = configFactory.create(...) // returns ConfigA or ConfigB
String result = serviceRunner.run(config);
Is there a better way to code it I mean without casting?
The only solution I can see is:
interface Service { String run(); }
#RequestScope
class ServiceA implements Service {
private ConfigA config;
public ServiceA(ConfigA configA) {this.configA = configA}
public String run() {
...
}
}
but I'm not convinced it's a good idea to implement service beans as state beans and I'm using CDI (quarkus actually) for DI which it seems doesn't support assisted injection via constructor
Why don't you hide the detail about which Config a given Service handles inside the Service itself? By doing so you could have something like the following:
interface Service {
boolean handlesConfig(Config config)
String run(Config config);
}
class ServiceRunner {
private List<Service> services;
public String run(Config config) {
for (service : services) {
if (service.handles(config)) {
return service.run(config);
}
}
}
}
Seems like it's a case for Bridge pattern. You have parallel hierarchies of service and config. So if tomorrow there is a ServiceC, there would supposedly be a ConfigC. There might be an abstraction which is common in both service and config. Try to find it and abstract it out. Then service would be using that abstraction. And ConfigA, ConfigB would be impls of that abstraction.
Or perhaps, as the replier above mentioned, service should be programmed to the abstract config instead of impls.
Does the Configs have different types of interfaces that can't be extracted into a common interface? In that case, it is violating the Liskov's substitution principle, which requires that all subclasses should be interchangeable. e.g. the hierarchy of Shape <- Rectangle <- Square is wrong, because square is not a type of rectangle (programmatically, of course) - because Rectangle has 2 dimensions, namely length and breadth, while square has one dimension of length only. Making this hierarchy would break the abstraction. Similarly, it might be your case that the hierarchy of Config may not be a hierarchy at all.

Guice service dependencies

I have three guava Services which get started by a guava ServiceManager asynchronously.
The first service is the database connection pool which needs to start fully before the second/third service can successfully process incoming messages. Obviously with these being started asynchronously, the database may not have fully started before the second/third service starts to process a message, which will lead to exceptions.
What is the desired pattern here?
I can inject the database service into the other services and call the awaitRunning() method in the service startup, but then I will suffer the same issue when the ServiceManager is shutdown.
I believe guice does not have an out-of-the-box mechanism for this. Spring e.g. has a depends-on attribute that can define some ordering. There are frameworks that give you this with guice as well (e.g. dropwizard guicey implements an order annotation). This is however fairly simple to solve.
The approach is to use multibindings to define a manager for all dependency classes. This I will call Managed (adopted from jetty). The interface will implement an ordering. We then use a manager that starts all the services one by one in a well defined order (can also be used for shutdown if wanted).
See my code example here:
public class ExecutionOrder {
public static void main(String[] args) {
Injector createInjector = Guice.createInjector(new AbstractModule() {
#Override
protected void configure() {
Multibinder<Managed> multiBinder = Multibinder.newSetBinder(binder(), Managed.class);
multiBinder.addBinding().to(Service1.class);
multiBinder.addBinding().to(Service2.class);
bind(ManagedManager.class).in(Singleton.class);
}
});
createInjector.getInstance(ManagedManager.class); // start it
}
public interface Managed extends Comparable<Managed> {
public default void start() {}
public default int getOrder() { return 0;}
#Override
default int compareTo(Managed o) {
return Integer.compare(getOrder(), o.getOrder());
}
}
public static class ManagedManager {
#Inject
public ManagedManager(final Set<Managed> managed) {
managed.stream().sorted().forEach(Managed::start);
}
}
public static class Service1 implements Managed {
#Override
public void start() {
System.out.println("Started Service 1");
}
#Override
public int getOrder() {
return 1;
}
}
public static class Service2 implements Managed {
#Override
public void start() {
System.out.println("Started Service 2");
}
#Override
public int getOrder() {
return 2;
}
}
}
My - admittedly stupidly named - ManagedManager is injected by guice with all Managed interfaces, using guice's multibindings (see the module I initialise). I then sort that and call start.
The start method would be where you initialise your services (e.g. your database connection). By overwriting the getOrder() method you can define which service is started at which point.
That way you get a well defined startup behaviour and you can adapt the interface to have a well defined shutdown behaviour as well.
I hope this helps,
Artur

How to properly access application state from JAX-RS

#Path("/test")
public class MyClass {
#GET
public Response response() {
// Generating some expensive object here.
}
Right now I load the data into arrays etc inside the "response" function, but I want to do it before the query is even made. This way, I want to avoid reloading the data every time a a query is made. How do I achieve this?
This depends on your framework. Are you using the reference implementation Jersey? Jersey comes bundled with HK2 automatically. Then you could add
#Path("/test")
public class MyClass {
#Inject
private MyState stateful;
// here comes your code...
}
to your resource. Of course, you would still need to configure what to inject into this field. With HK2, you use an AbstractBinder for this purpose:
class MyBinder extends AbstractBinder {
private final MyState stateful;
public MyBinder (MyState stateful) {
this.stateful = stateful;
}
#Override
protected void configure() {
bind(stateful).to(MyState.class);
}
}
Finally, you need to add this binder on the application's setup. For this purpose, JAX-RS Application object can be queried for singletons. Simply add the required instance to the application such that it is returned by Application#getSingletons as here:
class MyJaxRSApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
return Collections.singletonSet(MyClass.class);
}
#Override
public Set<Object> getSingletons() {
return Collections.singletonSet(new MyBinder(new MyStateImpl()));
}
}
You can now run your application where MyStateImpl is always injected into MyClass.

Injecting many decorated instances with Guice -- on mixing HessianServlet with Guice

Given the following code in a Guice servlet module configureServlets():
serve("/a").with(new Decorator(new A()));
serve("/b").with(new Decorator(new B()));
...
serve("/z").with(new Decorator(new Z()));
...
What would be the best / easiest solution to properly inject all this? (i.e. injecting fields in the various decorated classes A, B, C...)
I was thinking using named providers, but I would prefer not having to define a new provider class for each A, B, C... The ideal solution would be thus generic.
ON MIXING HESSIAN WITH GUICE...
To help precise the question, the real code uses web-services with Hessian. After digging on the net there is currently no proper answer on this problem (I've seen many ugly hacks), and the solution given by Guillaume fits the bill on this precise case.
To summarize the original problem: to implement a web-service using Hessian, one must implement an HessianServlet, which is a GenericServlet; however Guice can only bind HttpServlet. The trick was thus to implement a thin wrapper HessianHttpServlet:
class HessianHttpServlet extends HttpServlet {
public HessianHttpServlet(HessianServlet hessianServlet) {
this.hessianServlet = hessianServlet;
}
#Override public void init(ServletConfig config) throws ServletException {
hessianServlet.init(config);
}
#Override public void service(ServletRequest request, ServletResponse response) {
hessianServlet.service(request, response);
}
}
And calling:
serve("/a").with(new HessianHttpServlet(new WebServiceA()));
The complete solution is thus in that case to inject WebServiceX :
void configureServlet() {
serve("/a").with(new HessianHttpServlet(inject(new WebServiceA())));
serve("/b").with(new HessianHttpServlet(inject(new WebServiceB())));
...
serve("/z").with(new HessianHttpServlet(inject(new WebServiceZ())));
}
private HessianServlet inject(HessianServlet hessianServlet) {
requestInjection(hessianServlet);
return hessianServlet;
}
You can use requestInjection(Object instance) on each of your decorators.
I created a little open source project which enables easy integration of hessian and guice. You can use annotation based configuration like this:
WebService:
#HessianWebService
public class UserServiceImpl implements UserService {
...
}
Guice configuration:
public class WebServiceGuiceServletContextListener extends GuiceServletContextListener {
#Override
protected Injector getInjector() {
return Guice.createInjector(
/* your guice modules */
new HessianWebServicesModule("your web service implementations package")
);
}
}
or the manual way using the EDSL:
public class WebServiceGuiceServletContextListener extends GuiceServletContextListener {
#Override
protected Injector getInjector() {
return Guice.createInjector(
/* your guice modules */
new HessianWebServicesModule(){
#Override
protected void configureHessianWebServices() {
serveHessianWebService(UserService.class).usingUrl("/Users");
}
}
);
}
}
More information, configuration options and complete examples are available here: https://bitbucket.org/richard_hauswald/hessian-guice/

Categories

Resources