OSGi : How can a Service auto discover client bundles deployed at runtime? - service

I have a scenario where during the system install time, a few services were deployed on to the OSGi container and these services will be listening for other bundles that provide data and are dynamically installed and uninstalled at runtime.
These data providers do not expose any services and should not even invoke services; my idea is to enable the pre-deployed services to listen for the event of installation of these data provider bundles and if the pattern matches, then process and persist the data into the data store.
For example I have a WidgetService which will listen for installation or uninstallation event of Widget data provider bundles, ShppingCartService that will listen for the installation/uninstallation events from ShoppableItem data provider bundles, etc.
This helps me to keep the processing and persisting logic be centralized and my data providers need not write any code to make their data processed. All that is expected from the data provider bundles is the Service Name/id, Service Version,PreRequisites, and the data that they need to publish.
I have read several articles on OSGi that explain dynamic pluggability of services and the clients able to discover or discard services based on their availabity; however, those are all talking about scenarios where clients are to be intelligent to discover and execute the services they are interested in.
My intention is to make client completely unaware of any service discovery, for that matter any code. All that the client passes is the info about the service the client is interseted in, the dependencies, and the data; the client should be completely dumb.
Is this possible in OSGi? I'm ready to consider this architecture even at the cost of extending a few of the OSGi core framework classes!
I have found some what, may be, remotely related question on stack overflow at :
Discovering Bundle MetaData with out installing the bundle
However, I want a hook or an event that will call my respective service when one or more data provider bundles have been installed. These data provider bundles can be interested in any of the services that are installed in the system. I'm even ready to write a central bunle repository manager/listener kind of stuff that will listen to any bundle installation and invoke my Service facade that will decide which service to execute based on the meta data provided by the data provider bundle.
I'm just starting OSGi, so need a little direction on how to move forward...
I'll be really thankful to you guys/girls :) if you can help me achieve this!
I have a doubt deep in my mind that this may not be readily available in OSGi, and even if that is true I'm ready to spend time and extend the framework to achieve this. All I need is a few guidelines and a clear direction. Who knows, if OSGi is really lacking this functionality, then it would be a very useful add-on to a future OSGi spec.

You might have a look at section 4.7 (Events) of the OSGi Core spec. The Framework raises BundleEvents when there is a change in the lifecycle of a bundle, e.g. when it is installed or uninstalled. What you need to do is to implement a BundleListener, which then will receive the events, so your service can react on the changes.

I have described a design pattern that I call "OSGi Mediator", which may be a solution to your problem.
The items you want to mediate would only require to register with the service registry; all the dependencies could be managed by your mediator implementation.

Related

Spring restful services in websphere

