How to perform the correct flow deviation in an integration with multiple systems?

Asked

Viewed 284 times

7

We have a system, which I will call A, which serves some customers. We are now performing the first integrations with the internal systems (ERP) of these customers. When we make, for example, a request to the web service of System A, it should map this request to a specific web service integration (made available by the client), so the data will stop directly in the database of the Erps of each client.

The flow can be summarized in the following:

Request Web Service System The Request Client Integration Web Service Client Database

However, not all customers have or will even have integration with their internal systems, so the flow to them remains this:

Request Web Service System The Database System A

Currently, the Web Service of System A is made in Java, using Jersey and the REST Standard.

For each Resource class, which is where Jersey endpoint mappings exist, there is also a specific Service class. In the services classes are all existing business logic. Finally, the trio is completed with a DAO class, which is responsible for the CRUD of the data in the database.

Thus, given any functionality in System A, the following classes could exist:

RESOURCE

@Path("/funcionalidade")
@Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public class FuncionalidadeResource {
    private final FuncionalidadeService service = new FuncionalidadeService();

    @GET
    @Path("/exemplo")
    public String getExemplo() {
        return service.getExemplo();
    }
}

SERVICE

public class FuncionalidadeService {
    private final FuncionalidadeDao dao = new FuncionalidadeDao();

    public String getExemplo() {
        // Lógica de negócios necessária aqui
        return dao.getExemplo();
    }
}

DAO

public class FuncionalidadeDao {

    public String getExemplo() {
        // Consulta o banco de dados aqui
        return "Um dado buscado do banco";
    }
}

All Services and Daos have interfaces, which were hidden here for brevity.

With this, my question is the following, how to make sure that for certain clients (those who have integration) the request is diverted to their web services and never actually use the DAO of System A?

Another point that adds complexity: a single functionality can have numerous methods in your Resource, but not necessarily all will be integrated. This means that: for the same functionality, in some requests the search must take place in the client’s database and for others in the System A database.

So far, I’ve thought of a possible solution to this problem:

Upon receiving the request from the client on the System A web service, we verify that the client who makes the request has integration with this specific function. This, I imagined, could be done by making a query in the database, where each functionality would have its unique code next to the client’s code. It would be enough to inform the client code and the functionality code to know if it has integration for it. However, this does not solve the whole problem, since within the same functionality there may be methods that have integration or not. Therefore, each method of a feature would also need to have a unique code in the database. With this, in each request we would pass the unique code of this method along with the client code to know if the client has integration for this method. Assuming this previous part works, the next step would be, if the client had integration, how would we bypass their web service instead of our DAO? To solve this, I thought to add another level in the architecture of the web service of System A. Thus getting the flow of a request that had integration within the web service:

Resource Service Router DAO

The new layer, Routers, would exist only for functions that have some kind of integration with any client. It would be responsible for verifying if the client has integration for that specific method, if it has it, it would pass on to another class the demand to carry out this request in the client’s web service. If not, it will just call System A’s DAO method.

In this way, the Router class will have a reference to the DAO of System A, which was previously in the Service and also a reference to some kind of Requestdispatcher in order to pass to this class the demand to give continuity to a request that has integration.

In this approach, two things sound very strange to me and I still haven’t accepted them very well:

  • The fact that each Resource method has to have a unique code to be able to link, in the database, to the client that has integration. This seems very subject to errors and difficult to manage the more the software grows.

  • If the Router discovers that the client has an integration in that particular method, how will it know which Requestdispatcher to instantiate? Each customer should have their own. For each integrated functionality. This creation can be demanded for a Factory, however, would this Factory have to have the code of the hardcoded clients in order to instantiate the correct Dispatcher? Sounds like code Smell to me.

As I said, this possible solution did not convince me by the cons that it adds, so I would like ideas and suggestions. Who knows who has ever had experience with it can tell us the least turbulent way forward.

Thank you!

2 answers

7


Resource Service DAO Router

I would say that flow is not correct. It’s more like this

                               / Base de dados
