DevOps | Provisioning and Service Discovery Convention (MongoDb Example)

How do you auto-provision an application service? This (real-world) example uses Vagrant and Ruby to auto-provision MongoDb for a Java application.

installation is a small part of provisioning.

Pay attention to the convention used. Understand the convention and you can auto-provision any middleware service using any iaas technology for any application.

The 3 Provisioning Steps

There are 3 distinct steps required to auto-provision an application service (MongoDb in our case).

  1. provision the infrastructure
  2. install, configure then restore the service’s content
  3. service discovery – allow app to contact service

The most common service discovery pattern is when the app calls and connects to the service. Thus the app needs the service’s contact details. Often – the service needs to know who’s calling – if it doesn’t recognize the number, it won’t pick up the phone.

installing Provisioning is

Auto provisioning a service (Mongo) database end to end is not easy – many confuse installing and provisioning – one is just a small part of the other.

The Service Discovery Convention

Our app needs contact details in order to call up and talk to the database. There is a convention for how this happens and as long as the app (and provisioning scripts) follow the convention, everything works like a charm.

Why Do We Need a Convention

Remember the mantra “convention over configuration” – have you ever wondered why that is so?

Without a convention – we would hardcode lots of key data values everywhere. This makes the app and provisioning scripts brittle. Passwords would be long lived and must be made available to both the provisioning scripts and the app beforehand. With convention, passwords are engineered at the provisioning stage and live for a week at most.

Contacting MongoDb By Convention

These use cases document the convention adhered to by both the provisioning (Ruby) scripts and the (Java) application.

1. How the Java App Contacts MongoDb

Let’s begin where the Java Application contacts its storage serviceMongoDb in our case.

Our MongoDbRegistry.java is responsible for contacting the Mongo database. It employs ClassObject.toSegmentedClassName to pound the class name into a segmented string.

MongoDbRegistry => mongo.db.registry

So mongo.db.registry is the property key. MongoDbRegistry then asks AppProperties to fetch the property value with a key that begins with mongo.db.registry (the next section details how AppProperties implements this request.

AppProperties returns a URL – through which MongoDbRegistry acquires the below mongo database configuration. This mongo configuration is from a real production system – it is untouched – the pasword has not been masked.

Untouched MongoDb Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:mongo="http://www.springframework.org/schema/data/mongo"
          xsi:schemaLocation=
                  "http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <mongo:mongo id="mongo" host="192.168.1.156" port="27017"/>
    
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg ref="mongo"/>
        <constructor-arg name="databaseName" value="laundry4j_store"/>
        <constructor-arg name="userCredentials" ref="userCredentials"/>
    </bean>

    <bean id="userCredentials" class="org.springframework.data.authentication.UserCredentials">
        <constructor-arg name="username" value="mongodb.app.user.7140.1330.sat" />
        <constructor-arg name="password" value="XhTeaIwVv1NAhtAhYvJhdKa7Wt0Zt20h" />
    </bean>

    <mongo:repositories base-package="com.laundry4j.mappers.mongodb" />

</beans>

The password is published because it was in service for only a day. The system releases daily to production. Visit the mongodb xml configuration template.

By using Spring’s dependency injection framework – the business of acquiring MongoDb’s contact details involves no hardcoded strings. It’s all done by convention.

2. How AppProperties Finds the Properties File

The convention used by AppProperties to retrieve a property value is as follows.

An application name of laundry4j has its properties file in the folder com.laundry4j.properties off the user’s home directory. The file itself would be named com.laundry4j.app.properties.

  ${user.home}/com.laundry4j.properties/com.laundry4j.app.properties

No string is hardcoded – com.laundry4j is taken from the root of the url classpath. The tag app.properties is derived from the name of the AppProperties class.

3. How AppProperties Retrieves the Property Value

We’ve seen how AppProperties locates the file.

It reads the property name/value pairs into its cache and provides a directory service for other application classes.

Requests come in with a string key and it picks out the first property that starts with the given key. The comparison is case insensitive.

4. How Did the URL wind up in the Properties File

Remember that MongoDbRegistry asked AppProperties for the value associated with the mongo.db.registry key. How did the property key/value pair wind up in the app.properties file.?

Leave a Reply

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