Our application environment in Websphere Application Server has 3 clusters
1. UI Cluster
2. Service Cluster
3. Integration Cluster
We have around 50 war files (Micro Services) deployed to Service cluster. All services are REST based and exposed through SPRING API. Restarting Service cluster takes close to 30 mins. This time is critical during live incidents in Production. For reasons, if Service cluster needs to be restarted, we need to have 30 mins downtime for all end users. We are looking to reduce to recycle time, please suggest us for any solution.
Is there a way to load all the Spring based jar files before the application starts?
i.e. for example there is a service war file called as xyz-1.0.war and there are Spring based jar files as maven dependencies. All 50 number of WAR files has the same set of dependencies, I am thinking in a way to see if we can load all the Spring based jars before the application is started by websphere server.
Please suggest.
I don't know that you can load them BEFORE the application starts (class loading is generally on-demand), but you might be able to speed things up through the use of shared libraries for your common files, so they'd be loaded by a single class loader rather than from each WAR's class loader. It won't eliminate the class loading activity, since each WAR would still need to load the necessary classes, but it'd speed up the mechanics of the class loads since the shared library loader would return the already-loaded class rather than searching its class path.
There are two different approaches you could take to this. Step one in both cases is to create a shared library with the classes that are shared among the applications. The options for step two:
1) Create a custom class loader on the server and associate the shared library with this new class loader. This will make the classes in the shared library visible to all applications running on the server.
2) In the shared library configuration, select "Use an isolated class loader for this shared library", then associate the shared library with any applications that require it. In the event that the shared classes are required only by some applications, this will provide them only to the applications that require them.
A couple points of caution:
If you require unique Class instances (for example, static values unique to each WAR), this approach won't work, because there will be only one instance of the Class loaded by the shared library loader. In that event, you'll have to stick with WAR-level packaging.
If you use the isolated class loader solution, note that those loaders use "parent last" class loading, in which they are searched before server class loaders. If you have anything in those libraries that conflicts with classes provided by the server, it could open you up to ClassCastExceptions or LinkageErrors.
Note that the shared library loaders operate as parents of the WAR loaders, and as such, classes in the libraries will not be able to "see" classes in the WARs. You'll need to make sure that the libraries are essentially self-contained in order for these approaches to be successful.
More specific details on the configuration steps can be found in this blog post: https://www.ibm.com/developerworks/community/blogs/aimsupport/entry/create_shared_library_and_associate_it_with_the_application_server_or_application_on_websphere_application_server?lang=en_us
If you are doing microservices then your services should be independently deployable, so they each should be in the separate cluster. Traditional WebSphere Application Server is a bit heavy weight for this solution (depending on how many resources you have on your nodes), so I'd suggest you to migrate your service cluster to WebSphere Liberty and in that case you could have each service in separate clusters. This would allow you to restart each service independently, at much shorter time.
If you are doing microservices, then your UI cluster should be prepared for any service unavailability - that is a primer when doing microservices, and display some message to end user, that this service is temporary unavailable.
Regarding your current setup - you could try the "Rollout update" option, which will restart your server sequentially, so services should be available on other nodes.
so-random-dude advice to use blue/green deployment is also very good. You could have 2 cells, and then switch plugin configuration after redeployment. If your services are written in a way that different versions can run in parallel during update, you would have no downtime.
If you want to reduce downtime further and improve performance, you should consider using Java EE/Rest services instead of Spring, as it will cut down significantly size of your app, amount of libs to be scanned, deployment and startup time. It is much better integrated and supported in WebSphere Liberty than tons of jars that you have to include with Spring.
I have a simple solution for you, just ditch the Websphere and deploy those 50 "wars" as independent jars with embedded netty/undertow/tomcat/jetty in it.
I am afraid, what you have currently is not at all a microservice architecture. Agreed, different teams/consultants/organizations has different interpretation of "micro"services. But this is an extreme, which you should avoid at any cost; because you are having all the pain points of microservice and ZERO benefits (benefits such as independent scalability/deployability etc).
Restarting Service cluster takes close to 30 mins. This time is
critical during live incidents in Production. For reasons, if Service
cluster needs to be restarted, we need to have 30 mins downtime for
all end users
Have you looked at different deployment strategies like Canary deployment / Blue-Green deployment? Do you have more than one instances behind a load balancer?

Service Fabric: Plugins vs. Application Types

I'm developing a Service Fabric-based trading platform that will host hundreds of different long-running trading algorithms, all of which conform to a common interface and share a good deal of common code but can be vastly different in their internal specifics. I could model each of the different algos as an application type (which I'd dynamically load) but given the large number of different algos I have to wonder if in makes more sense to create a single Plugin Runner application type then implement the algos as plugins.
In a related question, I understand how to implement a plugin architecture, in general, but I'm not quite sure where one would place the actual plugins in order to be discoverable by an instance running on Service Fabric.
Anyway, thanks for your help....
Both approaches can work I think. Using lots of Application Types adds the (significant) overhead of running lots of processes, but allows you to use and upgrade multiple versions of the same algorithm running simultaneously.
Using the plugin approach requires you to deal with versioning yourself.
Using the Application approach probably requires some kind of request router, while the
plugin service could make it's own decisions (if it's stateless).
You can create a Stateful service that acts as the plugin repository, or mount a file share, or use a database, no restrictions from the platform here. You can use naming conventions to locate the proper plugin.
The following approach could work if an application upgrade is acceptable to you when changing the set of plugins needed for a given application instance.
Recall that Service Fabric apps must be packaged before deployment or upgrade. Using either msbuild tasks or Powershell, you could copy your plugin dlls to the plugin runner service's code package as a post-packaging step prior to the app upgrade. Then your plugin dlls would be available to the service at startup using Assembly.Load and the code package's path, available in your service implementation's Context.CodePackageActivationContext.GetCodePackageObject("Your-Code-Package-Name").Path property. The code package's name is defined in ServiceManifest.xml, and is named Code by default.

