/* * Copyright 2013 NGDATA nv * Copyright 2008 Outerthought bvba and Schaubroeck nv * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.lilyproject.runtime.test; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Assert; import org.lilyproject.runtime.configuration.ConfManager; import org.lilyproject.runtime.configuration.ConfManagerImpl; import org.lilyproject.runtime.model.LilyRuntimeModel; import org.lilyproject.runtime.model.ModuleDefinition; import org.lilyproject.runtime.model.ModuleSourceType; import org.lilyproject.runtime.rapi.ConfListener; import org.lilyproject.runtime.rapi.ConfRegistry; import org.lilyproject.runtime.testfw.AbstractRuntimeTest; public class ConfListeningTest extends AbstractRuntimeTest { private File conflistenmodConfDir; @Override protected LilyRuntimeModel getRuntimeModel() throws Exception { File moduleDir = createModule("org.lilyproject.runtime.test.testmodules.conflistenmod"); LilyRuntimeModel model = new LilyRuntimeModel(); ModuleDefinition module = new ModuleDefinition("conflistenmod", moduleDir, ModuleSourceType.EXPANDED_JAR); model.addModule(module); return model; } @Override protected ConfManager getConfManager() throws Exception { List<File> confDirs = new ArrayList<File>(); // Base dir below which the conf will be defined File confDir = createTempDir(); File test1ConfDir = new File(confDir, "conftest1"); test1ConfDir.mkdirs(); // Create a config for the configuration manager File lilyRuntimeConfDir = new File(test1ConfDir, "runtime"); writeConf(lilyRuntimeConfDir, "configuration.xml", "<conf><reloading enabled='true' delay='1000'/></conf>"); // Create a conf for our test module conflistenmodConfDir = new File(test1ConfDir, "conflistenmod"); writeConf(conflistenmodConfDir, "foobar.xml", "<conf/>"); // Create the ConfManager confDirs.add(test1ConfDir); return new ConfManagerImpl(confDirs); } public void testConf() throws Exception { Map beans = runtime.getModuleById("conflistenmod").getApplicationContext().getBeansOfType(ConfRegistry.class); ConfRegistry confRegistry = (ConfRegistry)beans.get("conf"); final Set<String> changedPaths = new HashSet<String>(); final Set<String> changedConfs = new HashSet<String>(); confRegistry.addListener(new ConfListener() { public void confAltered(String path, ChangeType changeType) { switch (changeType) { case CONF_CHANGE: changedConfs.add(path); break; case PATH_CHANGE: changedPaths.add(path); break; } } }, null, ConfListener.ChangeType.CONF_CHANGE, ConfListener.ChangeType.PATH_CHANGE); // Sleep a second, as it seems the resolution for (my) file system changes is 1 second Thread.sleep(1500); writeConf(conflistenmodConfDir, "foobar.xml", "<conf x='y'/>"); writeConf(conflistenmodConfDir, "x/y/foobar.xml", "<conf x='y'/>"); // Sleep so that we can receive notifications (see configured delay) Thread.sleep(1000); Assert.assertEquals(2, changedConfs.size()); Assert.assertEquals(1, changedPaths.size()); Assert.assertTrue(changedConfs.contains("foobar")); Assert.assertTrue(changedConfs.contains("x/y/foobar")); Assert.assertTrue(changedPaths.contains("x/y")); Collection<String> childPaths = confRegistry.getConfigurations("x/y"); Assert.assertEquals(1, childPaths.size()); Assert.assertEquals("foobar", childPaths.iterator().next()); // // Test that removal of a conf causes both a change event for the conf and its containing directory // changedPaths.clear(); changedConfs.clear(); boolean deleteSuccess = new File(conflistenmodConfDir, "x/y/foobar.xml").delete(); Assert.assertTrue(deleteSuccess); // Sleep so that we can receive notifications (see configured delay) Thread.sleep(1000); for (String p : changedPaths) { System.out.println("changed path: " + p); } Assert.assertEquals(1, changedConfs.size()); Assert.assertEquals(1, changedPaths.size()); Assert.assertTrue(changedConfs.contains("x/y/foobar")); Assert.assertTrue(changedPaths.contains("x/y")); } private void writeConf(File dir, String path, String content) throws FileNotFoundException { File foobar = new File(dir, path); foobar.getParentFile().mkdirs(); PrintWriter writer = new PrintWriter(new FileOutputStream(foobar)); writer.print(content); writer.close(); } }