Binding services with Guice - java

I have written several services that I am glueing together using Guice. For example some abstract service A is described by these interfaces
Response
Request
Service
And the implementation is defined as
ResponseImpl
RequestImpl
ServiceImpl
Would it be better to bind all of the above implementations to their interface in the service's module, or just the Service class itself?

When you seperate contract (interface) and implementation (service-impl), you usually hand only the interfaces (api-jar) to the application-clients. So they will never see (and care about) any implementing beans.
Thus, in your client code, bind the interfaces:
#Provides
public Service lookup() {
return .... whatever you need to do to access the Service
}

Related

Inject multiple remote EJBs in bean

In Java EE, if I have an interface:
#Remote
public interface MetaService {
ServiceData get();
}
And I have, in an ear 2 implementations:
#Stateless
public class Service1MetaService implements Calculator {
#Override
public ServiceData get() {...}
}
#Stateless
public class Service2MetaService implements Calculator {
#Override
public ServiceData get() {...}
}
I can create a bean, where:
#Stateless
public class View {
#Inject
private Instance<MetaService> metaServices;
...
}
And in View, the field metaServices will have the 2 implementations of MetaService.
I'd like similar functionality with remote beans.
So let's say, I have the above interface and implementations, but the packaging is different.
In base.jar I have the MetaService interface. This is packaged will all the subsequent applications mentioned below.
In a.ear I have the Service1MetaService implementation, while in b.ear I have the Service2MetaService implementation and in c.war I have the View class, which would like to use these implementations.
But as you would expect, the injected Instance is empty (not null tho). Is there a way to find the remote bean references in my injected Instance instance, even though these implementations are in separate applications?
One important thing is that in the View class I don't know and don't care about the number of these implementations, nor the names of the applications they are deployed in. So there is no way for me to use specific JNDI strings to get these references.
P.S.: Should I try and use technologies like JMS instead? So that I call the method add on a JMS proxy, which sends out the requests and waits for answers from all the applications that implement said interface?
P.S.: To clarify, the reason I need this is actually so that I can get data of running services on my application server(s). I updated the example interface and implementations, so that it's more clear. Also, it would be nice, if I could get these metadata synchronously, so JMS is not neccessarily prefered, however I can probably make it work.
I managed to convince myself to move away from remote EJBs. Well, it was also thanks to #chrylis-onstrike- as well, however, I'll opt for using JMS for this purpose.
The reason is that I can broadcast a request for the different services I need data from on-demand, enabling me to check for new services going online, or services failing.
Thanks to everyone who spent time trying to help me out.

[Spring-Cloud][Maven][Docker]Should Feign interfaces be put in FeignClients or EurekaClients?

EurekaServer: register/expose services
EurekaClients: provide services
FeignClients: consume services and provide APIs
I'm using Feign for service consumption. I wonder if feign interfaces (interfaces that annotated with #FeignClient) should be put in EurekaClients or FeignClients?
If Feign interfaces are put in EurekaClients.
GOOD: I only need to write only one copy of Feign interfaces, and implement it in the EurekaClients. For any FeignClients that need to use this service, import these interfaces from EurekaClients and just use it.
BAD: Module dependencies could be easily set, but it is hard to do mvn package or using docker for production. As the problem I stated HERE.
If Feign interfaces are put in FeignClients(almost every examples I can find on the internet do like this).
GOOD: Easy to build.
BAD: A lot of duplicated code. Because for every FeignClient I need to re-write #FeignClient annotated interfaces. If there are a lot of nested FeighClients and EurekaClients, it would be too difficult to maintain.
So any suggestions for a good practice of Where should I put Feigh interfaces ?
Here is the pattern we followed in our projects. Each service has two projects, e.g., :
Service A
model
service
All the controllers and other business related classes, e.g, DAOs, service, Repository classes are kept in the service project. While the models used by the controller and exposed to the outside world are kept in the model project. The controller also implements an interface which exposes the REST API. This interface is kept in the model project also.
public interface AuthorService {
#RequestMapping(method = RequestMethod.GET, produces = {
MediaType.APPLICATION_JSON_VALUE}, value = "/authors/{id}")
#ResponseBody
Author getAuthor(#PathVariable("id") Integer id);
}
The AuthorService interface and the model, Author are kept in the model project. The controller, AuthorController which implements the AuthorService is kept in the_service_ project.
Let's say ServiceB uses ServiceA, then the former import's the latter's model project. In ServiceA's service, we create a Feign interface, e.g.,
#FeignClient(name = "author", fallback =
AuthorServiceFallbackClient.class)
public interface AuthorServiceClient extends AuthorService {
}
This pattern helped us to reduce quite a bit of code duplication.

