I am trying to refactor a legacy order handling and stock system with into a cleaner service oriented event-driven architecture. However, I am having some difficulty deciding what service should be responsible for the reservation/allocation of stock.
A brief overview of the current system
Sales orders are placed with us via third party system but we do not necessarily have all order lines in stock.
If an order item is in stock then we allocate/reserve the stock for that order straight away.
However, if we do not have enough stock then we procure the stock from our suppliers via a purchasing system.
When the item arrives from the supplier, the system will search through all open sales orders for the item and reserve/allocate the available stock to them, prioritising by sales order date. ***
I have already identified two services that I think need to be developed
Sales - Responsible for receiving the sales order and inserting into the database. Has domain entities such as Order, OrderLine etc.
Inventory - Responsible for keeping track of how much stock is available in our warehouse. Has domain entities such as StockItem.
However, as the allocation/reservation of stock concerns both inventory and sales I am not sure where the behaviour in point 2 above should be put.
I welcome any help or thoughts on this.
I think you have 2 BCs (bounded contexts): Inventory and Sales. For the integration between them I would probably go for domain events approach.
When a new item arrives at the warehouse, the Inventory BC increments the stock for the item, and publish an event.
Sales BC subscribes to the event, and it updates the opened sales that are waiting for the stock item.
So, behaviour of "point 2" are shared by both BC:
Sales BC search for opened orders waiting for that item. And then it asks Inventory BC to get the number of items it needs (this request is synchronous) and close the order.
Inventory BC receives the request and decrements the stock for the item.
However, as the allocation/reservation of stock concerns both inventory and sales I am not sure where the behaviour in point 2 above should be put.
I've been thinking about this problem (purely academically), and my current conclusion is that reservation management belongs with the inventory system. That keeps the stock source (the loading of items procured from your suppliers) and the stock sink (fulfillment of orders) together.
So the inventory system caches its own copy of the data required to fill the order (allowing it to work autonomously). It should be able to make progress as soon as it is informed that the suppliers have provided new inventory, even if the sales system happens to be down for maintenance.
You mentioned SOA and NServiceBus, so my initial thought was that you've attended Udi Dahan his ADSD training? I'll assume you have. With that, I'll try to answer your question.
So far I don't have a lot of information. But with what we have, I figured we need these properties to store all that you mentioned.
ProductId, one for each available product
InventoryTotal, attached to a ProductId. This number goes up and down
OrderId, to create an order
OrderDate, to make sure we can find the order that should receive incoming stock first.
If you have an OrderId, you can attach one or more ProductId to create an actual order. Different ways of storing this technically. Maybe in a relational database with Order and OrderLine tables, or possibly in a DocumentDb where everything is stored in a single document. That's totally irrelevant at this point.
Assuming we need 4 attributes, I'm not sure why we would create more than 1 service to split this up? This might change when we have more information, but at this moment I don't see the need.
If you want to discuss this, contact us at support#particular.net, mention my name and we can continue the conversation.
You are talking about loosely coupled domain apps, managing your sales orders, managing your inventory and managing your purchase orders.
Inventory must always be up to date, in order to not sell what you can't deliver. So PO en SO app should both talk to inventory via synchronous (inventory) services. To keep everything consistent, events on purchasing side, like receiving less than you expected for a PO, will have an impact on any SO already assigning quantity of that PO, as persisted in inventory. So the same PO pcs for example, in which the event of receiving less as expected, is registered, should synchronously update inventory, to update the quantity available for SOs to assign from, and publish an event, to be picked up, asynchronously, in the So app, so that the user can be notified and talk relevant action. Etc.
Related
I will try to keep this as generic as possible using the “order” and “product” example, to try and help others that come across this question.
The Structure:
In the application we have 3 different services, 2 services that follow the event sourcing pattern and one that is designed for read only having the separation between our read and write views:
- Order service (write)
- Product service (write)
- Order details service (Read)
The Background:
We are currently storing the relationship between the order and product in only one of the write services, for example within order we have a property called ‘productItems’ which contains a list of the aggregate Ids from Product for the products that have been added to the order. Each product added to an order is emitted onto Kafka where the read service will update the view and form the relationships between the data.
The Problem:
As we pull back by aggregate Id for the order and the product to update them, if a product was to be deleted, there is no way to disassociate the product from the order on the write side.
This in turn means we have inconsistency, that the order holds a reference to a product that no longer exists within the product service.
The Ideas:
Master the relationship on both sides, which means when the product is deleted, we can look at the associated orders and trigger an update to remove from each order (this would cause duplication of reference).
Create another view of the data that shows the relationships and use a saga to do a clean-up. When a delete is triggered, it will look up the view database, see the relationships within the data and then trigger an update for each of the orders that have the product associated.
Does it really matter having the inconsistencies if the Product details service shows the correct information? Because the view database will consume the product deleted event, it will be able to safely remove the relationship that means clients will be able to get the correct view of the data even if the write models appear inconsistent. Based on the order of the events, the state will always appear correct in the read view.
Another thought: as the aggregate Id is deleted, it should never be reused which means when we have checks on the aggregate such as: “is this product in the order already?” will never trigger as the aggregate Id will never be repurposed meaning the inconsistency should not cause an issue when running commands in the future.
Sorry for the long read, but these are all the ideas we have thought of so far, and I am keen to gain some insight from the community, to make sure we are on the right track or if there is another approach to consider.
Thank you in advance for your help.
Event sourcing suites very well human and specifically human-paced processes. It helps a lot to imagine that every event in an event-sourced system is delivered by some clerk printed on a sheet of paper. Than it will be much easier to figure out the suitable solution.
What's the purpose of an order? So that your back-office personnel would secure the necessary units at a warehouse, then customer would do a payment and you start shipping process.
So, I guess, after an order is placed, some back-office system can process it and confirm that it can be taken into work and invoicing. Or it can return the order with remarks that this and that line are no longer available, so that a customer could agree to the reduced order or pick other options.
Another option is, since the probability of a customer ordering a discontinued item is low, just not do this check. But if at the shipping it still occurs - then issue a refund and some coupon for inconvenience. Why is it low? Because the goods are added from an online catalogue, which reflects the current state. The availability check can be done on the 'Submit' button click. So, an inconsistency may occur if an item is discontinued the same minute (or second) the order has been submitted. And usually the actual decision to discontinue is made up well before the information was updated in the Product service due to some external reasons.
Hence, I suggest to use eventual consistency. Since an event-sourced entity should only be responsible for its own consistency and not try to fulfil someone else's responsibility.
Based on this talk from Mauro Servienti called "All Our Aggregates are Wrong. Here is the link for reference: https://www.youtube.com/watch?v=KkzvQSuYd5I
We might have a few bounded contexts each containing information of a item.
e.g
Marketing Context - name, description, images
Sales Context - list price, product code?
Inventory - stock level
Each context might have their own name for it, e.g. inventory might call it sales item.
I think sales might be the owner of an item so when you go to create an item that is the place it will be created.
I have two questions.
Does the UI call these context's seperately?
If I have a UI to create a product/item and takes the data for both marketing and sales (list price, product code, name, description), I believe it is the case that the UI will make two separate calls.
The first call being to the sales context to create the item, which will publish a ItemCreated event or similar.
The second call will be to the marketing context to set the name, description, etc...
Is this correct?
Marketing's item
so my understanding of the inventory service, is that it will listen for the sales ItemCreated event and then create its own aggregate/stream for its representation of an item (Inventory item)
With marketing on the other hand, if I have a UI where I create the item with sales and then need to set the data in marketing, does the UI wait for an item to be created in marketing before then setting the title and description? Does the UI poll the marketing context until the item has been created and then performs the command to update the data?
I did something similar in the past.
The best approach I found is:
Firs you have to find the main owner of the item. In my case it was a product catalog.
Having a product in the catalog means the company intent to work with this product even if there is not stock, nor a marketing campaign, nor anything yet. This is an aggregate by its own, its operation (add product to catalog) is completly transactional because even if the event ProductAddedToCatalog fails to be applied in other Bounded Context (BC) (because infrastructure fails) I do not have to undo nor coordinate/orchestate anything. Just retry raising the event. The Catalog BC is kept in a consistent state.
For the others BC; applying the event means they create its entry with empty/default values. i.e. in Warehouse BC the entry is created with 0 stock and its correlated product catalog ID. In marketing the entry is created as a product with no marketing campaings so far. And so on with others BC.
How I modeled the UI taks for this? I created several screens like a wizard.
The first screen ask for product catalgo info. Its only task is insert a new product on the catalog.
The next screen ask for Warehouse info but it is not inserting; it is updating the entry with default values created by applying ProductAddedToCatalog event that was raised in the first step.
This way, in case warehouse step fails, the system keeps its consistent state and a user could use the UI task for updating product stock in Warehouse BC later.
For my internship, I need to implement a blockchain based solution to manage a drug supply chain. The management of this supply chain implies to track-and-trace (geolocate) a drug on the chain, but also to monitor the storage temperature to see if the cold chain is respected. For that I created a mock-up of the POC my Dapps (https://balsamiq.cloud/sum5oq5/p8lsped)and also I wanted to prepare myself by doing a UML and a use cases. However, I didn't find a lot of information about blockchain's UML and use cases besides two literatures which were quite different, so I don't know if what I did was correct or not...
The users of my Dapps will be the following ones:
The stakeholders (Manufacturers, Distributors and Retailers) which will use the Dapps to place orders and also monitor them. They also can search in the historic a specific order. Finally, trough IOT sensors they update the conditions of the order (temperature & location).
The administrator which roles is to update the Dapps and its rules. But also to add or delete user while also defining the rights that they have on the blockchain (I intend to use a permisionned blockchain). Finally, they are also here to help in case of technical problem.
The Dapps that I'm thinking about works in the following:
A user, the customer, can place an order (a list of products) to a
certain seller and choose the final destination of the order.
The order is then put together before being shipped or stocked in the
depots of one of the stakeholders (distributor or retailer) with a
description of the stocking and/or shipping condition of the product
(for example the product must be stocked or transported in a room
with a temperature of less than 5°C). During the shipping and
storing, an IOT device will feed the drops with the temperature and
geolocation of the product by updating the data each 5-10mn.
Obviously they will be a function that allows all the users to see
the history of the order passed and search inside a specific order.
In case where the temperature doesn't respect the temperature
recommended, then the smart-contract send an alert. The same if the
collocation of the product is "weird" like being in some European
countries and not in an Asian country, an alert will be sent again by
the smart-contractual. Finally, in the case where the product is sent
to the asked location by the customer, then the money for the order
will be paid to the seller.
So based on what I explained, I came here in hope that someone tell me if the use cases and UML that I did were correct or not.
I thank in advance anybody who'll take the time to help me.
Its my first time making a use case and this is for my coursework.
I had to follow the case study below.
Case Study 8: Warehouse Control System (WCS)
A warehouse distributes health food and related products. Customers order a particular
product and quantity from the warehouse. The Warehouse Control System WCS saves the
order and provides to the customer the order number. The WCS generates a pick list and
shopping label, which tells the order-picker person how many of each item to pick to fulfil
the order. The order-picker picks the items, places them in the box, and places the shipping
label on it. The order-picker then uses the WCS to specify whether the order is ready or
not. Then the manager sends the order number, address, and the payment data to the
shipping company. At the end of the day, the shipping company arrives to pick up all the
orders. The inventory of the product in stock is carried out by the staff, but in others, it is
outsourced to an external company. Each staff has a specific function which is either to
raise an order or check the re-order level of the products in stock.
The company wants to create a computer system that allows employees and external
companies to access the application system on desktop. Model, design and implement a
GUI client that can access the database using Visual Studio or any other software
development package. The database must be designed from the class model and the entity
data model using MS Access or Oracle database.
I'm not sure: should the Warehouse Control System (WCS) be an actor ? If not how to make the use case without it?
Here the use case I made:
The WCS is the system under consideration (the blue boundary).
Some observations:
Use verb-subject(-object) to name use cases
Order ready and the like are no use cases
Try to not start functional decomposition (like it seems you did with that Order ready
I recommend to read Bittner/Spence about use cases as usual.
So, not really sure if this is the right place for this but I have this current Context level data flow diagram for the bellow specification extract and I have never done one before so I was wondering if it was correct or if it needs fixing? any help appreciated
This is a link to a screen of my current one http://i.imgur.com/S4xvutc.png
SPECIFICATION
Currently the office staff operate the following processes:
Add/Amend/Delete Membership
This is run on-demand when a new membership application is received or when a member indicates that he/she wishes to make amendments to their details. It is also run in those rare instances when a membership is terminated at the discretion of the manager. A new member has an ID number allocated (simply incremented from the previous membership accepted). A membership balance is also maintained for accounting purposes.
Another process operates in a similar fashion on data associated with transfer partners.
Monthly Maintenance
This is run on the last day of each month to issue requests and reminders for subscriptions due, and to remove memberships where fees remain outstanding. Standard letters are also generated. Membership balances are updated as appropriate.
Payment Updates
This is run prior to the Monthly Maintenance, with membership balances being updated accordingly.
Payments to partners are also disbursed at this time.
New Member Search
This is run whenever a new member has been added to the database. The partners are partitioned in terms of vehicle category and location. Normally, there is a limited choice of partner in a particular location (if, indeed, there is any choice) but for some popular destinations, several partners are involved in providing the airport transfer. Thus, a search is then made through the appropriate section for potential matches in the following manner:
A search is then made on the grounds of sex (many female passengers in particular prefer a driver of their own sex, especially if travelling alone or in couples).
Matches are then selected according to factors such as cost (if available), availability of extra requested facilities (such as child seats, air-conditioning etc.)
Existing Member - Additional Searches
These are run on-demand in the same fashion as for a new member's search. Members may of course request any number of such searches, but a separate payment is due for each.
All financial transactions (payments) are also posted to the separate Accounts file, which also stores other financial details relating to running costs for the consideration of the firm's accountants at the end of the financial year.
Thanks for any help, regarding this level 0 Context only DFD
It needs some fixing.
The most obvious flaw is that you use verbs in your dataflows. In some cases this can be fixed easily by just discarding the verb. Return balance and status is not a datflow, but balance and status is.
In others cases it is not so easy. Check Balance, is it outstanding? sounds more like a Process than a dataflow. It looks like Accounting is responsible for doing that job. So will Accounting produce a list of outstanding balances? Or will it return a single balance and status, and if so, based on what input? Will your Airpot Transport System send a list of balances to check to Accounting?
Take for example Monthly Maintenance. What matters is that you want
requests and reminders for subscriptions due
Standard letters
These need to be visible in your DFD
The fact that you want to remove memberships where fees remain outstanding, probably has not place in the toplevel diagram, because that looks like an internal affair.
In general, focus on what the System produces. Maintaining internal state is secondary, is is a necessity to produce the desired output.