Skip to content

Instantly share code, notes, and snippets.

@dtanner
Created April 30, 2015 05:39
Show Gist options
  • Save dtanner/576eff1e189082ba8577 to your computer and use it in GitHub Desktop.
Save dtanner/576eff1e189082ba8577 to your computer and use it in GitHub Desktop.
Example of a basic utility class to interact with etcd
package com.foo.config
import com.foog.util.TomcatDatasourceUtil
import grails.plugins.rest.client.RestBuilder
import groovy.json.JsonSlurper
/**
* Application service to get and set values from a centralized remote configuration service.
*/
class RemoteConfigService {
def grailsApplication
public static final String CATALOG_DB_URL_KEY = "dataSource/url"
protected static final int INITIAL_RETRY_TIMEOUT_SECS = 5
/**
* Runs a process to watch for configuration changes to the plancatalog datasource URL.
* If the URL value changes, call the datasource utility to update the connections to point at the new database.
*/
void watchForChanges() {
if (!grailsApplication.config.remoteConfig.enabled) {
log.info "remoteConfigBaseUrl not configured - will not watch for config changes"
return
}
log.debug("watching for changes")
Thread.startDaemon {
int secondsToWait = INITIAL_RETRY_TIMEOUT_SECS
while (true) {
try {
String url = get("${CATALOG_DB_URL_KEY}?wait=true")
if (url) {
grailsApplication.config.dataSource_plancatalog.url = url
TomcatDatasourceUtil.ensureCurrentDatasources(grailsApplication, ['dataSource_plancatalog'])
}
secondsToWait = INITIAL_RETRY_TIMEOUT_SECS
} catch (Exception e) {
log.warn("Exception occurred while watching for config changes. Will wait ${secondsToWait} seconds and continue watching", e)
Thread.sleep(1000 * secondsToWait)
// double the length of the time to wait before retrying, up to a maximum of 30 minutes
secondsToWait = [60 * 30, 2 * secondsToWait].min()
}
}
}
}
/**
* Get the configured value for the given key
* @param key
* @return the current value
*/
String get(String key) {
def jsonSlurper = new JsonSlurper()
def json = jsonSlurper.parseText(new URL("${grailsApplication.config.remoteConfig.baseUrl}/${key}").text)
return json?.node?.value
}
/**
* Set the given key to the given value in the centralized configuration service
* @param key
* @param valueArg
*/
void set(String key, String valueArg) {
RestBuilder rest = new RestBuilder()
def resp = rest.put("${grailsApplication.config.remoteConfig.baseUrl}/${key}") {
value = valueArg
}
if (resp.status != 200) {
throw new Exception("Error setting configuration value for key=${key}. Response=${resp.body}")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment