added first version of configuraiton api and simple function test.
authorErik Brakkee <erik@brakkee.org>
Sat, 30 Jul 2011 20:22:36 +0000 (22:22 +0200)
committerErik Brakkee <erik@brakkee.org>
Sat, 30 Jul 2011 20:22:36 +0000 (22:22 +0200)
14 files changed:
impl/src/main/java/org/wamblee/xmlrouter/impl/CompositeConfig.java [moved from impl/src/main/java/org/wamblee/xmlrouter/impl/RouterConfigServiceImpl.java with 51% similarity]
impl/src/main/java/org/wamblee/xmlrouter/impl/CompositeRouterConfig.java [new file with mode: 0644]
impl/src/main/java/org/wamblee/xmlrouter/impl/ConfigImpl.java
impl/src/main/java/org/wamblee/xmlrouter/impl/ExtendedConfig.java
impl/src/main/java/org/wamblee/xmlrouter/impl/ExtendedRouterConfig.java
impl/src/main/java/org/wamblee/xmlrouter/impl/SingleRouterConfig.java
impl/src/main/java/org/wamblee/xmlrouter/impl/XMLRouter.java
impl/src/main/java/org/wamblee/xmlrouter/impl/XMLRouterConfigService.java [new file with mode: 0644]
impl/src/main/java/org/wamblee/xmlrouter/impl/XMLRouterConfiguration.java
impl/src/main/java/org/wamblee/xmlrouter/impl/XMLRouterConfigurationImpl.java
impl/src/test/java/org/wamblee/xmlrouter/impl/ConfigImplTest.java
impl/src/test/java/org/wamblee/xmlrouter/impl/SingleRouterConfigTest.java
impl/src/test/java/org/wamblee/xmlrouter/impl/XMLRouterFunctionTest.java [new file with mode: 0644]
impl/src/test/java/org/wamblee/xmlrouter/impl/XMLRouterTest.java

similarity index 51%
rename from impl/src/main/java/org/wamblee/xmlrouter/impl/RouterConfigServiceImpl.java
rename to impl/src/main/java/org/wamblee/xmlrouter/impl/CompositeConfig.java
index 76fd26faf727de73773fc06f3f3afdf8f9516e7d..b378052c207b05015b78d427870070c733e7dcbf 100644 (file)
  */
 package org.wamblee.xmlrouter.impl;
 
+import java.util.LinkedHashMap;
+import java.util.Map;
+
 import org.wamblee.xmlrouter.common.Id;
-import org.wamblee.xmlrouter.config.RouterConfig;
-import org.wamblee.xmlrouter.config.RouterConfigService;
+import org.wamblee.xmlrouter.config.Config;
 
