As a Java developer I maintain my skills in order to be competitive in the market. When I heard all those buzz words about containers – Docker, Kubernetes, and modernizing your application for cloud I decided to give it a try. In February I participated in the Index 2018 conference in San Francisco. At the conference I demoed a small Code for Good quiz for which I modernized JPetStore, a sample Java EE application, with Kubernetes and AI.

JPetStore is a traditional Java Enterprise Edition application that demonstrates the best practices for deploying the Java EE application with the latest standards. I got my hands on a version with Spring and MySQL DB.

“The Pet Store Demo is the reference application for J2EE that showcases the main features of the J2EE platform. It’s part of the Blueprints program that seeks to provide best practice guidelines for J2EE application development.
Implicit in the Java Pet Store is a set of components that can be reused in other contexts. For example, the Java Pet Store includes a shopping cart, a mailer, and inventory components. It’s our intention that this reference application can be used as a framework for building real-world applications. In addition, recommendations about typical design decisions need to be made, such as JSP versus servlets, stateful versus stateless session beans, and container- versus bean-managed persistence.”
Larry Freeman, Manager J2EE Blueprints team. Read the full interview with Larry.
JPetStore picture
JPetStore interface

I followed these simple steps to modernize the infrastructure of the application. I containerized it, brought it to the cloud, and added an AI powered mobile app as the new UX:

  1. Dockerized the application
  2. Deployed it with Kubernetes
  3. Accessed the new UX with AI (the Android app with IBM Watson)

Step one: Dockerize the application

I found a nice recipe for Dockerizing the JPetStore app. Basically, I created an account on docker.io (blumareks). I added my image of JPetStore to the repository so it can be referenced in the next steps.

