Note that there are some explanatory texts on larger screens.

plurals
  1. POZooKeeper for Java/Spring Config?
    primarykey
    data
    text
    <p>Are there any well documented use cases of Apache ZooKeeper being used to distribute configuration of Java applications, and in particular Spring services?</p> <p>Like many users of cloud services I have a requirement to change the configuration of a variable amount of Java services, preferably at run-time without needing to restart the services.</p> <p><strong>UPDATE</strong></p> <p>Eventually I ended up writing something that would load a ZooKeeper node as a properties file, and create a <code>ResourcePropertySource</code> and insert it into a Spring context. Note that this will not reflect changes in the ZooKeeper node after the context has started.</p> <pre><code>public class ZooKeeperPropertiesApplicationContextInitializer implements ApplicationContextInitializer&lt;ConfigurableApplicationContext&gt; { private static final Logger logger = LoggerFactory.getLogger(ZooKeeperPropertiesApplicationContextInitializer.class); private final CuratorFramework curator; private String projectName; private String projectVersion; public ZooKeeperPropertiesApplicationContextInitializer() throws IOException { logger.trace("Attempting to construct CuratorFramework instance"); RetryPolicy retryPolicy = new ExponentialBackoffRetry(10, 100); curator = CuratorFrameworkFactory.newClient("zookeeper", retryPolicy); curator.start(); } /** * Add a primary property source to the application context, populated from * a pre-existing ZooKeeper node. */ @Override public void initialize(ConfigurableApplicationContext applicationContext) { logger.trace("Attempting to add ZooKeeper-derived properties to ApplicationContext PropertySources"); try { populateProjectProperties(); Properties properties = populatePropertiesFromZooKeeper(); PropertiesPropertySource propertySource = new PropertiesPropertySource("zookeeper", properties); applicationContext.getEnvironment().getPropertySources().addFirst(propertySource); logger.debug("Added ZooKeeper-derived properties to ApplicationContext PropertySources"); curator.close(); } catch (IOException e) { logger.error("IO error attempting to load properties from ZooKeeper", e); throw new IllegalStateException("Could not load ZooKeeper configuration"); } catch (Exception e) { logger.error("IO error attempting to load properties from ZooKeeper", e); throw new IllegalStateException("Could not load ZooKeeper configuration"); } finally { if (curator != null &amp;&amp; curator.isStarted()) { curator.close(); } } } /** * Populate the Maven artifact name and version from a property file that * should be on the classpath, with values entered via Maven filtering. * * There is a way of doing these with manifests, but it's a right faff when * creating shaded uber-jars. * * @throws IOException */ private void populateProjectProperties() throws IOException { logger.trace("Attempting to get project name and version from properties file"); try { ResourcePropertySource projectProps = new ResourcePropertySource("project.properties"); this.projectName = (String) projectProps.getProperty("project.name"); this.projectVersion = (String) projectProps.getProperty("project.version"); } catch (IOException e) { logger.error("IO error trying to find project name and version, in order to get properties from ZooKeeper"); } } /** * Do the actual loading of properties. * * @return * @throws Exception * @throws IOException */ private Properties populatePropertiesFromZooKeeper() throws Exception, IOException { logger.debug("Attempting to get properties from ZooKeeper"); try { byte[] bytes = curator.getData().forPath("/distributed-config/" + projectName + "/" + projectVersion); InputStream in = new ByteArrayInputStream(bytes); Properties properties = new Properties(); properties.load(in); return properties; } catch (NoNodeException e) { logger.error("Could not load application configuration from ZooKeeper as no node existed for project [{}]:[{}]", projectName, projectVersion); throw e; } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload