Monday, September 01, 2014

Gitcon, runtime configuration via a Git repo

This weekend, aside from taking kid to football game and various classes, changing diapers and watching "Breaking bad", I've been working on an new small open source library, Gitcon, which allows Java application to decouple some configuration into a standalone source repository so that software owner can modify configuration without deploying application for every modification. It is a cheap approach to dynamic configuration.

By the way, I was very surprise to find out that the term "Gitcon" has not been reserved for "Git conference" so far.


What led me to this project was a set of requirements:
  1. As a start, the configuration means properties file
  2. As a start, only Git source repository needs to be supported
  3. As a start, it only needs to gets configuration for once when application starts. The configuration is used to populate Spring application context where beans are mostly singletons. Software owner needs to restart application to pick up configuration change.
  4. The library must be very friendly to Spring
  5. It gets file from Git repo authenticated via SSH key.
  6. The SSH private key must be configurable
  7.  This is outside the scope of the library, but the SSH key comes from S3, which is authenticated by instance profile
  8. When SSH key is not specified, default one in user's home directory is applied. This is for development purpose.
  9. One Spring context may includes multiple properties coming from multiple repositories authenticated with different SSH keys.
  10. One properties file can include another under the same repository
 These requirements are the minimal goals that the first version of Gitcon must achieve in order to replace configurations of some existing applications.


The design is fairly straightforward. All it needs is to cope with the limitations from Jsch that JGit relies on.

1. S3FileFactoryBean

S3FileFactoryBean is something that takes an IAM, a bucket and a key, downloads a file from S3 into local temporary directory, returns the file and deletes it when Spring context closes. Since the logic is generic to the purpose of Gitcon, it lives in a neutral package, kaufman-aws as artifact org.cyclopsgroup:kaufan-aws:0.0.2.

<bean id="gitSshKeyFile" class="">
    <constructor-arg value="my-s3-bucket" />
    <constructor-arg value="my-app/git-ssh-private.key" />

2. Clone, checkout Git repo with JGit

The easiest way to clone a Git repo is to use JGitLocalResourceRepository. With support from Eclipse JGit, this class defines Git repository URI, the access to Git repository and optionally the path to SSH private key. You may find out more details in Javadoc. An example:

<bean id="gitResourceRepo"
        value="" />
    <property name="sshIdentityFile" ref="gitSshKeyFile" />

3. Create properties

The class GitconPropertiesFactoryBean simply creates Properties instance out of given ResourceRepository and a path to properties file. Since it creates Properties with ExtendedProperties, variable replacement and file inclusion is supported.

<bean id="appProperties"
    <constructor-arg ref="gitResourceRepo" />
    <constructor-arg value="myapp/" />

If you haven't tried, ExtendedProperties interprets properties file in a different way than Properties and exposes the content with a much more user friendly API. It is an ancient class from commons-collections, if a human is as old as this class, he would probably get a driver license by now.

4. Expand properties in Spring

This is done by a simple setup in Spring. It doesn't belong to Gitcon but I put it here so that the story is complete. The following config does the work.

<context:property-placeholder properties-ref="appProperties" />

To learn more

Like other CyclopsGroup projects, Gitcon Maven site is published to Very soon I will come up with a few wiki pages with official guides and examples.

Javadoc can be found here. Source code is in Github. The first version, org.cyclopsgroup:gitcon:0.0.1 has been published into Maven central repository.

If you have question, please feel free to contact me in Github, Facebook or Google+. Thank you for reading.

No comments: