I work as a working student in a company and my job is to create a guide on how to convert a software monolith to Microservices. The monolith consists of many individual modules on the server side and I am supposed to create this guide on the basis of a single module. This should be done on server side, as client a RichClient is used (no Web-App).
The whole thing is written in Java and a Websphere Application Server with EJBs and Servlets is used.
Now to my question. I am currently not very familiar with software architecture and am not quite aware of the necessary steps. What is clear is that I have to resolve all dependencies of the considering module to further modules, correct? What follows or what has to be assumed before?
This is very tough to explain here fully , but i can provide you some starting point .
let follow Domain driven architecture for this . assume your monolith application represent a domain . try to divide domain in to sub-domain depending upon functionally , remember each subdomain have its
1. own ubiquoous language (Language understood by all person involved in project ( technical ,non -technical) )
2. Boundary context --> define boundary of each sub domain
3. Domain model
4. Aggregate --> Set of entity which should have consistence data (i am not going in to detail of aggregate you can further read )
Basically each sub-domain represent a micro-service.
further you can explore how these microservices are communicated to each other (Synchronous or Asynchronous ) depending on your requirement.
Related
Currently using JBoss 5.2 + Java 8 (Upgrading JBoss is soon to come). We have the opportunity to revitalize the application with a strong core for multi-tenancy support, so assume this can be started from scratch.
Our Java+Spring application is a simple web app:
Exposes various REST services to be utilized by our client implementations (mobile native + browser).
Connects various systems to complete a 'tenant' implementation.
We build out our tenant implementation utilizing our standardized client/server patterns with customization on each side. On the service side, this involves connecting to various external services including the specific tenant's back-end system for querying or end-product submission.
It's a domain driven design, treating the various services as pluggable utilities based on an interface. The services basically act as a translation and request/response handler to and from our standardized domain objects. Currently the various service interfaces, common services, and tenant-specific modules are broken off into separate projects and maven'd together via POM in JAR format. Also note we currently have a single controller layer since the client/server interfaces are standardized for our solution.
My question is: How can we support releases of various tenants without bringing down the JVM?
The current thought was to be able to dynamically swap the tenant JAR dependencies. Right now the tenant-specific services are designated by spring bean injection - tenant config determined by the URL requests are made with (secured by a session token).
Consider the following scenario of 3 tenants:
Tenant A releases monthly # 3am on a Saturday
Tenant B wants agile/security releases every 2 weeks # 9am Saturday
Tenant C wants planned development releases every quarter # 8pm on a Wednesday
Definitely need to ensure security of the application, so don't want to break the class loading to do anything shady.
Any help/direction would be appreciated and will update with what we end up with.
Thanks in advance!
So what I've come up with so far is a single JVM hosting multiple WARs.
Components separated into their own projects:
'core' - Controllers, web service factories, etc..
Service interfaces
Domain Objects
Tenant Implementations (each their own)
This split of projects allows them to be built individually and take advantage of Maven's versioning system (snapshots).
Each implementation(tenant) now has an 'app' project that mavens the various components and services together. This is a different project than the Tenant Implementations - allows that one to be reused by other projects that would utilize the same domain objects. These 'app' projects would provide all configurations for the app and sub components, being built into their own WAR.
Deployment process is as said - a single JVM that doesn't get cycled while starting/stopping WARs. We currently run an older version of JBoss, so messing with the class loader has been the main issue, but not bad. Looking to upgrade or separate WARs into their own server areas under JBoss.
Going to look into a custom class loader via database storage for JARs or into moving to a Docker setup.
I'm trying to getting into understanding properly the package by feature approach.
1 - Let say I have 2 features that tap on the same data. For instance,
one feature could be visualizing bank account information with
different sophisticate possibilities. The other feature is about
making transaction from the bank account (We could well imagine that
this feature does not involve visualization, it could be simply
provided as a rest service).
1.a - The data model is shared across two features here. How does that impact the package by features. Shall we create redundant data models
class in the 2 package ? Shall we create a specific package for the
data model instead?
which leads me to the second question?
2- In general how are cross-cutting concern dealt with ?
2.a - For instance the case above when it comes to the data model?
2.b - Or, when it comes to the database access or some common access to an external service (shared by different feature but doing
something different with it)?
2.c - Else, the front-end or the overall bundling of the application in general.
What i mean here, is the following case: Currently i have an application which has
(i) a message transfer capability (between participant of the system)
(ii) It also has the messaging monitoring capability whereby it automatically detect rules violation and give penalties.
(iii) A visualization capability dedicated to the administrator of the system.
(iv) A notification capability provided to the administrator of the system to send message to participants.
(V) A violation cancellation capability for the admin as well. And so on.
The point is all of it has to be packaged in one application that i
call marketplace infrastructure. Should the marketplace infrastructure
that wires everything together have his own package ? Even if it is
not a feature.
I think the same could be applied some how in a Web-application as well. There has to be one central point that bundles all the feature modules / packages altogether. If each module define routes, controllers etc... There should be a central routes that import all routes for instance.
If the application has a database behind, this database is used by different feature, well who is going to start the database and wire every modules.
So bottom line is: what about the cross functional stuff (data models,
service access and etc..) and the bundling (wiring everything
together).
PS: By wiring i think about dependency injection, still the graph of object has to be defined somewhere.
Many thanks for any help.
Currently we are building web services applications with Spring, Hibernate, MySQL and tomcat. We are not using real application server- SoA architecture. Regarding the persistence layer - today we are using Hibernate with MySQL but after one year we may end up with MongoDB and Morphia.
The idea here is to create architecture of the system regardless concrete database engine or persistence layer and get maximum benefits.
Let me explain - https://s3.amazonaws.com/creately-published/gtp2dsmt1. We have two cases here:
Scenario one:
We have one database that is replicated (in the beginning no) and different applications. Each application represents on war that has it's one controllers, application context, servlet xml. Domain and persistence layer is imported as maven lib - there is one version for it that is included in each application.
Pros:
Small applications that are easy to maintain
Distributed solution - each application can be moved to it's own tomcat instance or different machine for example
Cons:
Possible problems when using hibernate session and sync of it between different applications. I don't know that is possible at all with that implementation.
Scenario two - one application that has internal logic to split and organize different services - News and User.
Pros:
One persistence layer - full featured of hibernate
More j2ee look with options to extend to next level- integrate EJB and move to application server
Cons:
One huge war application more efforts to maintain
Not distribute as in the first scenario
I like more the first scenario but I'm worried about Hibernate behavior in that case and all benefits that I can get from it.
I'll be very thankful for your opinion on that case.
Cheers
Possible problems when using hibernate session and sync of it between different applications. I don't know that is possible at all with that implementation.
There are a couple of solutions that solve this exact problem:
Terracotta
Take a look at Hibernate Distributed Cache Tutorial
Also there is a bit older slide share Scaling Hibernate with Terracotta that delivers the point in pictures
Infinispan
Take a look at Using Infinispan as JPA-Hibernate Second Level Cache Provider
Going with the first solution (distributed) may be the right way to go.
It all depends on what the business problem is
Of course distributed is cool and fault tolerant and, and,.. but RAM and disks are getting cheaper and cheaper, so "scaling up" (and having a couple hot hot replicas) is actually NOT all that bad => these are props to the the "second" approach you described.
But let's say you go with the approach #1. If you do that, you would benefit from switching to NoSQL in the future, since you now have replica sets / sharding, etc.. and actually several nodes to support the concept.
But.. is 100% consistency something that a must have? ( e.g. does the product has to do with money ). How big are you planning to become => are you ready to maintain hundreds of servers? Do you have complex aggregate queries that need to run faster than xteen hours?
These are the questions that, in addition to your understanding of the business, should help you land on #1 or #2.
So, this is very late answer for this but finally I'm ready to answer. I'll put some details here about further developing of the REST service application.
Finally I landed on solution #1 from tolitius's great answer with option to migrate to solution #2 on later stage.
This is the application architecture - I'll add graphics later.
Persistence layer - this holds domain model, all database operations. Generated from database model with Spring Roo, generated repository and service layer for easy migration later.
Business layer - here is located all the business logic necessary for the oprations. This layer depends on Persistence layer.
Presentation layer validation, controllers calling Business layer.
All of this is run on Tomcat without Application server extras. On later phase this can be moved to Application server and implement Service locator pattern fully.
Infrastructure - geo located servers with geo load balancer, MySQL replication ring between all of them and one backup server and one backup server in case of fail.
My idea was to make more modern system architecture but from my experience with Java technology this is a "normal risk" situation.
With more experience - more beautiful solutions :) Looking forward for this!
I am a S/W developer working on a Java web application.
I have very limited knowledge of Java and want to understand my application architecture from a very high level in simple terms. Being a developer, I do not completely understand the big picture.
Can anyone help me understand this?
Each layer represents a place where some problems are solved is similar way, often using some particular libraries or frameworks. In trying to understand this work your way down through the layers. BUT, note that each layer hides the details underneath, you don't need to understand the details of lower layers in order to understand one layer.
So the Struts piece is dealing with the User-Interface related issues of understanding user requests choosing some business logic to invoke and choosing how to display the results back to the user. It doesn't concern itself with how the business logic works, that's the job of the next layer down.
By Business Logic I mean the Java (or other language) code that expresses the realities of a the customer's business. For example in a retail application we might need to work out discounts for particular volumes of orders. So the UI layer wants to display the price for a customer's order. It doesn't have any discount logic itself, instead it says to the business logic layer "Customer X is order N widgets and M zettuls, when can we supply and how much shall we charge" and the business logic figures out the pricing for this customer, which might depend on all sorts of things such as the status of the customer, the number things we have in stock, the size of the order and so on. The UI just gets an answer £450, to be delivered 16th September, and displays it.
That leads to questions such as "why separate the business logic to its own layer?" There are several possible reasons:
The business logic might be used by some completely different UI as well
It pre-exists, from some older system
Our brains are too small to think about UI and Business Logic at the same time
We have different teams working on UI and BL - different skills are needed
This same way of thinking follows down the layers. Th important thing when thinking about each layer is to try to focus on the role of the layer and treat the other layers as black-boxes. Our brains tend to be too small to think about the whole thing at the same time. I can almost feel myself changing mode as I shift between the layers - take off my UI head, put on my persistence head.
There's plenty of material "out there" about each layer. Suggest you start by reading up about one of them and ask specific questions if you get stuck.
Looks like a standard "enterprisy" application to me.
Interface
This app. is primarily intended to be used via web browsers by humans. This interface or UI layer (in a broad sense) is build using the MVC framework Struts. If you don't know MVC, then it's a good idea to read up on this term.
The app. also exposes web service interface, which is intended to be used by non-humans (other applications or scripts).
So, 2 kinds of interface is provided.
Business logic
Request coming from the 2 interfaces noted above, ultimately talk to the lower half (App. tier) to get some real job done. The actual process (calculating stuff, storing stuff and what not) happens here. Note also that this tier also talks to external systems (via Service Gateway) in order to complete the requests.
The reason they separated the system like this can vary. If it's a very simple, small app. then it doesn't pay off to have these abstractions, so it's probably a quite complex system. Maybe the app. tier is some legacy app. and they wanted to put some better UI on top of it. Maybe the app. tier and the web tier happened to use different technology stack. Or perhaps the app. tier is used by many other external systems. It also makes updating each services/replacing each services etc. easier, so maybe they are anticipating that. Anyways, it looks like a very common SOA type of design.
Not sure what else you might want to know. I see that the designer intends to use distributed cache in both tiers. All in all, it's a very common type of system integration diagram.
App Tier - Where the basic application logic resides (think of a basic console-only program).
Database - MySQL, Oracle... server
DOs - Short for Domain Objects. If anemic usually limited to getters/setters and can be synonymous with Entities (#Entity).
Data Access Objects - Objects using DAO pattern to fetch domain objects from the database. Could be considered equivalent as DAL (Data Access Layer) although this might not fit here. Usually uses a persistence/mapping framework such as Hibernate or iBatis.
Domain Model - Where Domain (domain being what has been studied/analyzed from requirements) Classes are packaged and associated (one-to-one, many-to-one, ...). Sometimes there are even composited in other container classes.
Core Application Services - Groups Services classes which could be equated to the Business Logic Layer (BLL). Biz services handle the Domain Model, Application Services are relative to the Application (methods don't manipulated Domain) and not sure what System Services are supposed to do. I'm also not sure what the distinction between Core and the Application Service block is.
Facade/Interface - This is where all the communication is done with other Tiers. It helps to fully understand interfaces and the Facade pattern.
TOs: Transfer Objects. Related to Domain Objects and used for transferring as the name implies.
Web Tier - All the logic added to make the application accessible from the Web.
Business Delegate: Block using delegation pattern? Here it apparently plays the middle man between Application facade and the Presentation Tier using TOs.
Model: Notion relative to the MVC pattern and variants. With JSF I know that beans are usually linked to JSPs. This model is to be distinguished from the Domain Model. It is created for the purposes of presentation and might contain information that has nothing to do with the data being manipulated in the application tier and is specific to the web tier.
View: Notion relative to the MVC pattern and variants. JSPs represent individual pages and use their own markup.
Session: Look up theory on sessions (necessary as HTTP is stateless).
ApplicationContext: Groups instances/settings that can be pulled into from anywhere. Often associated in the Java world with the Spring framework. To not be confused with UglyGlobalVar/singletons.
Front controller: Could be considered as equivalent to Controller of MVC although the Front Controller pattern appears to be more specific. Servlets are considered as controllers as they handle communication (GET, POST...) and coordinate the model/view. Not familiar with Struts but imagine that the framework implements classes to represent user actions.
Presentation Tier: Simply all of the logic used for outside presentation.
Filters: Can be used to filter requests, for example to redirect a request to a login page.
Feel free to add/correct this description.
I have one module written on Java - web service module which accepts request process it(some business rules here), saves(modify or delete) values in db (using Hibernate) and then send status response). Is it reasonable to refactor that module so at the end there will be 2 modules - 1 is web service module and 2 - processing module where business rules applied and db processes made? and if yes then what is the good practices for information exchange between modules ?
Thanks !
Remember "KISS" - keep it simple; stupid.
It's more important to have a clean and maintanable code, focused on the
domain model, rather than breaking it up based on technical considerations.
Yes; database storage is one aspect, yes, handling webservice calls is another, but its too easy to spend a lot of time to make a "clean" separation, with the only result that it takes longer to change things later. (As everone thats been working on an 14 layered "enterprise" application can tell you.)
Ideally, the "business logic" is the one module you write, and the webservice adaptation and the data storing just should work, "magically". As that is not the case, you obviously have to deal with that too, but its not the primary focus.
I strongly recommend that: the business rules = your datamodel. The webservice methods should be as thin as possible and expose the model as cleanly as possible.
This is a rather insighful article about the "business layer" http://thedailywtf.com/Articles/The-Mythical-Business-Layer.aspx
Also remember that "layers" are abstract concepts, and its not a fundamental requirement that they are "physically" separated in diffent eclipse projects etc. Really, it's not.