I didn’t change the MySql DB Docker file from the DockerCon 2017 for this repository:

  1. FROM mysql:5.5
    ADD mysql5/*.sql /docker-entrypoint-initdb.d/
    
  2. The JEE Liberty server file with the JPetStore app looks like this:
    
    # Build JPetStore war
    FROM openjdk:8 as builder
    COPY . /src
    WORKDIR /src
    RUN ./build.sh warfile
  3. Use WebSphere Liberty base image from the Docker Store:
    
    FROM websphere-liberty:latest
    
    # Copy war from build stage and server.xml into image
    COPY --from=builder /src/dist/jpetstore.war /opt/ibm/wlp/usr/servers/defaultServer/apps/
    COPY --from=builder /src/server.xml /opt/ibm/wlp/usr/servers/defaultServer/
    RUN mkdir -p /config/lib/global
    COPY lib/mysql-connector-java-5.1.45.jar /config/lib/global
    
  4. I changed the files responsible for the push to the registry, docker-compose.yml:
    
    version: "3.3"
    services:
    web:
    image: blumareks/jpetstore:latest
    build: .
    ports:
    - "80:9080"
    environment:
    - VERSION=1
    
    db:
    image: blumareks/jpetstoredb:latest
    build: ./db
    ports:
    - "3306:3306"
    environment:
    - MYSQL_ROOT_PASSWORD=foobar
    - MYSQL_DATABASE=jpetstore
    - MYSQL_USER=jpetstore
    - MYSQL_PASSWORD=foobar
    
  5. After that I was able to build and run my docker image using Docker for Mac:
    
    $ docker-compose build
    $ docker-compose up -d
    
  6. To stop it and remove the images (rm):
    
    docker-compose stop
    docker-compose rm -f
    

After testing the code to make sure everything worked (http://localhost/jpetstore) I pushed the images to the Docker repository:


$ docker-compose push

Running my image on my local machine, even in the cool Docker, wasn’t what I wanted to do. I wanted to deploy it on the cloud and leave it there. I learned that people are using Kubernetes to do that. I decided to do what is fashionable – the Silicon Valley way.

Step two: Deploy with Kubernetes

Running Docker images was a great experience. Now I am ready to deploy the application to the IBM Cloud.

Note: You must have a pay-as-you-go or subscription account to the IBM Cloud to create a free cluster.

To create a free cluster:

  1. From the IBM Cloud Catalog go to the Containers category, click Containers in Kubernetes Clusters.
  2. Read up on clusters, then click Create. Enter a cluster name.
  3. The default cluster type is free. Next time, you can create a standard cluster and define additional customizations, like the number of worker nodes.
  4. Click Create Cluster. The details for the cluster open, but the worker node in the cluster takes a few minutes to provision. You can see the status of the worker node in the Worker nodes tab. When the status reaches Ready, your worker node is ready to use.

Setting up the cluster took some time (well, you might look in Step three). When it was done, my cluster was ready.

IBM Cloud Dashboard with running Kubernetes cluster

The easiest way to get access to your Kubernetes cluster is to use the GUI provided by IBM Cloud. When you click on the name of your cluster a details page opens. To open the dashboard click Access in the menu on the left nav. Follow the directions on the page.

Getting access to the Kubernetes dashboard

When everything is ready, open the dashboard. You need the token for that:


$ kubectl config view -o jsonpath='{.users[0].user.auth-provider.config.id-token}'

$ kubectl proxy

Copy the token and use it in the login screen.

I needed to create mysql-pod, mysql-service, and openliberty-pod (the most atomic elements in the Kubernetes are “pods”). I simply clicked the create button and provided links to those 3 files in the following order:

  • shazam4pets-mysql-pod.yaml
  • shazam4pets-mysql-service.yaml
  • shazam4pets-openliberty-rc.yaml
Adding the YAML files
Adding the YAML files

The files use the Docker images created earlier. Here are the listings (SPACES ARE IMPORTANT – seriously 🥇):

shazam4pets-mysql-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod
  labels:
    name: mysql-pod
    context: shazam4pets
spec:
  containers: 
    - 
      name: mysql
      # it is recommended to use the specific version that application support instead of the latest
      # image: mysql:latest
      image: blumareks/jpetstoredb
      env:
        - name: "MYSQL_USER"
          value: "jpetstore"
        - name: "MYSQL_PASSWORD"
          value: "foobar"
        - name: "MYSQL_DATABASE"
          value: "jpetstore"
        - name: "MYSQL_ROOT_PASSWORD"
          value: "foobar"
      ports: 
        - containerPort: 3306

shazam4pets-mysql-service.yaml

apiVersion: v1
kind: Service
metadata: 
  name: mysql-service
  labels: 
    name: mysql-pod
    context: shazam4pets
    app: mysql
spec:
  ports:
    # the port that this service should serve on
    - port: 3306
  # label keys and values that must match in order to receive traffic for this service
  selector: 
    name: mysql-pod
    context: shazam4pets
    app: mysql

shazam4pets-openliberty-rc.yaml

apiVersion: v1
kind: ReplicationController
metadata:
  name: openliberty-rc
  labels:
    name: openliberty
    context: shazam4pets
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: openliberty
    spec:
      containers:
      - name: openliberty-rc-pod
        image: blumareks/jpetstore
        ports:
        - containerPort: 9080

And finally I got everything running as shown here.

Pods and the service running hosting our JPetStore application

I am ready to access it from the new UX. More details on the previous two steps are in my GitHub repo.

Step three: Access the new UX with AI

I was inspired by the Shazam application for music. Similar to Shazam for music, you can point a smart phone on a pet, take a picture, and get the name/breed of the animal along with the price quote from my pet store.

How did I do it? First, I classified what is on the picture. The IBM Watson Visual Recognition service is pretty awesome for animal classification. There is quite a robust classification of dogs with their breeds. There are other animal classifiers as well. I needed an IBM Cloud account to provision the Watson Visual Recognition service. That was easy.

Some time ago I created a selfie app for Android (you can get the Smart Selfie app), so I reused the same code but customized it for my Shazam for pets AI powered app (also available on GitHub.)

In addition to the IBM Watson Visual Recognition, I added the IBM Watson Text to Speech service so kids can get the information faster without reading it (I noticed kids prefer a voice UI). To run this Android app you need the following:

  • Android Studio
  • An android device
  • IBM Cloud account to create Watson services:
    • Watson Visual Recognition service credentials (API KEY) and ID of your custom classifier
    • Watson Text to Speech service credentials (ID and password)

Finally you need to copy the above credentials from those Watson services and paste them into the credentials.xml file for this Android app.

To learn more and see videos about this process go to my github repository.

An earlier version of this post was published on Medium.

Join The Discussion

Your email address will not be published. Required fields are marked *