Migrating J2EE style Project to OSGi Style using the OSGi declarative services - spring

I am new to OSGi and am using Equinox "Virgo Tomcat Server" (VTS) along with eclipse blueprint, and got big assignment to do in limited time
There is application already developed in J2EE Style
By using JSP->Struts2->Spring->MySQL and SOAP Web Services.
-There are various layer in the existing architecture
Simple Request flow is as mention below
From UI layer->it goes to strus2 configration-> it goes to Spring Configuration->From Spring configuration xml (that is module wise application context xml) Struts Action class is called -From Struts Action class layer -> it goes to Task layer->handler layer->Service Layer -> Adapter or DAO layer ->DB in some cases from service layer call also goes to WebService layer and communicate with Back-end legacy system
My Queries are as Follows
Q1] From UI/JSP to up-to strtus2 action layer code for every module should be club together in to a single .war file say "onlinebank.war" and from struts2 action onwords module wise code in every layer should go in to Module wise OSGi bundles
For e.g. if there are 10 modules there should be 10 osgi bundles
And each module wise bundle should contain module specific code from every layer after action layer and there should be communication between one war "onlinebank.war" and 10 osgi bundles
Q2]To take Q1 to next level
If there are 10 modules then instead of crunching module specific code in one OSGi bundle,
I have to create 3 bundles for each module(XXXAPI,XXXMain,XXXConfig)
for e.g. TestModule
I] TestModuleAPI (will contain only interfaces and abstract classes)
II] TestModuleMain (will contain implementation of interfaces and abstract classes and will provide some default functionality)
III]TestModuleConfig (will be accessing the default functionality of Main Bundle Via API Bundle and also provide some customize/new functionality)
So if there are 10 Module and 3 OSGi Bundles for each module (API,Main,Config) then for 10 bundles there should be 3*10=30 bundles and there should be proper communication between -single war "onlinebank.war" and the 30 bundles
Also there should be proper communication among 30 bundles it self to resolve the dependencies and works together properly/synchronously
Any help will be greatly appreciated
Regards,
Gokul

This is a big task you are tackling. I did such a migration and am quite familiar with OSGi. Still it took about 2 months. So you should first not underestimate the problems you will be facing.
The next thing is that a typical spring application is not well modularized. As there are no private/public packages in JSE developers tend to ignore module boundaries. The modules often also do not have a clean and small API at all so people known what they should access and what not.
So I think your first task is to refactor the application so each bundle offers a minimal API and other modules only access the API. For this task it might make sense to use an architecture tool that allows to define and control these accesses. While still in spring you create beans from a service interface from the API. Later in OSGi the API will allow to define clean OSGi services. If you skip this step then OSGi will not have big advantages. OSGi only works well if the application is strictly modularized.
Then for the actual OSGi migration I can only urge you to hire some specialist to help you. It will be a waste of time and resources if you do this alone.

Related

Best practice- share Spring-boot Service and Repo layer code between applications

Need some best practice recommendations to a classic requirement around modularising Springboot application based on layers.
Some background info:
Small- medium size Spring boot project with less than 10 developers
2 different Spring-boot applications and shared Service, Repo layer and also shared models
Bit too late to go with micro service approach with full Model/ Controller/ Service/ Repo per API.
Currently there is just one web application exposing the APIs for a frontend application.
Requirement is to add new set of APIs which are used for B2B integration, so the request/ response formats will be quite different to the already available APIs. i.e. /webapi/v1/orders for frontend client and /b2b/v1/orders will need to return different response format.
The Service and Repository layer along with the models need to be shared among the 2 applications, so 3 modules identified as similar to how it's explained in https://stackoverflow.com/a/50352532/907032
-- Main app
-- Webapi (Got dependency to common, jar packaging)
-- b2b (Got dependency to common, jar packaging)
-- common (jar packaging)
The two applications need to be deployed separately and also separated from CICD perspective not to build all the sub modules every time (A change to b2b controller should not affect common/ Webapi)
A change to common module which is only required to the latest b2b module, preferably should not trigger a build and deploy of webapi. i.e. webapi uses common-1.01 and b2b module uses common-1.02. Understood the new version common-1.02 should not break any feature from common-1.01 but just trying to save unnecessary build & deploy for that module until required if that makes sense.
The challenge
Should the modules defined in the same Repo or 3 different Repos?
All the talks about mono vs multi repo is about whether to keep all different projects in same or not, but here as you can see these are modules which are kind of related to each other.
If we define these as sub-modules in same Repo, how versioning of the common module handled? If it's always triggering a build of all three sub modules, do we even have any advantage of modularising the code?
As per your description, the module named "common" is not not that comon to the other two. I'd go with the multi-modudle way by doing so:
first break that common module in three: common, utils-webapi, utils-b2b
The first will strictly contains the thing both webapi and b2b need at the same version. Utils-webapi will be dedicated strictly to the things in api. Same goes for utils-b2b
B2b depends on utils-b2b with depends on common. Webapi depends on utils-webapi with depends on common
Versionning of common module is always consistant, only utils-X module version change from the X module perspective
CI is thus independant for each build.
Note: You can go further and simply consider utils-webapi utils-b2b and get rid of common. At the cost of some deduped code.

differentiate between maven multi module and Spring micro services?

I am reading spring micro services for next project. Tut said that "The architecture style the main application divided in a set of sub applications called microservices. One large Application divided into multiple collaborating processes.". So already we have a framework maven multi module There I separated the project in my experience. even though it is. why do we need micro services to separate a project?. please differentiate it. thanks in advance..
Every service in the microservice architecture should be isolated which means that the team in charge of that service is able to put continuous deployment in practice without need to deploy other services. In practice, IMHO I think that we can use two approaches using our favourite build tool such as maven or gradle:
Monoproject: domain, repositories, services and controllers are all in the same project.
Multiproject: domain, repositories, services and controllers can be grouped in different modules. i.e domain and repositories are in repository module and services in another module with the same name and controllers in front module.
But, doesn't matter which approach you use the project (mono or multi) should represent one service.

Migrating from Spring monolith application to OSGI

We have been building two suites of applications for the last 10 years using Spring as our dependency injection. We also use spring-batch and spring-amqp. We are now looking to move to OSGI so that our monolithic applications can be separated into bundles so that we can be more agile. The two suites are web applications and are deployed as two separate war files. We are looking to use Apache Karaf as our OSGI runtime.
Spring-DM is dead and it appears that we are going to have to convert EVERYTHING to use Blueprint for our dependency injection.
My question is how do we do this incrementally? It will be close to impossible to convert all of this over at once. It seems like one bundle should still be able to use Spring DI and have it's own application context as long as we take the responsibility to expose any services that we want to the service registry in the bundle activator, but I'm not sure if there is some kind of magic that we would lose like transaction management.
Any guidance on this would be really appreciated.
You might want to consider to make the problem appear even larger and switch to DS instead of Blueprint ... To take truly advantage of the OSGi model, DS is far superior to Blueprint in all aspects. In reality, after the first hurdle, you'll make much more progress and your gains will be higher. Though Blueprint made Spring available on OSGi, it never 'got' OSGi.
For strategy, keep your Spring app alive as a single bundle and move things out gradually. I.e. the elephant approach.
The biggest gain that OSGi provides can be summarized as follows:
Make sure modules have service APIs that ONLY handle collaboration. I.e. each service API should be a story/scenario how the actors work together, not how they come into existence and are configured.
Let Configuration Admin to the configuration work. I.e. never expose configuration APIs. In OSGi, you register instances, not things that still need to be configured.
Make sure you really understand the OSGi model with services. You might want to take a look at OSGi enRoute that leverages OSGi to the hilt.
I propose you take a look at the blueprint-maven-plugin. It allows to use a subset of CDI and JEE annoations to define injections as well as transactions and persistence. The plugin creates blueprint xml at build time which can then be executed by karaf. The big advantage is that these annotations are also supported by spring. So you can transition and in parallel release to production using spring.
I have a complete example here Annotation based blueprint and JPA.
Using this plugin I migrated a medium sized project while it was developed and released in parallel. If you need further advice while using the plugin I can surely help.