-/**
- * Router configuration service providing an atomic configuration API for the
- * XML router.
- * 
- * @author Erik Brakkee
- */
-public class RouterConfigServiceImpl implements RouterConfigService {
+public class CompositeConfig<T> implements ExtendedConfig<T> {
 
-    @Override
-    public RouterConfig emptyConfig() {
-        // TODO Auto-generated method stub
-        return null;
+    private Map<Id<T>, T> configs;
+
+    public CompositeConfig() {
+        configs = new LinkedHashMap<Id<T>, T>();
+    }
+
+    public void add(Config<T> aConfig) {
+        for (Id<T> id : aConfig.map().keySet()) {
+            configs.put(id, aConfig.map().get(id));
+        }
     }
 
     @Override
-    public Id<RouterConfig> apply(RouterConfig aConfig,
-        Id<RouterConfig> aOldConfig) {
-        // TODO Auto-generated method stub
-        return null;
+    public Map<Id<T>, T> map() {
+        return configs;
     }
 
     @Override
-    public void clear(Id<RouterConfig> aConfig) {
-        // TODO Auto-generated method stub
+    public boolean remove(Id<T> aId) {
+        notSupported();
+        return false;
+    }
 
+    private void notSupported() {
+        throw new RuntimeException("readonly instance");
     }
 
+    @Override
+    public Id<T> add(T aT) {
+        notSupported();
+        return null;
+    }
 }
diff --git a/impl/src/main/java/org/wamblee/xmlrouter/impl/CompositeRouterConfig.java b/impl/src/main/java/org/wamblee/xmlrouter/impl/CompositeRouterConfig.java
new file mode 100644 (file)
index 0000000..5ba6571
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2005-2011 the original author or authors.
+ * 
+ * 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.wamblee.xmlrouter.impl;
+
+import java.util.Collection;
+
+import org.wamblee.xmlrouter.config.Config;
+import org.wamblee.xmlrouter.config.DocumentType;
+import org.wamblee.xmlrouter.config.Filter;
+import org.wamblee.xmlrouter.config.RouterConfig;
+import org.wamblee.xmlrouter.config.Transformation;
+
+public class CompositeRouterConfig implements ExtendedRouterConfig {
+
+    private CompositeConfig<DocumentType> documentTypes;
+    private CompositeConfig<Transformation> transformations;
+    private CompositeConfig<Filter> filters;
+
+    public CompositeRouterConfig(Collection<RouterConfig> aConfigs) {
+        documentTypes = new CompositeConfig<DocumentType>();
+        transformations = new CompositeConfig<Transformation>();
+        filters = new CompositeConfig<Filter>();
+        for (RouterConfig config : aConfigs) {
+            documentTypes.add(config.documentTypeConfig());
+            transformations.add(config.transformationConfig());
+            filters.add(config.filterConfig());
+        }
+    }
+
+    @Override
+    public Config<DocumentType> documentTypeConfig() {
+        return documentTypes;
+    }
+
+    @Override
+    public Config<Transformation> transformationConfig() {
+        return transformations;
+    }
+
+    @Override
+    public Config<Filter> filterConfig() {
+        return filters;
+    }
+}
index 54c0c6d2357604103284b1d818c754a2e1fdc551..e29725e8655d2be5ad4fab667d4152dca68e37e8 100644 (file)
@@ -101,14 +101,4 @@ public abstract class ConfigImpl<T> implements ExtendedConfig<T> {
             throw new NullPointerException("Id is null");
         }
     }
-
-    @Override
-    public boolean isDirty() {
-        return dirty;
-    }
-
-    @Override
-    public void resetDirty() {
-        dirty = false;
-    }
 }
index 070a52a9dd201f2022982b9b128aa9ae0421bb48..232e54d66a8fa7a3dffbb8d2e766893076a4108a 100644 (file)
@@ -19,7 +19,4 @@ import org.wamblee.xmlrouter.config.Config;
 
 public interface ExtendedConfig<T> extends Config<T> {
 
-    boolean isDirty();
-
-    void resetDirty();
 }
index 94b7128e04a0a41273089c6559684c3e2d7a7ade..f8b0f75d17e4b16c10cc91fcfdb16bb770dc33b2 100644 (file)
@@ -29,16 +29,4 @@ public interface ExtendedRouterConfig extends RouterConfig {
      * Locks the configuration object from further changes.
      */
     // void lock();
-
-    /**
-     * Checks whether or not the configuration has changed.
-     * 
-     * @return True iff dirty.
-     */
-    boolean isDirty();
-
-    /**
-     * Resets the router configuration dirty state.
-     */
-    void resetDirty();
 }
index 36016ca302ee8df806e1264e690555a72d70ee9e..c58ef8909f6e6db8ebc19bcdda4fea35b3ece394 100644 (file)
@@ -78,18 +78,4 @@ public class SingleRouterConfig implements ExtendedRouterConfig {
     public Config<Filter> filterConfig() {
         return filters;
     }
-
-    @Override
-    public boolean isDirty() {
-        return documentTypes.isDirty() || transformations.isDirty() ||
-            filters.isDirty();
-    }
-
-    @Override
-    public void resetDirty() {
-        documentTypes.resetDirty();
-        filters.resetDirty();
-        transformations.resetDirty();
-    }
-
 }
index 637440fe4dc0b6e0f1ae4d87fda3676817978302..a203f93fe380e2d8d2ecc493ba4f2a4b89ed2dde 100644 (file)
@@ -83,13 +83,6 @@ public class XMLRouter implements Gateway, DestinationRegistry {
     private void publishImpl(String aSource, DOMSource aEvent) {
         long time = clock.currentTimeMillis();
 
-        // TODO dirty flag will become unnecessary in the future.
-        if (config.routerConfig().isDirty()) {
-            config.transformations().replaceTransformations(
-                config.routerConfig().transformationConfig().map());
-            config.routerConfig().resetDirty();
-        }
-
         Id<DOMSource> id = new Id<DOMSource>(nextEventId.getAndIncrement());
         List<String> types = determineDocumentTypes(aEvent);
         EventInfo info = new EventInfo(time, aSource, id, types, aEvent);
@@ -132,7 +125,7 @@ public class XMLRouter implements Gateway, DestinationRegistry {
 
         boolean delivered = false;
         Set<String> possibleTargetTypes = new HashSet<String>();
-        possibleTargetTypes.addAll(config.transformations()
+        possibleTargetTypes.addAll(config.getTransformations()
             .getPossibleTargetTypes(aInputType));
 
         // ask each destination what target types, if any they want to have.
@@ -145,8 +138,8 @@ public class XMLRouter implements Gateway, DestinationRegistry {
             if (!requested.isEmpty()) {
                 // Deliver to the destination.
                 for (String targetType : requested) {
-                    TransformationPath path = config.transformations().getPath(
-                        aInputType, targetType);
+                    TransformationPath path = config.getTransformations()
+                        .getPath(aInputType, targetType);
                     List<Transformation> ts = path.getTransformations();
                     int i = 0;
                     boolean allowed = true;
@@ -196,7 +189,7 @@ public class XMLRouter implements Gateway, DestinationRegistry {
 
     private boolean isAllowedByFilters(String aType, DOMSource aEvent) {
         boolean allowed = true;
-        for (Filter filter : config.routerConfig().filterConfig().map()
+        for (Filter filter : config.getRouterConfig().filterConfig().map()
             .values()) {
             if (!filter.isAllowed(aType, aEvent)) {
                 allowed = false;
@@ -207,7 +200,7 @@ public class XMLRouter implements Gateway, DestinationRegistry {
 
     private List<String> determineDocumentTypes(DOMSource aEvent) {
         List<String> res = new ArrayList<String>();
-        for (DocumentType type : config.routerConfig().documentTypeConfig()
+        for (DocumentType type : config.getRouterConfig().documentTypeConfig()
             .map().values()) {
             if (type.isInstance(aEvent)) {
                 res.add(type.getName());
diff --git a/impl/src/main/java/org/wamblee/xmlrouter/impl/XMLRouterConfigService.java b/impl/src/main/java/org/wamblee/xmlrouter/impl/XMLRouterConfigService.java
new file mode 100644 (file)
index 0000000..ca5e417
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2005-2011 the original author or authors.
+ * 
+ * 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.wamblee.xmlrouter.impl;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.wamblee.xmlrouter.common.Id;
+import org.wamblee.xmlrouter.config.Config;
+import org.wamblee.xmlrouter.config.RouterConfig;
+import org.wamblee.xmlrouter.config.RouterConfigService;
+
+/**
+ * Router configuration service providing an atomic configuration API for the
+ * XML router.
+ * 
+ * @author Erik Brakkee
+ */
+public class XMLRouterConfigService implements RouterConfigService {
+
+    private AtomicLong sequence;
+    private XMLRouterConfiguration config;
+    private Config<RouterConfig> routerConfigs;
+
+    public XMLRouterConfigService(XMLRouterConfiguration aConfig) {
+        sequence = new AtomicLong(1L);
+        config = aConfig;
+        routerConfigs = new ConfigImpl<RouterConfig>(sequence) {
+            public RouterConfig wrap(Id<RouterConfig> aId, RouterConfig aT) {
+                return aT;
+            }
+        };
+    }
+
+    @Override
+    public RouterConfig emptyConfig() {
+        return new SingleRouterConfig(sequence);
+    }
+
+    @Override
+    public Id<RouterConfig> apply(RouterConfig aConfig,
+        Id<RouterConfig> aOldConfig) {
+        config.startConfigurationChange();
+        try {
+            return applyImpl(aConfig, aOldConfig);
+        } finally {
+            config.endConfigurationChange();
+        }
+    }
+
+    private Id<RouterConfig> applyImpl(RouterConfig aConfig,
+        Id<RouterConfig> aOldConfig) {
+        if (aOldConfig != null) {
+            routerConfigs.remove(aOldConfig);
+        }
+        Id<RouterConfig> id = routerConfigs.add(aConfig);
+        update();
+        return id;
+    }
+
+    @Override
+    public void clear(Id<RouterConfig> aConfig) {
+        config.startConfigurationChange();
+        try {
+            clearImpl(aConfig);
+        } finally {
+            config.endConfigurationChange();
+        }
+    }
+
+    private void clearImpl(Id<RouterConfig> aConfig) {
+        routerConfigs.remove(aConfig);
+        update();
+    }
+
+    private void update() {
+        ExtendedRouterConfig newconfig = new CompositeRouterConfig(
+            routerConfigs.map().values());
+        config.setRouterConfig(newconfig);
+    }
+
+}
index 51c8cc7b257074f259798150cf51bc674630fe05..25ae3313151cb70d2a7f6684ab231ce704f3e93a 100644 (file)
@@ -53,10 +53,18 @@ public interface XMLRouterConfiguration {
     /**
      * @return Configuration data.
      */
-    ExtendedRouterConfig routerConfig();
+    ExtendedRouterConfig getRouterConfig();
+
+    /**
+     * Sets the configuration and updates derived data.
+     * 
+     * @param aConfig
+     *            Configuration to set.
+     */
+    void setRouterConfig(ExtendedRouterConfig aConfig);
 
     /**
      * @return Transformation paths (derived data).
      */
-    TransformationPaths transformations();
+    TransformationPaths getTransformations();
 }
index b0b02713017ed583b421b3f96e54c5015fc2bf4a..99db0fd2b65a71b77e0e3eaade316cdbd4bcbf23 100644 (file)
  */
 package org.wamblee.xmlrouter.impl;
 
+import java.util.ArrayList;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
+import org.wamblee.xmlrouter.config.RouterConfig;
+
 /**
  * Implements the XML Router configuration interface including the required
  * locking.
@@ -33,10 +36,13 @@ public class XMLRouterConfigurationImpl implements XMLRouterConfiguration {
     private ExtendedRouterConfig config;
     private TransformationPaths transformations;
 
-    public XMLRouterConfigurationImpl(ExtendedRouterConfig aConfig,
-        TransformationPaths aTransformations) {
+    public XMLRouterConfigurationImpl(ExtendedRouterConfig aConfig) {
         config = aConfig;
-        transformations = aTransformations;
+        transformations = new TransformationPaths();
+    }
+
+    public XMLRouterConfigurationImpl() {
+        this(new CompositeRouterConfig(new ArrayList<RouterConfig>()));
     }
 
     @Override
@@ -60,12 +66,19 @@ public class XMLRouterConfigurationImpl implements XMLRouterConfiguration {
     }
 
     @Override
-    public ExtendedRouterConfig routerConfig() {
+    public ExtendedRouterConfig getRouterConfig() {
         return config;
     }
 
     @Override
-    public TransformationPaths transformations() {
+    public void setRouterConfig(ExtendedRouterConfig aConfig) {
+        config = aConfig;
+        transformations.replaceTransformations(config.transformationConfig()
+            .map());
+    }
+
+    @Override
+    public TransformationPaths getTransformations() {
         return transformations;
     }
 }
index 98296d4d8cc110bf2174340fbe13478576b0ef06..1e8cfc3b35c1ef5ce9a0631f9ce8dee0d0525570 100644 (file)
@@ -61,7 +61,6 @@ public class ConfigImplTest {
     @Test
     public void testAdd() {
         MyType type1 = mock(MyType.class);
-        assertFalse(config.isDirty());
 
         Id<MyType> id1 = config.add(type1);
 
@@ -69,10 +68,6 @@ public class ConfigImplTest {
         assertEquals(1, config.map().size());
         assertTrue(config.map().get(id1) instanceof MyTypeWrapper);
         assertSame(type1, ((MyTypeWrapper) config.map().get(id1)).getType());
-        assertTrue(config.isDirty());
-
-        config.resetDirty();
-        assertFalse(config.isDirty());
 
         // add another one.
         MyType type2 = mock(MyType.class);
@@ -80,8 +75,6 @@ public class ConfigImplTest {
         assertNotNull(id2);
         assertEquals(2, config.map().size());
         assertFalse(id1.equals(id2));
-        assertTrue(config.isDirty());
-
     }
 
     @Test
@@ -92,12 +85,8 @@ public class ConfigImplTest {
         assertNotNull(id1);
         assertEquals(1, config.map().size());
 
-        config.resetDirty();
-        assertFalse(config.isDirty());
-
         config.remove(id1);
         assertTrue(config.map().isEmpty());
-        assertTrue(config.isDirty());
     }
 
     @Test(expected = UnsupportedOperationException.class)
index c6f9920865f4165a3f7dcf7d17e62abebe38d9c2..af347372a4fdfdc79fec1bbf38dd543dc53cbe89 100644 (file)
@@ -43,15 +43,10 @@ public class SingleRouterConfigTest {
         DocumentType type1 = mock(DocumentType.class);
         DocumentType type2 = mock(DocumentType.class);
 
-        assertFalse(config.isDirty());
         Id<DocumentType> id1 = config.documentTypeConfig().add(type1);
-        assertTrue(config.isDirty());
 
-        config.resetDirty();
-        assertFalse(config.isDirty());
         Id<DocumentType> id2 = config.documentTypeConfig().add(type2);
         assertFalse(id1.equals(id2));
-        assertTrue(config.isDirty());
 
         assertEquals(2, config.documentTypeConfig().map().size());
         assertTrue(config.documentTypeConfig().map().get(id1) instanceof RobustDocumentType);
@@ -63,17 +58,12 @@ public class SingleRouterConfigTest {
         Transformation transformation1 = mock(Transformation.class);
         Transformation transformation2 = mock(Transformation.class);
 
-        assertFalse(config.isDirty());
         Id<Transformation> id1 = config.transformationConfig().add(
             transformation1);
-        assertTrue(config.isDirty());
 
-        config.resetDirty();
-        assertFalse(config.isDirty());
         Id<Transformation> id2 = config.transformationConfig().add(
             transformation2);
         assertFalse(id1.equals(id2));
-        assertTrue(config.isDirty());
 
         assertEquals(2, config.transformationConfig().map().size());
         assertTrue(config.transformationConfig().map().get(id1) instanceof RobustTransformation);
@@ -84,15 +74,10 @@ public class SingleRouterConfigTest {
         Filter filter1 = mock(Filter.class);
         Filter filter2 = mock(Filter.class);
 
-        assertFalse(config.isDirty());
         Id<Filter> id1 = config.filterConfig().add(filter1);
-        assertTrue(config.isDirty());
 
-        config.resetDirty();
-        assertFalse(config.isDirty());
         Id<Filter> id2 = config.filterConfig().add(filter2);
         assertFalse(id1.equals(id2));
-        assertTrue(config.isDirty());
 
         assertEquals(2, config.filterConfig().map().size());
         assertTrue(config.filterConfig().map().get(id1) instanceof RobustFilter);
diff --git a/impl/src/test/java/org/wamblee/xmlrouter/impl/XMLRouterFunctionTest.java b/impl/src/test/java/org/wamblee/xmlrouter/impl/XMLRouterFunctionTest.java
new file mode 100644 (file)
index 0000000..46e36c0
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2005-2011 the original author or authors.
+ * 
+ * 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.wamblee.xmlrouter.impl;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.logging.Level;
+
+import javax.xml.transform.dom.DOMSource;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.wamblee.general.SystemClock;
+import org.wamblee.xmlrouter.config.DocumentType;
+import org.wamblee.xmlrouter.config.RouterConfig;
+import org.wamblee.xmlrouter.config.Transformation;
+import org.wamblee.xmlrouter.listener.EventInfo;
+import org.wamblee.xmlrouter.listener.EventListener;
+import org.wamblee.xmlrouter.listener.LoggingEventListener;
+import org.wamblee.xmlrouter.subscribe.Destination;
+
+public class XMLRouterFunctionTest {
+
+    private XMLRouterConfiguration config;
+    private XMLRouter routerService;
+    private XMLRouterConfigService configService;
+
+    private EventListener listener;
+
+    private DOMSource source1;
+    private DOMSource source2;
+
+    @Before
+    public void setUp() {
+        config = new XMLRouterConfigurationImpl();
+        EventListener logListener = new LoggingEventListener(Level.INFO);
+        listener = spy(logListener);
+        routerService = new XMLRouter(new SystemClock(), config, listener);
+        configService = new XMLRouterConfigService(config);
+
+        source1 = mock(DOMSource.class);
+        source2 = mock(DOMSource.class);
+    }
+
+    private RouterConfig registerDocumentType(String aType) {
+        DocumentType type = mock(DocumentType.class);
+        when(type.isInstance(any(DOMSource.class))).thenReturn(true);
+        when(type.getName()).thenReturn(aType);
+        RouterConfig routerConfig = configService.emptyConfig();
+        routerConfig.documentTypeConfig().add(type);
+        return routerConfig;
+    }
+
+    @Test
+    public void testOneTransformationOneDestination() {
+        RouterConfig routerConfig = registerDocumentType("any");
+        Transformation transformation = mock(Transformation.class);
+        when(transformation.getName()).thenReturn("trans");
+        when(transformation.getFromType()).thenReturn("any");
+        when(transformation.getToType()).thenReturn("bla");
+        when(transformation.transform(same(source1))).thenReturn(source2);
+        routerConfig.transformationConfig().add(transformation);
+
+        configService.apply(routerConfig, null);
+
+        Destination destination = mock(Destination.class);
+        when(
+            destination.chooseFromTargetTypes((Collection<String>) anyObject()))
+            .thenReturn(Arrays.asList("bla"));
+
+        routerService.registerDestination(destination);
+
+        when(destination.receive(any(DOMSource.class))).thenReturn(true);
+        routerService.publish("bla", source1);
+        verify(listener).delivered(any(EventInfo.class),
+            anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
+
+        verify(transformation).transform(source1);
+        verify(destination).receive(same(source2));
+
+        // now the same when the destination rejects the event.
+        when(destination.receive(any(DOMSource.class))).thenReturn(false);
+        routerService.publish("bla", source1);
+        verify(listener).notDelivered(any(EventInfo.class));
+    }
+}
index 7da3de5f932119f0499bb00761f00fb199aa24fa..baa63a16c7a6de2cc7121ce85407a8131fbf4a13 100644 (file)
@@ -80,8 +80,7 @@ public class XMLRouterTest {
     @Before
     public void setUp() {
         routerConfig = new SingleRouterConfig(new AtomicLong(1L));
-        config = new XMLRouterConfigurationImpl(routerConfig,
-            new TransformationPaths());
+        config = new XMLRouterConfigurationImpl(routerConfig);
         EventListener logListener = new LoggingEventListener(Level.INFO);
         listener = spy(logListener);
         router = new XMLRouter(new SystemClock(), config, listener);
@@ -276,6 +275,8 @@ public class XMLRouterTest {
         when(transformation.getToType()).thenReturn("bla");
         when(transformation.transform(same(source1))).thenReturn(source2);
         routerConfig.transformationConfig().add(transformation);
+        config.getTransformations().replaceTransformations(
+            routerConfig.transformationConfig().map());
 
         Destination destination = mock(Destination.class);
         when(
@@ -338,6 +339,8 @@ public class XMLRouterTest {
             source1, null);
 
         routerConfig.transformationConfig().add(transformation);
+        config.getTransformations().replaceTransformations(
+            routerConfig.transformationConfig().map());
 
         Destination destination = mock(Destination.class);
         when(
@@ -356,6 +359,8 @@ public class XMLRouterTest {
             source1, source2);
 
         routerConfig.transformationConfig().add(transformation2);
+        config.getTransformations().replaceTransformations(
+            routerConfig.transformationConfig().map());
         when(
             destination.chooseFromTargetTypes((Collection<String>) anyObject()))
             .thenReturn(Arrays.asList("bla", "bla2"));
@@ -400,6 +405,8 @@ public class XMLRouterTest {
         Transformation transformation = createTransformation("any", "other",
             source1, source2);
         routerConfig.transformationConfig().add(transformation);
+        config.getTransformations().replaceTransformations(
+            routerConfig.transformationConfig().map());
 
         router.publish("source", source1);
         verify(listener, times(2)).delivered(any(EventInfo.class),
@@ -421,6 +428,8 @@ public class XMLRouterTest {
         Transformation t2 = createTransformation("intermediate", "other",
             source2, source3);
         routerConfig.transformationConfig().add(t2);
+        config.getTransformations().replaceTransformations(
+            routerConfig.transformationConfig().map());
 
         router.publish("source", source1);
         verify(listener).delivered(any(EventInfo.class),