The Blog

 

Introduction to the IBM Stock Trader sample

The IBM Stock Trader application is a simple stock trading sample, where you can create various stock portfolios and add shares of stock to each for a commission. It keeps track of each portfolio’s total value and its loyalty level, notifying you of changes in level, which affect the commission charged per transaction. It also lets you submit feedback on the application, which can result in earning free (zero commission) trades, based on the tone of the feedback. (Tone is determined by calling the Watson Tone Analyzer, which will be covered in a future article).

The sample is intended to showcase what one might expect after performing a lift-and-shift of a traditional monolithic, on-premises application to one that has been refactored as Docker-based microservices running within a modern Kubernetes-based environment. It deliberately shows off how to use the traditional Java EE programming models, such as JDBC and JMS, to access traditional system-of-record resources, such as a relational database or a message queueing infrastructure. Note that while the application usually uses IBM Db2 and MQ, it also works great with open source technologies, like Apache Derby as the relational database, and with the JMS server built-in to Open Liberty.

The concept demonstrates how to run a microservices-based application in a Kubernetes environment. Initially tested in a MiniKube, the application is generally deployed to IBM Cloud Private, the IBM on-premise Kubernetes-based offering, which can be installed independently or atop Red Hat OpenShift. This sample demonstrates usage of various IBM middleware products, such as Db2, MQ, and ODM, each of which are deployed with their helm charts in the IBM Cloud Private catalog, called from Java-based micro-services running atop Open Liberty. You can also deploy this sample to the IBM Cloud Kubernetes Service, the IBM-hosted Kubernetes-based offering in the public cloud.

Logistics

All of the source code is publicly available in GitHub. There are eight repositories underneath the IBMStockTrader org, each of which represents a separate microservice that delivers a specific capability. For example, the /stock-quote repository, provides the functionality of looking up the price of a given stock and takes care of caching such values in Redis for a configurable period of time.

The built versions of each of these repositories are available in public DockerHub. For example, to work with the stock-quote microservice, you would need access to ibmstocktrader/stock-quote, or you would pull it down to your Docker register using docker pull ibmstocktrader/stock-quote.

Whether you prefer to clone the source code from GitHub and build each microservice yourself, or just use the pre-built images in DockerHub, you can easily get this sample up and running in your own Kubernetes environment. There is also a helm chart you can use to deploy it to the IBM Cloud (public or private), which will be discussed in a future article.

Architecture

As stated earlier, this sample has been factored into a set of microservices that work together to deliver the overall application. The following diagram shows the interactions between these microservices:

Stocker Trader for IBM Private Cloud

As you can see, the portfolio microservice sits at the center of the application, serving as the controller in a standard Model View Controller (MVC) architecture, accessed by a choice of clients that provide the view. This microservice takes care of persistence using JDBC, messaging using JMS, and makes REST calls to get stock quotes or to drive a business rule in IBM Operational Decision Manager (ODM); plus, it drives Watson and invokes APIs in API Connect in the public IBM Cloud. There is also one old-fashioned Enterprise Java Bean (EJB) — specifically a Message Driven Bean (MDB), which listens for the messages sent from portfolio, and which invokes a notification service. Using an Istio routing rule (which will be discussed in a future article) that can be specified per portfolio, it sends its notification either to a Slack channel (using a “serverless” IBM Cloud Functions action sequence) or as a tweet to the @IBMStockTrader Twitter account.

Future articles will also look at WeaveScope, which is a Kubernetes plugin that can dynamically generate a microservice interaction diagram for you (among other things), similar to the PowerPoint diagram shown above. Stay tuned for an upcoming article on this cool tool; for now, here’s a quick tease of what it can generate:

WeaveScope Diagram

Clients

Though all of the back-end microservices in this sample are written in Java, we enter the world of polyglot programming when it comes to which user interface you choose. One is written in Java, and the other in Node.js/Vue.js. Both call the exact same REST services from the portfolio microservice, but each renders the results in a different way in the web browser.

The Java client, named trader, is deliberately very simplistic, so as to be easily understood by looking at its source code. It is simply a set of servlets that make REST calls to porfolio and returns raw HTML. There is no fancy CSS or JavaScript, just to keep everything to the point. (In fact, you can turn off the JavaScript engine in your browser and it still works the same.) While not particularly pretty, it gets its point across as to how to call JAX-RS-based microservices and how to deal with the JSON that gets returned and render it in a UI.

Java Client Trader Interface

On the other hand, the other client, named tradr (note the trendy lack of an “e”), delivers a much more modern-looking user interface. Running in the browser’s JavaScript engine, it utilizes Node.js to drive the back-end calls and Vue.js to render the results. Its code is a bit more complicated to walk through, but it is a good example of the kind of sophisticated user interface that customers expect these days.

Modern-looking interface Tradr

Future articles

We hope you have enjoyed this brief introduction to the IBM Stock Trader sample. While this has been a high-level overview, upcoming articles will dive deeper into specific topics of interest. In fact, we’d love to hear your feedback on what topics you’d like to see covered in detail. For now, here’s a proposed list of possible upcoming topics, where we’ll use the sample to drill into how specific features were implemented:

  • Installing the prerequisite products with their helm charts, and then deploying this sample itself with its own helm chart

  • Invoking REST services from Java, using the MicroProfile REST Client feature (mpRestClient-1.0)

  • Security, such as authentication with OpenID Connect, and doing single-signon (SSO) using JSON Web Tokens (JWT)

  • Health checks, using the MicroProfile Heath feature (mpHealth-1.0), and wiring those up to Kubernetes so it can restart an unhealthy microservice

  • Unit of Work isolation, including two-phase commit (XA) transactions across DB2 and MQ

  • Externalizing configuration parameters using Kubernetes config maps and secrets, and accessing those with the MicroProfile Config feature (mpConfig-1.1)

  • Tracking usage metrics with the MicroProfile Metrics feature (mpMetrics-1.1) and viewing the results in Prometheus dashboards

  • Logging and tracing, using the ELK stack (ElasticSearch, LogStash, and Kibana) built in to IBM Cloud Private and the IBM Cloud Kubernetes Service, and viewing a federated logging dashboard, showing log output across microservices/pods, with filtered views showing just what you care about to debug a problem in this distributed environment

  • Using Istio to control routing to different versions of a notification service

  • Using the WeaveScope tool to gain insight into how your microservices are working together at runtime

  • Looking at the two clients in more details, comparing/contrasting using the same REST services from Java and JavaScript

Thank you for your time, and stay tuned for upcoming articles based on this sample!