Resource - Service - Router __/ 
                              \ 
                               \ Web Service

The fact that each Resource method has to have a unique code for be able to link, in the database, to the client that has integration. This seems very subject to errors and difficult to manage as the more software grows.

Why? Use GUID’s as identifiers. They are statistically unique.

In case the Router discovers that the client has an integration in that method specific, how will he know which Requestdispatcher to instantiate? Each customer should have his. For each integrated functionality...

Force ERP to follow certain rules imposed by you.

This idea may be absurd but that’s exactly how the whole Internet works. It’s exactly by the fact of HTTP be standard that you can access any web page through the browser. Imagine the servers using each of your protocol. The browser would have to support all protocols?

These rules don’t have to be very specific. You just have to indicate, for example, that only supports server integrations HTTP. And that the data is in a format specified by you. (for example JSON, or XML with a format defined by you). It is also important to specify where this data can be obtained (query string, or body)

If customers want the XML in another format you can use XSLT to make transformations. It is up to you to decide whether this XSLT is defined by you or the customer.

If you do not want to impose URLS defined by you, they may be present in a configuration file, which indicates which URL to use for each feature.

This will allow you to write only one module that works with all Erps

ERP is not willing to follow its rules

Then you will really have to do a specific integration for this ERP. I would charge more money in these situations ;)

Modeling your needs with UML

I made an UML that will meet your needs.

inserir a descrição da imagem aqui

The intention is that You have an interface IOperacoes that indicates all the operations you can perform. These operations are implemented in 3 entities for different purposes.

The first entity shall be the entity responsible for carrying out the operations specifically referred to in. ImplementaOperacoes

The second entity is the entity responsible for using a form of integration. IntregradorHTTP and IntegradorBaseDeDados.

The third entity is the Router, that for a given operation calls the intruders to all ERPS (or other logic by itself defined).

In order to support multiple Erps the interface has been defined IErp. This interface specifies the integrators that each IErp supports. In this case it also contains information about ERP Urls for each Operation.

For example you can implement the Router so that one URL for null or empty, you automatically use the IntregradorBaseDedados

  • Hello, Bruno. Your alternative to the flow is also correct. However, there are moments that I will access only the DAO, others the WS (ERP). Who knows in some cases even both. I understand your argument, and I agree that there is no alternative but to create unique identifiers for each method, right? However, in the RequestDispatcher I would also need to have the unique code of each hardcoded client, to be able to instantiate the correct object, or not? I don’t have much to escape from making that communication with every specific ERP. Even being more expensive, that’s what customers want.

  • @Luiz The identifiers are not for the methods but for the objects that will be stored in the database. I do not know. You’ll have to give details of the various Erps to get a better idea of the situation. If all Erps obey the rules I said Windows can do only 1 module and have a folder for each ERP. These folders will only have one or more configuration files.

  • @Luiz Editei the answer.

  • Good answer! However, I believe that it is not very scalable. An interface to define all operations would soon become something too big. Another point is that for me to use the IntegradorBaseDeDados, It would be necessary for my Daos to implement, probably, Ioperacoes, if I understood what you meant. Actually, it wasn’t very clear to me where the Daos would fit into this model. I cannot fit this solution with the large number of Daos that exist in the project.

  • @Luiz the number of operations however large is ephemeral. No, your Daos do not have to implement Ioperacoes. But you would receive an implementation of them in your database integrator. Depending on the operation you want to do you can use an arbitrary number of operations of your Daos

  • Although I didn’t specifically meet my needs, I relied on your UML to create and implement the version we are using. I appreciate the dedication in helping, it was very helpful. More than deserved the reward. Thank you! ;)

Show 1 more comment

1

Isolation of services by context and then their integrations are topics of much discussion. And of course, every integration strategy depends very much on the scenario and resources available.

I really like the strategies:

App A >> Message >> App B

Or, for your scenario, at first sight:

App A >> Message >> Processor >> Message >> App B

So in your Processor runs the flow rules - with toggle Feature for example - and trigger or not a message to the target application - ERP.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.