- This tutorial requires access to Oracle Cloud. To sign up for a free account, see Oracle Cloud Free Tier.
- It uses example values for Oracle Cloud Infrastructure credentials, tenancy, and compartments. When completing your lab, substitute these values with ones specific to your cloud environment.
Data-centric microservices walkthrough with Helidon MP
This lab will show you how to deploy and run data-centric microservices highlighting use of different data types, data and transaction patterns, and various Helidon MP features.The lab will then show you metrics, health checks and probes, and tracing that have been enabled via Helidon annotations and configuration.
Create and bind OCI Service Broker to existing ATP instance
Set up Oracle Advanced Queuing in existing ATP instances
Deploy GrabDish Store Services
After you have successfully set up the databases, you can now test the “GrabDish” Food Order application. You will interact with several different data types, check the event-driven communication, saga, event-sourcing and Command Query Responsibility Segregation via order and inventory services. Go ahead and deploy the related order, inventory and supplier Helidon services. The Food Order application consists of the following tables shown in the ER diagram:
The Food Order application consists of a mock Mobile App (Frontend Helidon microservice) that places and shows orders via REST calls to the order-helidon microservice. Managing inventory is done with calls to the supplier-helidon microservice.
When an order is placed, the order service inserts the order in JSON format and in the same local transaction sends an
orderplacedmessage using AQ JMS. The inventory service dequeues this message, validates and adjusts inventory, and enqueues a message stating the inventory location for the item ordered or an
inventorydoesnotexiststatus if there is insufficient inventory. This dequeue, database operation, and enqueue are done within the same local transaction. Finally, the order service dequeues the inventory status message for the order and returns the resultant order success or failure to the frontend service.
This is shown in the below architecture diagram.
Open the Cloud Shell and go to the order folder, using the following command.
Go ahead and execute the same steps for deploying the inventory Helidon service, using the following command.
cd $MSDATAWORKSHOP_LOCATION/inventory-helidon ; ./deploy.sh
Once the image has been deployed in a pod, you should see the following message.
Use the same method to deploy the supplier Helidon service. Use the following command.
cd $MSDATAWORKSHOP_LOCATION/supplier-helidon-se ; ./deploy.sh
You can check that all images have been successfully deployed in pods by executing the following command.
The services are ready, and you can proceed to test the application mechanisms.
Verify Order and Inventory Activity of GrabDish Store
Open the frontend microservices home page from the previous lab. If you need the URL again, execute the
servicesshortcut command and note the External-IP:PORT of the msdataworkshop/frontend/LoadBalancer.
Click Transactional under Labs.
Check the inventory of a given item such as sushi, by typing
foodfield and clicking Get Inventory. You should see the inventory count result 0.
(Optional) If for any reason you see a different count, click Remove Inventory to bring back the count to 0.
Let’s try to place an order for sushi by clicking Place Order.
To check the status of the order, click Show Order. You should see a failed order status.
This is expected, because the inventory count for sushi was 0.
Click Add Inventory to add the sushi in the inventory. You should see the outcome being an incremental increase by 1.
Go ahead and place another order by increasing the order ID by 1 (67) and then clicking Place Order. Next click Show Order to check the order status.
The order should have been successfully placed, which is demonstrated with the order status showing success.
Although this might look like a basic transactional mechanic, the difference in the microservices environment is that it’s not using a two-phase XA commit, and therefore not using distributed locks. In a microservices environment with potential latency in the network, service failures during the communication phase or delays in long running activities, an application shouldn’t have locking across the services. Instead, the pattern that is used is called the saga pattern, which instead of defining commits and rollbacks, allows each service to perform its own local transaction and publish an event. The other services listen to that event and perform the next local transaction.
In this architecture, there is a frontend service which mimics some mobile app requests for placing orders. The frontend service is communicating with the order service to place an order. The order service is then inserting the order into the order database, while also sending a message describing that order. This approach is called the event sourcing pattern, which due to its decoupled non-locking nature is prominently used in microservices. The event sourcing pattern entails sending an event message for every work or any data manipulation that was conducted. In this example, while the order was inserted in the order database, an event message was also created in the Advanced Queue of the Oracle database.
Implementing the messaging queue inside the Oracle database provides a unique capability of performing the event sourcing actions (manipulating data and sending an event message) atomically within the same transaction. The benefit of this approach is that it provides a guaranteed once delivery, and it doesn’t require writing additional application logic to handle possible duplicate message deliveries, as it would be the case with solutions using separate datastores and event messaging platforms.
In this example, once the order was inserted into the Oracle database, an event message was also sent to the interested parties, which in this case is the inventory service. The inventory service receives the message and checks the inventory database, modifies the inventory if necessary, and sends back a message if the inventory exists or not. The inventory message is picked up by the order service which based on the outcome message, sends back to the frontend a successful or failed order status.
This approach fits the microservices model, because the inventory service doesn’t have any REST endpoints, and instead it purely uses messaging. The services do not talk directly to each other, as each service is isolated and accesses its datastore, while the only communication path is through the messaging queue.
This architecture is tied with the Command Query Responsibility Segregation (CQRS) pattern, meaning that the command and query operations use different methods. In our example the command was to insert an order into the database, while the query on the order is receiving events from different interested parties and putting them together (from suggestive sales, inventory, etc). Instead of actually going to suggestive sales service or inventory service to get the necessary information, the service is receiving events.
Let’s look at the Java source code to understand how Advanced Queuing and Oracle database work together.
What is unique to Oracle and Advanced Queuing is that a JDBC connection can be invoked from an AQ JMS session. Therefore we are using this JMS session to send and receive messages, while the JDBC connection is used to manipulate the datastore. This mechanism allows for both the JMS session and JDBC connection to exist within same atomic local transaction.
Click Spatial on the Transactional tab
Check Show me the Fusion menu to make your choices for the Fusion Cuisine
Click the plus sign to add Makizushi, Miso Soup, Yakitori and Tempura to your order and click Ready to Order.
Click Deliver here to deliver your order to the address provided on the screen
Your order is being fulfilled and will be delivered via the fastest route.
This demo demonstrates how geocoding (the set of latitude and longitude coordinates of a physical address) can be used to derive coordinates from addresses and how routing information can be plotted between those coordinates.
Oracle JET web component
Notice @Timed and @Counted annotations on placeOrder method of $MSDATAWORKSHOP_LOCATION/order-helidon/src/main/java/io/helidon/data/examples/OrderResource.java
Click Tracing, Metrics, and Health
Click Show Metrics and notice the long string of metrics (including those from placeOrder timed and counted) in prometheus format.
Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE) provides health probes which check a given container for its liveness (checking if the pod is up or down) and readiness (checking if the pod is ready to take requests or not). In this STEP you will see how the probes pick up the health that the Helidon microservice advertises. Click Tracing, Metrics, and Health and click Show Health: Liveness
Notice health check class at
$MSDATAWORKSHOP_LOCATION/order-helidon/src/main/java/io/helidon/data/examples/OrderServiceLivenessHealthCheck.javaand how the liveness method is being calculated.
Notice liveness probe specified in
livenessProbecan be set up with different criteria, such as reading from a file or an HTTP GET request. In this example the OKE health probe will use HTTP GET to check the /health/live and /health/ready addresses every 3 seconds, to see the liveness and readiness of the service.
In order to observe how OKE will manage the pods, the microservice has been created with the possibility to set up the liveliness to “false”. Click Get Last Container Start Time and note the time the container started.
Click Set Liveness to False . This will cause the Helidon Health Check to report false for liveness which will result in OKE restarting the pod/microservice
Click Get Last Container Start Time. It will take a minute or two for the probe to notice the failed state and conduct the restart and as it does you may see a connection refused exception.
Eventually you will see the container restart and note the new/later container startup time reflecting that the pod was restarted.
Notice @Traced annotations on
$MSDATAWORKSHOP_LOCATION/order-helidon/src/main/java/io/helidon/data/examples/OrderResource.javaAlso notice the additional calls to set tags, baggage, etc. in this
Place an order if one was not already created successfully in STEP 1 of this Lab.
Click Show Tracing to open the Jaeger UI. Select
Servicedropdown menu and click Find Traces.
Select a trace with a large number of spans and drill down on the various spans of the trace and associated information. In this case we see placeOrder order, saga, etc. information in logs, tags, and baggage.
If it has been more than an hour since the trace you are looking for, select a an appropriate value for Lookback and click Find Traces.
- Author - Paul Parkinson, Dev Lead for Data and Transaction Processing, Oracle Microservices Platform, Helidon
- Adapted for Cloud by - Nenad Jovicic, Enterprise Strategist, North America Technology Enterprise Architect Solution Engineering Team
- Documentation - Lisa Jamen, User Assistance Developer - Helidon
- Contributors - Jaden McElvey, Technical Lead - Oracle LiveLabs Intern
More Learning Resources
Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.
For product documentation, visit Oracle Help Center.