
Configuration is just as important a part of the code, especially in large projects. But often they treat it as a second-rate artifact of software development and operation. Bad if the configuration does not go through the same full cycle as the software. About audit changes and versioning forget, or spend not the most appropriate tools for this.
I have seen many projects where the configuration is enclosed in the file system in the form of properties / json / xml files with incomprehensible redefinitions to the mind at the moment of loading. And what actually uses the application becomes clear only after viewing the log files of the component or during debugging.
The script for auto-installation of your Git repository can be found in the “Configuration in your own git repository” section.
')
When choosing git, you can use all the tools that are used in development. Make reviews, compare configurations, support different configuration branches, reference tags, use both visual tools and tools in the command line.
To use all this powerful arsenal, we just need to learn how to read the configuration from the git repository.
To do this, use the Java class to read the configuration. It is based on a wrapper around hawtio-git (which in turn uses
JGit under the hood) and is available on github
git-configuration and in
maven central .
Seeing the configuration chaos around I will try to remind you of the light and beautiful.For the first time, the idea of storing a configuration in git inspired after exploring fuse fabric /
fabric8 .
The magnificent
spring-cloud-config project can also store the configuration in the git repository. But if we do not need a dependency on spring and its PropertySource abstraction, then the solution from this publication is better suited for an application on jvm.
Configuration on github
Let's start by reading the configuration we placed in the githab repository ...
Java
Configuration.javapackage com.github.igorsuhorukov.configuration; import com.github.igorsuhorukov.codehaus.plexus.util.IOUtil; import com.github.igorsuhorukov.smreed.dropship.MavenClassLoader; import io.hawt.git.GitConfigurationHelper; import java.io.InputStream; public class Configuration { public static void main(String[] args) throws Exception{ GitConfigurationHelper gitConfigurationHelper = new GitConfigurationHelper("https://github.com/igor-suhorukov/aspectj-scripting.git"); System.out.println("CONFIGURATION FROM GIT: HEAD REVISON ----------------------------------"); System.out.println(gitConfigurationHelper.getFileContent("master","pom.xml")); System.out.println("CONFIGURATION FROM GIT: BY TAG ----------------------------------------"); System.out.println(gitConfigurationHelper.getFileContent("master","aspectj-scripting-1.2", "pom.xml")); gitConfigurationHelper.destroy(); System.out.println("CONFIGURATION FROM MAVEN REPO -----------------------------------------"); InputStream configStream = MavenClassLoader.usingCentralRepo().resolveArtifact("com.github.igor-suhorukov:aspectj-scripting:pom:1.3").openStream(); System.out.println(IOUtil.toString(configStream)); } }
Dependencies required for example operation:
<dependency> <groupId>com.github.igor-suhorukov</groupId> <artifactId>git-configuration</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>com.github.igor-suhorukov</groupId> <artifactId>mvn-classloader</artifactId> <version>1.4</version> </dependency>
To get the configuration, you need to specify the path to our repository:
new GitConfigurationHelper("https://github.com/igor-suhorukov/aspectj-scripting.git")
Possible options
- Use the latest version of the file from the specified brunch:
gitConfigurationHelper.getFileContent("master","pom.xml")
- Or get a specific version of the tag (in the example this is the tag "aspectj-scripting-1.2") or revision:
gitConfigurationHelper.getFileContent("master","aspectj-scripting-1.2", "pom.xml")
And at the end of the work, close the connection with the repository:
gitConfigurationHelper.destroy()
As a nice addition to the configuration storage in git, you can also read the configuration from the maven repository. This requires the mvn-classloader: 1.4 library, which is already included in groovy-grape-aether: 2.4.5.2.
URL artifact = MavenClassLoader.usingCentralRepo (). ResolveArtifact ("com.github.igor-suhorukov: aspectj-scripting: pom: 1.3")
- usingCentralRepo () - from the central repository.
- using (repositoryPath) - for your corporate repository.
Further work with the artifact is quite simple. Calling the artifact.getFile () method allows you to get a link to the artifact in the local file system, and artifact.openStream () opens the InputStream to this file.
In what format to store the configuration and how to parse these files further - depends on the task and preferences and you decide. The configuration can be either a simple java.util.Properties, or Json (Gson / jackson), JAXB / XStream, or a configuration in the form of scripts on groovy, scala, javascript ...
Groovy
The same thing from the past header about java is much more concise written in groovy. You can run the example with the command:
java -jar
groovy-grape-aether-2.4.5.2.jar readGitConfig.groovy
readGitConfig.groovy
import com.github.igorsuhorukov.smreed.dropship.MavenClassLoader @Grab(group = 'com.github.igor-suhorukov', module = 'git-configuration', version = '1.0') import io.hawt.git.GitConfigurationHelper def gitConfigurationHelper = new GitConfigurationHelper('https://github.com/igor-suhorukov/aspectj-scripting.git') println 'CONFIGURATION FROM GIT: HEAD REVISON ----------------------------------' println gitConfigurationHelper.getFileContent('master','pom.xml') println 'CONFIGURATION FROM GIT: BY TAG ----------------------------------------' println gitConfigurationHelper.getFileContent('master','aspectj-scripting-1.2', 'pom.xml') gitConfigurationHelper.destroy() println 'CONFIGURATION FROM MAVEN REPO -----------------------------------------' def configStream = MavenClassLoader.usingCentralRepo().resolveArtifact('com.github.igor-suhorukov:aspectj-scripting:pom:1.3').openStream() println configStream.text
Configuration in own git repository
As an in-house repository, I chose
Gitblit , for those who know java, it is easier to install and maintain, and the push hooks mechanism on
Groovy allows you to work wonders. Alternatively, you can choose
Gogs - Go Git Service or any other Git repository server.
We will run the Gitblit server and configure it using the groovy auto-install script.
java -jar
groovy-grape-aether-2.4.5.2.jar gitblit.groovy
gitblit.groovy
import com.github.igorsuhorukov.smreed.dropship.MavenClassLoader @Grab(group='org.codehaus.plexus', module='plexus-archiver', version='2.10.2') import org.codehaus.plexus.archiver.zip.ZipUnArchiver @Grab(group='org.codehaus.plexus', module='plexus-container-default', version='1.6') import org.codehaus.plexus.logging.console.ConsoleLogger @Grab(group = 'org.eclipse.jetty', module = 'jetty-runner', version = '9.3.7.RC1' ) import org.eclipse.jetty.runner.Runner def gitblit = new File(MavenClassLoader.using('http://gitblit.imtqy.com/gitblit-maven').resolveArtifact('com.gitblit:gitblit:war:1.7.1').getFile()) File gitblitDirectory = new File(System.getProperty('user.home'), gitblit.getName().replace('.war','')) if(!gitblitDirectory.exists()){ gitblitDirectory.mkdir() ZipUnArchiver unArchiver = new ZipUnArchiver() unArchiver.setSourceFile(gitblit) unArchiver.enableLogging(new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG,"Logger")) unArchiver.setDestDirectory(gitblitDirectory) unArchiver.extract() def dataPath = new File(System.getProperty('user.home'), '.gitblit_data') if(!dataPath.exists()){ dataPath.mkdir() } def webXml = new File(gitblitDirectory.getAbsoluteFile(), 'WEB-INF/web.xml') webXmlText = webXml.text webXml.withWriter { w -> w << webXmlText.replace('${contextFolder}/WEB-INF/data', dataPath.getAbsolutePath()) } } Runner.main([gitblitDirectory] as String[])
The script downloads gitblit.war from the project repository, unpacks it into the user's home directory and replaces the path to the repository repository in the gitblit configuration. After that, it starts the jetty server and gitblit inside it.

I will give a sequence of commands that I used to create a configuration in the new repository ssh: // admin @ localhost: 29418 / configuration.git
vim configuration.properties git add configuration.properties git commit -m "import config" git tag -a ver1.0 -m "configuration version 1.0" vim configuration.properties git add configuration.properties git commit -m "update config" git push -u origin master --tags
The configuration read code is no different from the previous examples. It remains only to create an object in the code:
new GitConfigurationHelper("http://admin@localhost:8080/r/configuration.git")
And use the same API as in the github example.

Results
In the publication, we looked at how to read the configuration in java / groovy from the git and maven repositories. Using the groovy script, we were able to install and configure the gitblit repository automatically.
The code from the article is applicable in jvm projects and it would be interesting to hear from you how the same problem is solved in other programming languages and on other platforms.