Need help in selecting the right design pattern - oop

We are into the lead business. We capture leads and pass it on to the clients based on some rules. integration to each client very in nature like nature of the API and in some cases, data mapping is also required. We perform the following steps in order to route leads to the client.
Select the client
Check if any client-specific mapping(master data) is required.
Send Lead to nearest available dealer(optional step)
Call client api to send lead
Update push status of the lead to database
Note that some of the steps can be optional.
Which design pattern would be suitable to solve this problem. The motive is to simplify integration to each client.

You'll want to isolate (and preferably externalize) the aspects that differ between clients, like the data mapping and API, and generalize as much as possible. One possible force to consider is how easily new clients and their APIs can be accommodated in the future.
I assume you have a lot of clients, and a database or other persistent mechanism that holds this client list, so data-driven routing logic that maps leads to clients shouldn't be a problem. The application itself should be as "dumb" as possible.
Data mapping is often easily described with meta-data, and also easily data-driven. Mapping meta-data is client specific, so it could easily be kept in your database associated with each client in XML or some other format. If the transformations to leads necessary to conform to specific APIs are very complex, the logic could be isolated through the use of a strategy pattern, with the specific strategy selected according to the target client. If an extremely large number of clients and APIs need to be accommodated, I'd bend over backwards to make the API data-driven as well. If you have just a few client types (say less than 20), I'd employ some distributed asynchronicity, and just have my application publish the lead and client info to a topic corresponding to client-type, and have subscribed external processors specific for each client-type do their thing and publish the results on another single queue. A consumer listing to the results queue would update the database.

I will divide your problem statement into three parts mentioned below:
1) Integration of API with different clients.
2) Perfom some steps in order to route leads to the client.
3) Update push status of the lead to database.
Design patterns involved in above three parts:
1) Integration of API with different clients - Integration to each client vary in nature like the nature of the API. It seems you have incompitable type of interface so, you should design this section by using "Adapter Design Pattern".
2) Perform some steps in order to route leads to the client- You have different steps of execution. Next step is based on the previous steps. So, you should design this section by using "State Design Pattern".
3) Update push status of the lead to database: This statement shows that you want to notify your database whenever push status of the lead happens so that information will be updated into database. So, you should design this section by using "Observer Design Pattern".

Sounds like this falls in the workflow realm.
If you're on Amazon Web Services, there's SWF, otherwise, there's a lot of workflow solutions out there for your favorite programming language.

Related

Seperate or Merge Kafka Consumer and API services together

After recently reading about event-based architecture, I wanted to change my architecture into one making use of such strengths.
I have two services that expose an API (crud, graphql), each based around a different entity and using a different database.
However, now whenever someone deletes a certain type of row in service A, i need to delete a coupled row in Service B.
So I added Kafka to my design, and whenever I delete the entity in service A, it publishes a notification message into Kafka.
In service B I am currently consuming the same topic so whenever a new message is received the Service will also handle the deletion of the matching entity, because it already has access that table because the same service already exposes the CRUD API to users.
What i'm not sure about is whether putting the Kafka Consumer and the API together in the same service is a good design. It contradicts the point of single responsibility in micro services, and whether there is an issue in one part of the service, it will likely affect the second.
However, creating a new service will also cause me issues - i will have 2 different services accessing the same table, and i will have to make sure i always maintain them together, whenever making changes to the table or database.
What is the best practice in a incident such as this? Is it inevitable to have different services have data coupling or is it not so bad to use the same service for two, similiar usages.
There is nothing wrong with using Kafka... You could do the same with point-to-point service communication, however (JSON-RPC / gRPC), however.
The real problem you seem to be asking about is dual-writes or race-conditions leading to data inconsistency.
While you could use a single consumer group and one topic-partition to preserve order and locking across consumers interested in those events, that does not lock out other consumer-groups from interacting with the database to perform the same action. Therefore, Kafka itself won't help with this problem.
You'll need external, distributed locks (e.g. Zookeeper can be used here) that fence off your database clients while you are performing actions against it.
To the original question, Kafka Connect offers an API and is also a Producer and Consumer client (and would be recommended for database interactions). So is Confluent Schema Registry, KSQLdb, etc.
I believe that the consumer of your service B would not be considered "a service" or part of the "service", as in that it is not called as part the code which services requests. Yet it does provide functionality that is required for the domain function of your microservice. So yes I would consider the consumer part of the Microservice in terms of team/domain responsibility.
There may be different opinions on if the consumer code should share the same code base/repo as the "service" code. Some people believe that it is better to limit the repo scope to a single "executable", others believe it is beneficial to keep the domain scope and have everything in a single repo. I probably belong to the latter group but do not have a very strong opinion on it. I would argue it is more important to have a central documentation / wiki for the domain that will point to the repos involved etc.

How to seperate two projects from one solution and communicate with each other?