OSGi service not implementing interface

I am working on a project which uses OSGi which has below code
#Component(policy = ConfigurationPolicy.OPTIONAL, ds = true, immediate = true, metatype = false)
#Service(TestInterface.class)
public class TestInterface{
Here the code doesn't implement the interface in which the service is going to exposed. Also I have verified everywhere this is not referenced anywhere with #Reference.
Does it really need to make it as service instead of only component? In case if i want to use it in another Component i have to make it as a service by implementing interface.
Does OSGI really mandates the service to be exposed should implements interface?
An OSGi service can be registered under any type name not just interfaces. Interfaces are highly recommended since they nicely separate the implementation class from consumers of the service.

Using hystrix-javanica annotations on interfaces

I am integrating Hystrix into SilverWare microservices platform and I want to use hystrix-javanica annotations. These annotations are meant to be applied on the actual implementation of the methods that need to be executed using Hystrix. The problem is that I need to implement a generic solution where you only have a service interface. It has to be done this way in order to let developers use annotated references to other microservices (when they implement their own service) without any need to deal with the implementation of those services.
I came up with a solution where you annotate your microservice reference with something like this:
#Inject
#MicroserviceReference
#HystrixConfiguration(MyServiceHystrix.class)
private MyService myService;
And then you implement (or extend) the service interface and put Hystrix annotations on its methods:
public interface HystrixedMyService extends MyService {
#HystrixCommand
doSomething();
}
When there is #HystrixConfiguration annotation on a field in your microservice referencing another service, SilverWare will scan the class given as a parameter of this annotation and prepare a Hystrix command for every method of the service. The command will also receive a callable with an actual method invocation which will be executed in its run() method.
My question is: Is it possible to reuse some (internal) parts of hystrix-javanica so I do not need to scan all the annotations and create those Hystrix commands myself? I can see that most of the classes are designed to be used only with AOP.

Is it best to use type or properties to choose between OSGi Declarative Services?

I'm currently converting a piece of code from plain Java code to OSGi Declarative Services.
Original plain Java code
new AggregateServiceImpl(
new ChildServiceImpl1(),
new ChildServiceImpl2(),
new ChildServiceImpl3()
);
The classes are declared as so:
class AggregateServiceImpl implements Service
class ChildServiceImpl1 implements Service
class ChildServiceImpl2 implements Service
class ChildServiceImpl3 implements Service
So all classes implement Service, but the Aggregate implementation is capable of deferring to child Services when called upon.
AggregateServiceImpl itself does not know of the other implementations' existence. Its constructor is originally declared as:
public class AggregateServiceImpl(Service... children)
Clarification: the interface name 'Service' is intended generically and is not meant to represent an OSGi DS or Service concept.
Converting to OSGi
First I move each implementation into its own bundle. Then I declare my components (service implementations). I happen to be using bnd, so I use service annotations. For example:
#Component
class ChildServiceImpl1 implements Service
In the client class, we can look up the Service using the low level OSGi API or use DS in that bundle to create the object for us.
Problem
What's the best way of looking up a 'Service'? I want the AggregateServiceImpl but I might receive one of the ChildServiceImpls.
Is it best to use a separate service type or add a property to one of the components (e.g. "isRootService") to use as a filter when looking up ServiceReferences?
The best way is to use service registration properties
#Component
#Service
#Property(name = "service.id", value = "<some service unique ID")
class ChildServiceImpl1 implements Service{...}
When you look for some specific services you can use service filter:
bc.getServiceReferences(Service.class.getName(), "(service.id=<some value>)");
or if you like to use it in DS component as service reference:
#Reference(target = "(service.id=<some value>)", cardinality = ...)
private Service service;
If the AggregateServiceImpl is the only Service being used by other bundles, then it should be the only one you register.
From the code you have currently shown, we cannot tell if the AggregateServiceImpl class has dependencies on Service or the actual implementations.
If it has dependencies directly on other implementations, not the Service interface (as you have currently described it) the aggregate bundle should create the other implementation classes it requires directly and then register the AggregateServiceImpl as a Service.
If the other implementations need to be used elsewhere as well, then you should use properties (as you suggested) so consumers can distinguish between them. In this case, you still cannot use DS to construct your aggregate, since it doesn't have a dependencies on Service

Categories

Resources