How do you call an OSGi application from a non-OSGi application, and vice versa

I am considering writing a new set of applications using OSGi, but they will need to interact heavily with existing non-OSGi applications.
To clarify, the new applications will need to call into existing non-OSGi code bases maintained by other teams (usually propriety services of varying protocols), and new non-OSGi applications will need to call the new OSGi services.
I am not seeing much documentation for how to do this.
Can someone please point me to the correct steps
It sounds like you want to embed OSGi into a larger application. A good starting point for this is a blog post I wrote some time ago: http://njbartlett.name/2011/07/03/embedding-osgi.html
The trick to creating visibility between OSGi bundles and the objects "outside" OSGi is to publish and/or consume services using the system bundle's BundleContext. The embedding code must be aware of the objects from the outer application that you want to make visible into OSGi, and it should publish them as services. Be aware that you need to export the service interface packages via the system bundle exports -- how to do this is described in the blog post.
OSGi services are only for communications inside the same JVM process. So I guess you want to communicate between processes. In this case you have all the usual remoting protocols like SOAP, Rest, RMI. On the OSGi side you can bridge from OSGi services to offering SOAP or REST endpoints using Distributed OSGi (DOSGi).

Is an OSGi service still "OSGi managed" when it's obtained by non-OSGi code?

As an OSGi newbie, I'm trying to wrap my head around the boundaries of the OSGi runtime. My app, which is not build on OSGi, i.e. it's not running in an OSGi container, starts an OSGi container into which we deploy OSGi bundles at run time. Some of these bundles register services. Later, in our non-OSGi code, we obtain those services and use them.
I'm having trouble wrapping my feeble mind around the OSGi boundaries here. To be specific, when I obtain a service and invoke one of its methods, can I assume that all of the subsequent execution is executing within the OSGi container (Felix)? In other words, are dependencies in that code resolved via the OSGi modularity mechanisms? Or did I lose that OSGi management because I am using the service from non-OSGi code?
If my question seems founded in obvious mistaken assumptions about OSGi, please feel free to point them out.
Chad, to more effectively answer your question, I'd like to know a few things:
1) How exactly are you getting the service reference from an external application?
2) Is the external application a stand-alone application, or is it inside of a different container? If so, there are ways to make that happen.
The question you pose is interesting. Lets put it into a context. Lets assume you are able to get a reference to an OSGi service from Felix by an external application. When you use this service, you will be interacting with it via an interface. In that interface in OSGi, you will have import statements referenced which will be used in the method signatures of the interface and also in any final attributes. These import statements will have thier matching dependant libraries defined in your pom.xml file.
In order to use the service by an external application, you will need to publish an API ".jar" file that will contain the interface, and will reference the interfaces' dependancies. Your external application will need to use that API, and will likely have it assembled into your .war, .jar, or .ear file's lib directory. Because of this, none of your external application's dependancies can conflict with your API dependancies.
As long as you can use the API, then you're right, none of the SPI's dependencies matter. You can use Spring 3.0.4.RELEASE in your external app and still use Spring 2.5.6.SNAPSHOT in your OSGi application. As long as the API doesn't have any dependancies that conflict with the external application, you should be ok. The trick here is that you need to put your interfaces into a minimal .jar file as your API, and then put your implementation details into an SPI. Your external ap will use the API, and inside OSGI, you will use both the API and SPI.
Please let me know if this helps.
If you can get the service, then the dependencies are satisfied by definition, because bundles cannot provide services unless their dependencies are satisfied. Executing services on the outside doesn't really change anything.

Resources