I have a two project linked with each other, Project A and Project B in same VS solutions.
Now the requirement is, I have to do seperate projects, it means seperate DB, web site name, servers etc.
Now I want to know how I will communicate both the project each other using web API?
Before starting separate I would suggest reading about DDD (Domain Driven Design) to make the rights choices about what functionality and classes could be in one microservice or the other.
Anyway, once you have separated the two services properly, so the communication between them would be minimum, there are mainly two ways to communicate with each other.
One is using synchronous communication using HTTP calls using some HTTP client for your language, for example, in java-spring applications is very common to use Webclient. The pros of this approach is that you don't have to deal with eventual consistency because all happens in the same thread, the main con is that you are coupling the services and if one of them fails the other will fail too.
The second approach is to use asynchronous messaging using some message broker like kafka. With this approach when something happen in one of the service, it will publish the event in the message broker and it will be consumed by the other. Ther is no direct communication so there can't be cascade failures but the problem is that you don't know when exactly the message will be consumed (eventual consistency)
As you see both options have pros and cons and it depends on your use case to choose one or the other

Is there a RabbitMQ pattern for a client election

Is there a way to have a pub/sub queue in RabbitMq in which any of the subscribers could vote and all give a thumbs up (or more importantly a thumbs down) before processing continues?
I am not sure what to call this so It is very hard to research.
I am trying to make subscribers that can be added and have the ability to veto a process without knowing about them up front.
{edit below}
I am essentially trying to build a distributed set of services that could filter in very specific use cases as they are discovered. I am trying to do this so I do not have to down my service and version every time one of these new use cases is discovered.
Here is a contrived example but it gets the point across:
Lets say I want to calculate if a number is Prime.
I would like to have a service that has general easy rules, (is factor of 2? is factor of 3?)
But lets say that we are getting into very large numbers, and I find a new algorithm that is faster for finding specific cases.
I would like to be able to add this service, have it subscribe to the feed and be able to trigger "NotPrime" and have all other subscribers abandon their work as a result of the veto.
In a monolithic world I would look at some sort of plug in framework and have that implement the filters. That seems like mixing strategies in a bad way if were to do the same within a micro service.

NserviceBus Sagas Utility

I read this excellent tutorial (http://blogs.planbsoftware.co.nz/?p=247) about NserviceBus Sagas, but still I don't understand what is the advantage of this model (sagas), over using database or business layer transactions?
The main benefit of the saga model is that it allows you to take logic and data that would otherwise be spread out across a system (and various batch jobs), and pull that all into a single class, better following the single responsibility principle. Once you have that, you get all the other benefits that come from good software practices - better testability, maintainability, etc.
To show you real benefit of Saga model I'l show you two examples.
Imagine you have Services Oriented Architecture with hundreds of distributed hosts. Customer makes an Order that starts one or more sagas. Each saga have some related business logic. Handler for each given saga can be shared between different hosts and you don't need to check order state handling each message, NServiceBus implicitly checks saga state matching it by order id or other attributes and if it is still opened you'll get it in your data context.
You can also use this model as pattern without NServiceBus usage. Imagine you develop a video game and want to track some user combos. Each time player hits jump you open saga and add bonus points handling other rapid input. Once player delays for some time between inputs and saga closes itself saving total score for combo.
What are the benefits of Saga?
1) Your business logic is encapsulated in one place - saga.
2) You can extend it easily adding additional saga or removing them. You can also move them to other handlers or hosts.
3) You don't need to know what data in database are required in case of migration, you just need to migrate sagas which contain all necessary info

Two wcf servers vs a wcf server with callback

I have got two applications that need to communicate via WCF:
Called A and B.
A suppose to push values to B for storage/update
B suppose to push a list of values stored in it to A
the senior programmer in my team wants to open a WCF server at A and another WCF server at B.
I claim that one should be the server and the other should be the client and use server call back In order to avoid splitting the interface into two, avoid circular dependency, and duplication of code settings. he doesn't understand it. can anyone help me explain him why his solution is bad code?
It depends on your criteria. Let's assume a client/server model where A is the client and B is the server. You state that B should "push" data to A.
If you truly need push then you should make B into a duplex server. This does put some strain on your bandwith, so if you have a bandwith restriction, this might not be the right choice.
If you can incur some delay at A than you might want to opt for a polling mechanism of your own (maybe based on timing, or some other logic).
If both are not an option, you can try and swap roles. So then make B the client and A the server. It's les intuitive, but it might fit your scenario. If you can incur a delay on storing data, make B poll A for changes in the data and save at an interval.
If there can be no delay in both and bandwith is limited, you do end up with two WCF services. Altough it may look silly at first glance, keep in mind they are services and not servers. It does make things a bit more complex, so I would keep it as a last resort.
A service should encapsulate a set of functionality that other applications can consume. All it does is wait for and respond to requests from other components, it doesn't initiate actions by itself.
If Application B is storing data, then it can of course be provided to Application A as a service. It provides the "service" of storing data without application A having to worry about how or where, and returns successfully stored data. This is exactly the kind of thing that WCF Services are meant to handle.
I am assuming that application A is the one initiating the requests (unless you have an unmentioned 3rd application, one of them must be the initiator). If Application A is initiating actions (for example, it has a UI, or is triggered to do some batch processing etc.) then it should not be modeled as a "service".
I hope that helps :)