📜 ⬆️ ⬇️

Application Configuration with github



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.java
package 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

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")


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.

Source: https://habr.com/ru/post/275225/


All Articles