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).
- provision the infrastructure
- install, configure then restore the service’s content
- 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 service – MongoDb in our case.
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.
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.?