Micro services with JBOSS

I am new to Jboss, want to know if micro services architecture is a right choice on JBOSS. I cannot change the application server as it is decided by client architect and I have no choice.
Want to know whether we can develop micro services with underlying JBOSS application server.
I understand Spring boot comes with embedded tomcat container, which makes it flexible to stop and start, deploy individual service with no impact to other services.
However will that architecture works with JBoss too.
Please suggest.
Thanks,
I actually developed a feasibility study to investigate the solution you mentioned. My conclusion is that it is totally viable to use Micro Service principles in a JBoss Platform.
I used the combination of JBoss \ Spring Boot \ Netflix to create successful Micro Service stack, I personally do that to find a solution to the transaction problem (multiple micro services collaborating) and the fan out problem which caused because excessive Network communication and Serialization costs.
I also wrote a blog about the subject, you might find more details there if you like to, here is the link.
Micro Services – Fan Out, Transaction Problems and Solutions with Spring Boot/JBoss and Netflix Eureka
By the definition what micro services are, then conceptually yes. A micro service is a service that is an independent unit, it could deployed, updated, and undeployed independently without affecting any unrelated part of your application. So that would mean having multiple instances of JBoss for MS and your application calling them through some sort of gateway or any other mechanism depending on your use case. If you plan to deploy all your MS in the same JBoss instance then it defeats the very purpose of a MS. Given that, JBoss wouldn't be a right choice for MS deployment because it will only make your MS deployment infrastructure quite heavy.
Depending on what your client's requirements are, your could possibly keep your webapp in JBoss and deploy your MS containers separately.
It depends on what you want to get out of microservices.
Some of the developers at my organisation looked at Spring Boot but concluded that it's best off being run as a standalone container rather than in JBoss, otherwise you've effectively got two container frameworks competing (SB and JBoss) and a range of associated issues.
Deploying microservices in JBoss won't give you the same flexibility as a true container system like Docker. With Docker you create standalone packages for your microservices that contain all the code, system tools, runtime environment, etc. It can be as small or large as it needs to be. JBoss on the other hand is a large container running a single JVM designed to hold multiple applications. The level of isolation is not the same, and it's not efficient to have JBoss as a container for a single microservice so you have to appropriately size and then deploy to the instance to make use of the resources it has available.
If you're looking at microservices as a way to gain greater control over service lifecycle management (deployment, versioning, deprecating, etc.) as opposed to an automated, web-scale component deployment model a la Netflix or LinkedIn, you could do this adequately with JBoss.
I'm actually looking to do something along these lines here. It won't be true microservices but by packaging and deploying individual, properly versioned APIs rather than monolithic applications and following most of the other principles of microservice development (componentisation, business function focus, stateless etc.) we will be hopefully better able to manage and benefit from our APIs.
Our APIs will all be behind an API gateway and load balancer so we can choose how we distribute the microserves distributed across the JBoss instances and balance resource usage as required. Note that our organisation is relatively small and has relatively low and predictable traffic so this approach should work fine. Your needs however may be different.

ISO8583 middleware with JBoss

