benoitheinrich / micro-services-finder Goto Github PK
View Code? Open in Web Editor NEWThis project aims to allow developer to find candidates for microservices inside a monolith
This project aims to allow developer to find candidates for microservices inside a monolith
The first thing the tool does is to index all API modules types hierarchy.
This first step is very important so it indicates the capabilities of an API.
Those capabilities are based on the list of Service Definitions defined in that
API module (the list of interfaces).
Also, in some cases a Service Definition can be composed of other services, and for
this it will then extend another Service Definition which could be defined in
the same API module, or in some other API modules.
On the other hands, some POJOs might also extend other POJOs or abstract
POJOs, but those cases should be ignored.
Cases where an interface implements a standard Java type (ie. extends Comparable
)
should be ignored as well.
The indexing will then result in a list of Service Definitions per API module, and each
Service Definition will indicate if it extends other Service Definitions, and this
will create a graph of physical dependencies.
When the tool has finished to generate the indexes, it'll create dependency graphs for each
independent graph found by the tool.
The indexes created by the tools will be persisted so they can be reused without having to
parse the code base again and again.
The indexes will be persisted in a simple json file describing the Service Definitions
and the Service Implementations.
The Service Definitions will be stored in a service-definitions.json
file in the
current directory, and the Service Implementations will be stored in the
service-implementations.json
file (still in current directory).
If one of the file is missing, then it'll be regenerated.
If the file exists, it'll just use it.
Similar to the indexing of the API types, the implementation modules will need to be indexed
as well.
The indexing of the implementation will be one only for classes which extends a
Service Definition.
Other classes will be ignored as they can only be used by the internals of the implementation
module itself.
The way the tool indexes the implementation modules is that it'll check all the classes that
implement an interface, and then it'll check if that interface is considered as a
Service Definition based on the previous step.
If the class is considered as an implementation of a Service Definition, then that
class will be indexed, and it'll indicate which Service Definition is implemented and
which module contains that implementation.
This will be referred as a Service Implementation.
Some tests will need to be added for the Main
app to make sure it all works correctly.
As a Service Definitions can be implemented by many Service Implementations, the
tool needs to make a choice about which one to use if you were to create a standalone
microservice.
The first thing to do is to check the type of implementation and see if maybe one of the
implementation is a Mock Service.
A Mock Service is similar to a real implementation module, except that in general the
name of the class will start by the word ock
.
Mock Services will have to be ignored by the tool as they can't be delivered as part of
a microservice.
After ignoring Mock Services, if we still have more than one match, then the tool will
accept a configuration file to indicate which Service Implementations to use.
_Note that many _Service Implementations* can be used if needed, and by default, all
the Service Implementations will be used.*
The tool will allow some configuration in order to drive some of the behaviour when
generating graphs.
The configuration file is located in the source directory and is named msf.yml
.
In the following example let's imagine that we have 2 API modules and 5 different implementations:
api/
- api-a/
net.bhservices.test.a.ServiceA
- api-b/
net.bhservices.test.b.ServiceB
impl/
- impl-a1/
net.bhservices.test.a.impl1.ServiceA1Impl
- impl-a2/
net.bhservices.test.a.impl2.ServiceA2Impl
depends on ServiceB
- impl-b1/
net.bhservices.test.b.impl1.ServiceB1Impl
- impl-b2/
net.bhservices.test.b.impl2.ServiceB2Impl
depends on ServiceA
- impl-b3/
net.bhservices.test.b.impl3.ServiceB3Impl
Now let's say that we want to create an independent microservice for impl-b2
.
If we let run the tool with no configuration, it'll then depend on by both impl-a1
and impl-a2
which both implements api-a
.
In this example we would only need one of the implementation to make it work, so then
we would provide the following configuration to force the implementation impl-a1
to
be used.
Here is a the configuration that would be provided:
implementations:
- net.bhservices.test.b.impl2.ServiceB2Impl:
forced-dependencies:
- net.bhservices.module_a.ServiceA: net.bhservices.test.a.impl1.ServiceA1Impl
Now, imagine that we want to create a bundle for impl-a2
and that we want to select
only impl-b1
and impl-b2
for that bundle.
Here is a the configuration that would be provided:
implementations:
- net.bhservices.test.b.impl2.ServiceB2Impl:
forced-dependencies:
- net.bhservices.module_a.ServiceA: net.bhservices.test.a.impl1.ServiceA1Impl
- net.bhservices.test.a.impl2.ServiceA2Impl:
forced-dependencies:
- net.bhservices.test.b.ServiceB:
- net.bhservices.test.b.impl1.ServiceB1Impl
- net.bhservices.test.b.impl2.ServiceB2Impl
Note: in this case impl-b2 will be created in a bundle with only impl-a1, but another
bundle will be created for impl-a2 which will also contain impl-b2, but in this case it'll
rely on impl-a2 and not impl-a1 as it already provides the ServiceA
implementation.
When a service definition uses generics then the parsing of the extends doesn't work anymore.
Example.
Given the class file defined as:
package net.bhservices.module_b;
import net.bhservices.common.SomeCommonService;
public interface ServiceB<T extends Toto> extends BaseService, SomeCommonService {
void someMethod();
}
Then the service name is detected as ServiceB<T instead of ServiceB.
Also the service definition doesn't indicate what type of generic is being used.
That last part is probably not important for now and will be ignored.
The goal of this story is to allow the SBT build to generate a micro-services-finder
executable file that bundles all dependencies and everything.
Once generated, the user should be able to just run the micro-services-finder
as any command line application.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.