I have an OSGi bundle which is using two services through DS, A and B.
B service is using internally Apache's HttpClient.
My question is, when should I shutdown the HttpClient's ConnectionManager, I tried to do it inside the "unbind" method for service B but it won't work because having the unbind method being called does not mean having the instance destroyed so the same instance could be rebinded and therefore my following requests would fail because ConnectionManager was shutdown.
Hope someone could bring some light on HttpClient usage within OSGi environments.
Just remark. You might want to use HttpClientBuilderFactory provided by HttpClient OSGi bundle. Connection pools allocated by the factory will be automatically shutdown / deallocated by the OSGi container.
Is B itself a DS component? If so, you can clean up during B's deactivate method call. If B is a not a DS component, but a service registered using the raw service API, you can use a ServiceFactory when registering the service. Then when a consumers releases the service, your implementation of ServiceFactory.ungetService will be called and you can clean up there.
Related
We have about 50 microservices developed using Spring Boot. We use Spring Cloud for registering services with Eureka and invoke the service from the consumer using Feign. The contract is pretty standard, where the consumer uses an interface with #FeignClient("<foo>") annotation to locate a service that's registered as foo with Eureka. The registration, lookup and invocation on the target service all works as expected with one or multiple instances of the service running.
We have a new requirement where the same service foo may be running multiple instances where each instance has a specific stereotype or designation. For example, some instances of foo are expected to deal with 3rd party integration synchronous workload, and some instances of foo are expected to deal with internal messages (asynchronous workload). We have defined a configuration property called stereotype in the service that would be defined at the bootstrap (done via part of Spring Cloud config) to tell the service instance to deal with sync or async workloads. The configuration looks like this:
service.stereotype: sync # or async
In addition, we also add this property to the Eureka's eureka.instance.metadatamap map as stereotype property when registering the service foo. I can see that the Eureka now displays this value for service foo when it gets registered.
So far so good. Now the question:
Is there a configuration (or annotation) mechanism in either the DiscoveryClient or Feign to lookup foo but using the stereotype as a qualifier. In other words, when my consumer application looks up Eureka, can it somehow tell Eureka to give only the instance where, for example, the stereotype is async? If this is possible, then my consumer component can ensure that the asynchronous workload is only sent to the foo instance that deals with asynchronous workload.
So far, in my research, I have not found anything. I wrote a sample (that can possibly go in a DiscoveryClient override) that would use Eureka REST interface GET /eureka/v2/apps/appID as outlined here and then find the target endpoint by looking up the metadata map for each instance that's returned. But that sounded like brute force. I'd ideally like to do this using one of the existing mechanisms if available, so that I can continue using the load balancing and retry features of Feign instead of reinventing the wheel.
If I expose DataSource as a service in OSGI, how should I handle database connection failure? Should I configure an interceptor of the DataSource service, which would catch database connection failure exception and unregister the DataSource service? Or would OSGI container handle the exception for me?
How should I configure the consuming service, so that it would be able to survive unavailability of the DataSource service, and allow user to re-try the transaction again?
You should handle unexpected exceptions in the same way as you do when you do not use OSGi.
You should use connection-pool and register that as an OSGi service. It will handle connection failures for you. You must always close the connection, even if there is an exception during using that connection. (in finally block before java 6 and by using a try-with-resources block after java 7). Connection pools provide their functionality by implementing DataSource interface.
There are many connection-pools. You can google for them.
I implemented two OSGi components based on commons-dbcp. One for pooling regular DataSources and one for pooling XADataSources. The component picks up the original DataSource/XADataSource OSGi service, than registers a new pooled-DataSource OSGi service.
You can find the source of the module here: https://github.com/everit-org/commons-dbcp-component
It is available at maven-central here: http://search.maven.org/#artifactdetails%7Corg.everit.osgi%7Corg.everit.osgi.jdbc.commons.dbcp%7C2.0.1%7Cbundle
After dropping the jar into your OSGi container, you will see the configuration possibilities of the components at the Configuration page of WebConsole (if you have webconsole).
Need to call a EJB service from the servlet context listener's contextInitialized() method. Application is running on JBOSS, though the context listener works fine, I'm not able to access the EJB bean through JNDI look up.
Because the web deployment in JBOSS happens before EJB beans are bound with JNDI tree. How to overcome from this? Is there a way to configure JNDI bind early or start the web deployment later once EJB's are completely deployed?
I had put Thread.sleep() before the service call in the contextInitialized() method, it is working fine in my JBoss5.1.0 GA, and the same did not work in other machines JBoss of same version.
Applications needs this because, we want to load some master data from the DB and make it available in the web layer (kind of caching). Does JBOSS startupmbean suit this requirement? If yes how can I make the data available to web layer?
Also if any alternative ways are available, please suggest.
Poll for the EJBs in contextInitialized(). So instead of just sleeping for a certain time, try to connect to the EJB. If that fails, sleep, and retry, until the EJBs are available. In this case the context initialization is blocked.
Implement the cache as a lazy one: Fill the cache during the first query (and use the same polling procedure: connect to the EJB, retry until it becomes available). In this case the cache blocks.
You could split your deployment into two parts: One for the EJBs, one for the web application. Then deploy the first, and delay deployment of the web application until the EJBs are bound (either by watching the log file or by trying bind to the EJB from a command line app)
I have an application which receives high volume events (some metrics data) from web applications. I have a non-osgi application that receives these events and is responsible for forwarding these events to osgi bundle. I am trying to use EventAdmin for this communication. I looked at EventAdmin is null in maven-osgi project but does not clearly answer a few questions.
I want to install the EventAdmin service (at non-osgi application level). I am using "org.osgi.service.event.EventAdmin". However, there is no separate jar for this. It is part of compendium jar. Do I need to install compendium jar?
If I don't do above, the reference I get back from this call is always null:
ServiceReference ref = context.getServiceReference(EventAdmin.class.getName());
Any pointers are highly appreciated
Thanks
Masti
Event admin is for communication inside one OSGi framework. You can not use it outside of OSGi or for communication between OSGi containers. For your case I recommend to use jms for communication or if this is too slow then RabbitMQ or HornetQ may work. There is also work in progress to define remote events for OSGi but it is not yet available. One possible combination of event admin and jms might be to receive jms in one bundle and forward the event over event admin. So your business code bundle can abstract from jms.
I'm starting to delve into using Spring DM and OSGi services in an RCP application. I've created a service which is used by another bundle in the RCP application. It does a lookup of the service via calls to getBundleContext().getServiceReference() using the explicit bundle names and service class names. I'm not using DI anywhere yet. The issue I'm running into is that the service that is returned in the requesting bundle is a singleton. At times I notice a threading issue since it is a "stateful" service. How do I configure the application to get back a new service instance with each call?
Here is my spring xml file contents which registers the service:
<bean id="myServBean" class="com.xyz.ClassImpl"/>
<osgi:service ref="myServBean" class="com.xyz.Class"/>
OSGi services in general can be called concurrently by multiple clients. The only thing OSGi supports out of the box is the use of a ServiceFactory, which allows you to return a different instance to each invoking client bundle. There is no standard mechanism to create a new instance per method call. You would have to handle that in your service implementation yourself.