I want to ask about JBoss Middleware for ISO8583.
So, I kinda new on ISO8583, from what I know is we could use JPOS framework for this one. Then my supervisor ask me to research about JBoss Middleware that could be used to develop middleware application for send, receive, and parse ISO8583 message.
I have read on JBoss Middleware website, unfortunately I'm still not sure which JBoss technology should I use to develop such application.
Here is my questions:
1. In order develop enterprise application that capable to send, receive, and parse ISO8583, should I combine JPOS with JBoss Middleware? or JBoss Middleware has a complete capability to handle it?
2. Does anyone has/know good material/tutorial for me to learn about building ISO8583 middleware with JBoss technology?
Thank you.
JBoss Middleware is a family of products and its components alone do not provide ISO8583 capabilities out of the box.
jPOS is one of the most popular Java frameworks that provide complete capabilities to handle sending and receiving ISO8583 messages. There are other alternatives such as j8583 and IsoTypes.
You can combine any of these ISO8583 libraries together with JBoss Fuse (part of the JBoss Middleware family) to build a solution capable of sending, receiving and parsing ISO8583 messages.
I'm not aware of a definitive guide about building such solutions. If you need to use JBoss Middleware, you can follow this route:
Look into IsoTypes, which provides an ISO8583 marshalling library for Apache Camel (used by JBoss Fuse).
Start by building a Camel route that implements the IsoType library functions. Look into this sample project.
Please, be aware that building a production ready ISO8583 server and/or client from open source solutions require significant work in terms of scalability, information security and compatibility with multiple financial hosts and switches.
My answer only refers to the first basic steps to understand your problem/solution fit a bit better.
As a side note, you may be interested in looking at jreactive-8583, an ISO8583 connector that handles message parsing and the network layer out of the box. You may build your application using this and deploy it into JBoss Application Server (part of the JBoss Middleware family too). I use it in production.
You can take advantage of JPos Q2 and create a servlet deployable to JBoss container.
In the service init method you can do this:
Q2 q2 = new Q2();
q2.start();

osgi multiple versions of service

i have osgi services service-1.0.0.jar and service-1.1.0.jar they are implementation of service-api-1.0.0.jar
both these service-1.0.0.jar and service-1.1.0.jar have same service name and packages.
service are registered by bundle-activator
lets assume bundle activator is com.abc.xyz.MyActivator - 1.0.0 and 1.1.0
issue I am facing is when I deploy these services and lookup using service tracker and filter on version I want, I always get same implementation regardless of what version chosen.
this makes me believe that what i am trying to achieve is not doable.
I need multiple implementation of service packaged in separate bundles with difference of version and be able to choose dynamically at runtime.
I am trying this in jboss-6.1.1 eap
if i keep different package name in versions looks like it is able to understand that these are 2 different services but when package names are same i get same service implementation.
am i doing something wrong? has anybody tried this?
is it correct that OSGI allow you to deploy multiple versions of service?
UPDATE After using unique package names for MyActivator in 1.0.0 and 1.1.0 looks like the services are able to maintain the uniqueness.
Does that mean Activators has to unique across bundles?
I assume that service-api-1.0.0.jar exports the package which defines the service interface. In that case, it sounds like you have two implementations of the same version of the service. Not different implementations of different versions of the service. So from a service user point of view, the services are that same: they are from the same service api package version.
I think you are using the OSGi services in a strange way. As a client you should not look into the implemention bundles to determine versions or other informations.
Instead you should use the service interface and service properties to distinguish between services.
So for example you can have a property version and publish the first service with version=1 and the second with version=2. Then you can filter for this property to get a specific service.
Using reflection is also a rather unusual thing. Better try to provide classes in the interface package that you use to exchange data between client and service. This will make the client less dependent on the service impl.
If you have multiple implementations of the same service API, and a client queries for an implementation of the service API, it could get any of the implementations. And that's good because the client shouldn't care.
Say for example you have a Greeting interface with multiple implementations registered as services, possibly by multiple bundles. If a client asks OSGi for a Greeting service then OSGi will simply pick one. After all, if you just ask for a Greeting without specifying anything else then you should accept any implementation. Clients certainly shouldn't care which particular bundle the service comes from: this is the nature of decoupling.
Incidentally, when this happens OSGi normally chooses the implementation that was registered first (actually the one with the lowest service.id, which is an ever-incrementing number, so it's effectively the same thing). This is probably why you see OSGi consistently choosing one particular service.
If your client needs to distinguish between service implementations then you can add properties to the published services and filter on those services. For example one bundle could publish a Greeting service with property language=en_US (i.e. US English) and another could publish a Greeting service with language=de. If your client only wants greetings in English then it can use a filter like (language=en*).