Конфігурація додатків з допомогою github



Конфігурація є такою ж важливою частиною як і код, особливо у великих проектах. Але часто ставлення до неї, як до другосортного артефакту розробки і експлуатації. Погано якщо конфігурація не проходить той же повний цикл, що і ПО. Про аудит змін і версіонування забувають, або проводять не самим підходящим для цього інструментарієм.

Я бачив багато проектів, де конфігурація підкладається у файлову систему у вигляді properties/json/xml файлів з незбагненними розуму переоределениями в момент завантаження. І що ж насправді використовує додаток стає ясно тільки після перегляду лог файлів компонента або під час налагодження.

Скрипт для автоустановки свого Git репозитарію можете знайти в розділі «Конфігурація у власному git репозитарії».

При виборі git можна використовувати весь той інструментарій, що використовується в розробці. Робити рев'ю, порівнювати конфігурацію, підтримувати різні гілки конфігурації, посилатися на теги, користуватися як візуальними інструментами так і інструментарієм в командному рядку.

Щоб скористатися всім цим арсеналом нам треба лише навчитися читати конфігурацію з git репозитарію.

Для цього використовуємо Java клас для зчитування конфігурації. Він заснований на обгортці навколо hawtio-git (який в свою чергу під капотом використовує JGit) і доступний на github git-configuration, maven central.

Бачачи конфігураційний хаос навколо спробую нагадаю про світле і прекрасне.Вперше ідея збереження конфігурації в git надихнула після знайомства з fuse fabric/fabric8.

Зберігати конфігурацію в git репозитарії вміє і чудовий проект spring-cloud-config. Але якщо нам не потрібна залежність spring і його PropertySource абстракцію, то рішення з цієї публікації краще підійде для програми на jvm.


Конфігурація на github

Почнемо з читання конфігурації, яку ми розмістили в гитхаб репозитарії…

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));
}
}


Залежності, необхідні для роботи приклад:
<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>


Для отримання конфігурації потрібно вказати шлях до нашого архіву даних:
new GitConfigurationHelper("https://github.com/igor-suhorukov/aspectj-scripting.git")

Можливі варіанти
  • Використовувати останню версію файлу з зазначеного бранчу:
    gitConfigurationHelper.getFileContent("master","pom.xml")
    
  • отримати конкретну версію по тегу (у прикладі це тег «aspectj-scripting-1.2») або по ревізії:
    gitConfigurationHelper.getFileContent("master","aspectj-scripting-1.2", "pom.xml")
    
І в завершенні роботи закрити з'єднання з репозитарием:
gitConfigurationHelper.destroy()


В якості приємного доповнення до можливості зберігання конфігурації в git — можна зчитувати конфігурацію і з maven репозитарію. Для цього потрібна бібліотека mvn-classloader:1.4, яка вже входить в склад groovy-grape-aether:2.4.5.2.

URL artifact = MavenClassLoader.usingCentralRepo().resolveArtifact(«com.github.igor-suhorukov:aspectj-scripting:pom:1.3»)
  • usingCentralRepo() — з центрального сховища.
  • using(repositoryPath) — для вашого корпоративного сховища.


Далі працювати з артефактом досить просто. Виклик методу artifact.getFile() дозволяє отримати посилання на артефакт у локальній файловій системі, а artifact.openStream() відкриває InputStream до цього файлу.

В якому форматі зберігати конфігурацію і ніж розбирати ці файли далі — залежить від завдання і переваг і вирішувати вам. Конфігурація може представляти із себе як простий java.util.Properties, так і Json(Gson/jackson), JAXB/XStream, або конфігурацію у вигляді скриптів на groovy, scala, javascript…

Groovy
Те ж саме з минулого заголовка про java набагато лаконічніше записується в groovy. Запустити приклад можна командою:
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


Конфігурація у власному git репозитарії

Як in-house репозитарію вибрав Gitblit — для знаючих java його простіше встановити і підтримувати, а механізм push hooks на Groovy дозволяє творити дива. В якості альтернативи можна вибрати Gogs — Go Git Service або будь-який інший сервер Git репозитаріїв.

Запуск і конфігурацію Gitblit сервера виконаємо з допомогою groovy скрипта автоустановки.

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.github.io/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[])


Скрипт завантажує gitblit.war з репозитарію проекту, розпаковує його в домашню директорію користувача і замінює в конфігурації gitblit шлях до сховища репозитаріїв. Після цього запускає jetty сервер і gitblit всередині нього.



Наведу послідовність команд, які використав для створення конфігурації в новому репозитарії 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


Код читання конфігурації нічим не відрізняється від попередніх прикладів. Залишається тільки створити в коді об'єкт:
new GitConfigurationHelper("http://admin@localhost:8080/r/configuration.git")

І використовувати той же API, що і в github прикладі.



Підсумки

У публікації ми розглянули як зчитувати конфігурацію в java/groovy з git і maven репозитаріїв. З допомогою groovy скрипта змогли встановити та сконфігурувати gitblit репозитарій в автоматичному режимі.

Код зі статті застосовна в jvm проектах і було б цікаво почути від вас як ця ж завдання вирішується в інших мовах програмування і на інших платформах.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.