recursive.codes

recursive.codes

recursive.codes


The Personal Blog of Todd Sharp

Building And Deploying A Helidon Microservice With Hibernate Part 1

Posted By: Todd Sharp on 7/3/2019 12:00 GMT
Tagged: Cloud, Containers, Microservices, APIs, Developers

In the last few posts of our microservice journey we created a compartment, launched a Kubernetes cluster and set our tenancy up for a Docker user and registry and created an Autonomous DB instance that we can use for data persistence. In this post we will start to take a look at writing some actual microservice code. I want to reiterate that each application has unique requirements that should be evaluated before you choose to implement any solution and so the choices that I make in this blog series might be different than the choices your organization will make. The important questions to ask yourself are:

These are important questions to ask yourself, because introducing a new way of thinking can bring up issues that are difficult to resolve later on.

Microservice Patterns

Before we dive into the code, let’s start by defining a few patterns for microservice data management. The easiest patterns to digest when it comes to microservices are the shared database and database (or schema) per service patterns so let’s start with those patterns.

Shared Database

In monoliths, our data is usually stored in a single relational database. This made life easy when it came to persistence and querying – we could write queries that utilized joins and we could use ACID transactions to enforce data consistency. The shared database microservice pattern states that a single database is shared by multiple services which can freely query across tables using joins to retrieve data and utilize transactions to modify data in a reliable way that enforces consistency. That makes this pattern less difficult to comprehend for new developers, however it introduces challenges as our API becomes more complex. Schema changes now have to be coordinated with developers of other services because adding columns, changing default values and other operations could potentially break services that might access that same table. Also, long running transactions have the potential to block other services by holding locks on shared tables. Lastly, this pattern assumes that all services will persist their data in a traditional relational table and eliminates the possibility of utilizing NoSQL documents or Graph DB’s for persistence (there are workarounds here, which we’ll see a bit later on).

Database (or Schema) Per Service

The database (or schema) per service pattern addresses some of the shortcomings of the shared database pattern. Each service gets its own database which essentially means the database is part of the implementation of that service. Schema changes now won’t impact other services. This doesn’t necessarily have to result in a database server for each service. Often times it can be represented by individual tables per service (as long as there are users and permissions bound to each table which restrict access by other services), or even as a unique schema within a database instance for each service. Using database per service means that each service is free to use the type of database that is best suited to their needs.  Of course, there are some downsides to this pattern. Transactions are now difficult to manage. Referential integrity can’t be enforced as easily. Queries that join data can be difficult, if not impossible.

Enough Already, Show Me The Code!

I've done a lot of talking so far in this series about what microservices are and why you might use them, but it's always best to look at code to understand these theories so let's finally do that. For this series, we’ll build out an API for a simple social media style application in several parts. This gives us the opportunity to utilize some different microservice patterns as well as various features in the cloud and should present some interesting problems that we’ll need to address.

Building A User Service

Description

This service utilizes Helidon MP with Hibernate to persist users to a user table in an Oracle ATP instance. To get started, we can utilize the Heldon Maven archetype which will scaffold out some files and structure for our service. Here's the command (you can modify the path to your liking, or leave it as is):

Before we modify or look at the generated code, let's create our schema user for this microservice. You'll need to connect to your running ATP instance as admin to run the next query. Using SQL Developer Web as shown in the last post in this series would be an easy way to run it. Once you're ready, run the following (making sure to modify the password to something strong):

If you're using SQL Developer Web, you'll need to ensure that the admin user enables each schema that you would like to use with the following command:

For the command above, the placeholder values should be substituted as follows:

After enabling user access, the ADMIN user needs to provide the enabled user with their URL to access SQL Developer Web. This URL is the same as the URL the ADMIN user enters to access SQL Developer Web, but with the admin/ segment of the URL replaced by schema-alias/.

From here on out, we'll use the usersvc user, so log out of SQL Developer Web (or whatever tool you're using) and log in with the new username and password that we just created at the proper URL per the instructions above. Once logged in with the usersvc user, run the following to create a table for the microservice:

Next, we'll need to grab some dependencies. Create a folder called /build-resource in the root of the project and add a subdirectory called /libs. We'll need to grab the following JAR files so that our project can use the OJDBC driver to talk to our ATP instance:

Download the JARs from Oracle and place them in /build-resource/libs.  We also need to publish these to our local Maven repo so that when we run the application locally they'll be properly resolved. The following commands should help you out with that:

Next, modify your pom.xml file to include all of the necessary dependencies for JPA, Hibernate, Jackson and the OJDBC JARs.  Add the following entries to the dependencies section:

We'll need to add a Hibernate persistence config, so create a file under /src/main/resources/META-INF called persistence.xml and populate it like so:

While you're in that directory, modify microprofile-config.properties like so:

Now that we have all of our prerequisite configuration complete we can move on to the application code.  Locate the generated GreetApplication.java file. You can either modify it, or delete it and replace it with a new file, but ultimately we want to end up with a UserApplication.java that contains the following code:

Use the same process (modify or replace) for GreetingProvider to end up with a UserProvider that looks like so:

The UserProvider class will contain our populated configuration values when we run the application. At this point, we're ready to start writing the real logic of our microservice. In the next post in this series we'll take a deep dive into that code and get our service running and deployed on the Oracle Cloud.

Photo by Joshua Earle on Unsplash



Related Posts

Querying Autonomous Database from an Oracle Function (The Quick, Easy & Completely Secure Way)

Querying Autonomous Database from an Oracle Function (The Quick, Easy & Completely Secure Way)

I've written many blog posts about connecting to an Autonomous DB instance in the past. Best practices evolve as tools, services, and frameworks become...

Brain to the Cloud - Part III - Examining the Relationship Between Brain Activity and Video Game Performance

Brain to the Cloud - Part III - Examining the Relationship Between Brain Activity and Video Game Performance

In my last post, we looked at the technical aspects of my Brain to the Cloud project including much of the code that was used to collect and analyze the...

Brain to the Cloud - Part II - How I Uploaded My Brain to the Cloud

Brain to the Cloud - Part II - How I Uploaded My Brain to the Cloud

In my last post, we went over the inspiration, objectives, and architecture for my Brain to the Cloud project. In this post, we'll look in-depth at the...

Note: Comments are currently closed on this blog. Disqus is simply too bloated to justify its use with the low volume of comments on this blog. Please visit my contact page if you have something to say!