From 2686e3d7bf19bbe16671f7e4e3522a5d380ffdd8 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Mon, 23 Dec 2013 20:28:49 +0100 Subject: [PATCH] [Major] Strolch agent is now fully realm capable ResourceMap and OrderMap are kept in a StrolchRealm object for each realm which is configured. This is transparent for the user. When no realms are defined then the 'defaultRealm' is configured where all methods without a realm parameter use this realm. Once a realm is configured, the defaultRealm must be configured if it is still to be used at runtime. Tests make sure realms work, for both transient, and empty situations. Cached agent mode is next to be implemented --- .../agent/AbstractElementMapHandler.java | 71 +++++++++++++++++++ .../runtime/agent/ElementMapHandler.java | 4 ++ .../runtime/agent/EmptyElementMapHandler.java | 9 --- .../agent/InMemoryElementMapHandler.java | 38 +++++----- .../strolch/runtime/agent/StrolchAgent.java | 1 + .../strolch/runtime/agent/StrolchRealm.java | 57 +++++++++++++++ .../agent/TransientElementMapHandler.java | 54 ++++++++++---- .../AbstractionConfiguration.java | 14 ++++ .../component/ComponentContainerTest.java | 14 ++++ .../realmtest/config/StrolchConfiguration.xml | 36 ++++++++++ src/test/resources/realmtest/data/Orders.xml | 14 ++++ .../resources/realmtest/data/Resources.xml | 14 ++++ .../resources/realmtest/data/StrolchModel.xml | 29 ++++++++ 13 files changed, 313 insertions(+), 42 deletions(-) create mode 100644 src/main/java/li/strolch/runtime/agent/AbstractElementMapHandler.java create mode 100644 src/main/java/li/strolch/runtime/agent/StrolchRealm.java create mode 100644 src/test/resources/realmtest/config/StrolchConfiguration.xml create mode 100644 src/test/resources/realmtest/data/Orders.xml create mode 100644 src/test/resources/realmtest/data/Resources.xml create mode 100644 src/test/resources/realmtest/data/StrolchModel.xml diff --git a/src/main/java/li/strolch/runtime/agent/AbstractElementMapHandler.java b/src/main/java/li/strolch/runtime/agent/AbstractElementMapHandler.java new file mode 100644 index 000000000..1a1dfbf4a --- /dev/null +++ b/src/main/java/li/strolch/runtime/agent/AbstractElementMapHandler.java @@ -0,0 +1,71 @@ +/* + * Copyright 2013 Robert von Burg + * + * 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 li.strolch.runtime.agent; + +import java.text.MessageFormat; +import java.util.Map; + +import li.strolch.exception.StrolchException; +import li.strolch.model.query.StrolchQuery; + +/** + * @author Robert von Burg + */ +public abstract class AbstractElementMapHandler extends StrolchComponent implements ElementMapHandler { + + protected Map realms; + + /** + * @param container + * @param componentName + */ + public AbstractElementMapHandler(ComponentContainerImpl container, String componentName) { + super(container, componentName); + } + + @Override + public ResourceMap getResourceMap() { + return getResourceMap(StrolchQuery.DEFAULT_REALM); + } + + @Override + public ResourceMap getResourceMap(String realm) { + StrolchRealm strolchRealm = getRealm(realm); + return strolchRealm.getResourceMap(); + } + + @Override + public OrderMap getOrderMap() { + return getOrderMap(StrolchQuery.DEFAULT_REALM); + } + + @Override + public OrderMap getOrderMap(String realm) { + StrolchRealm strolchRealm = getRealm(realm); + return strolchRealm.getOrderMap(); + } + + private StrolchRealm getRealm(String realm) { + assertContainerStarted(); + StrolchRealm strolchRealm = this.realms.get(realm); + if (strolchRealm == null) { + String msg = "No realm is configured with the name {0}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, realm); + throw new StrolchException(msg); + } + return strolchRealm; + } +} diff --git a/src/main/java/li/strolch/runtime/agent/ElementMapHandler.java b/src/main/java/li/strolch/runtime/agent/ElementMapHandler.java index d21820dff..848d53788 100644 --- a/src/main/java/li/strolch/runtime/agent/ElementMapHandler.java +++ b/src/main/java/li/strolch/runtime/agent/ElementMapHandler.java @@ -21,6 +21,10 @@ package li.strolch.runtime.agent; public interface ElementMapHandler { public ResourceMap getResourceMap(); + + public ResourceMap getResourceMap(String realm); public OrderMap getOrderMap(); + + public OrderMap getOrderMap(String realm); } diff --git a/src/main/java/li/strolch/runtime/agent/EmptyElementMapHandler.java b/src/main/java/li/strolch/runtime/agent/EmptyElementMapHandler.java index f579e617c..28be6640a 100644 --- a/src/main/java/li/strolch/runtime/agent/EmptyElementMapHandler.java +++ b/src/main/java/li/strolch/runtime/agent/EmptyElementMapHandler.java @@ -15,8 +15,6 @@ */ package li.strolch.runtime.agent; -import li.strolch.runtime.configuration.ComponentConfiguration; - /** * @author Robert von Burg */ @@ -29,11 +27,4 @@ public class EmptyElementMapHandler extends InMemoryElementMapHandler { public EmptyElementMapHandler(ComponentContainerImpl container, String componentName) { super(container, componentName); } - - @Override - public void initialize(ComponentConfiguration configuration) { - this.resourceMap = new InMemoryResourceMap(); - this.orderMap = new InMemoryOrderMap(); - super.initialize(configuration); - } } diff --git a/src/main/java/li/strolch/runtime/agent/InMemoryElementMapHandler.java b/src/main/java/li/strolch/runtime/agent/InMemoryElementMapHandler.java index 8a3644c7f..e997c978b 100644 --- a/src/main/java/li/strolch/runtime/agent/InMemoryElementMapHandler.java +++ b/src/main/java/li/strolch/runtime/agent/InMemoryElementMapHandler.java @@ -15,15 +15,16 @@ */ package li.strolch.runtime.agent; +import java.util.HashMap; + +import li.strolch.model.query.StrolchQuery; +import li.strolch.runtime.configuration.ComponentConfiguration; +import li.strolch.runtime.configuration.RuntimeConfiguration; /** * @author Robert von Burg - * */ -public abstract class InMemoryElementMapHandler extends StrolchComponent implements ElementMapHandler { - - protected ResourceMap resourceMap; - protected OrderMap orderMap; +public class InMemoryElementMapHandler extends AbstractElementMapHandler { /** * @param container @@ -33,21 +34,20 @@ public abstract class InMemoryElementMapHandler extends StrolchComponent impleme super(container, componentName); } - /** - * @return the resourceMap - */ @Override - public ResourceMap getResourceMap() { - assertContainerStarted(); - return this.resourceMap; - } + public void initialize(ComponentConfiguration configuration) { - /** - * @return the orderMap - */ - @Override - public OrderMap getOrderMap() { - assertContainerStarted(); - return this.orderMap; + RuntimeConfiguration runtimeConfiguration = configuration.getRuntimeConfiguration(); + String[] realms = runtimeConfiguration.getStringArray(StrolchAgent.PROP_REALMS, StrolchQuery.DEFAULT_REALM); + + this.realms = new HashMap<>(); + for (String realm : realms) { + InMemoryResourceMap resourceMap = new InMemoryResourceMap(); + InMemoryOrderMap orderMap = new InMemoryOrderMap(); + StrolchRealm strolchRealm = new StrolchRealm(realm, resourceMap, orderMap); + this.realms.put(realm, strolchRealm); + } + + super.initialize(configuration); } } diff --git a/src/main/java/li/strolch/runtime/agent/StrolchAgent.java b/src/main/java/li/strolch/runtime/agent/StrolchAgent.java index 821acdc2b..6215ed29e 100644 --- a/src/main/java/li/strolch/runtime/agent/StrolchAgent.java +++ b/src/main/java/li/strolch/runtime/agent/StrolchAgent.java @@ -33,6 +33,7 @@ public class StrolchAgent { public static final String PROP_DATA_STORE_MODE = "dataStoreMode"; //$NON-NLS-1$ public static final String PROP_DATA_STORE_FILE = "dataStoreFile"; //$NON-NLS-1$ + public static final String PROP_REALMS = "realms"; //$NON-NLS-1$ private static final Logger logger = LoggerFactory.getLogger(StrolchAgent.class); private ComponentContainerImpl container; diff --git a/src/main/java/li/strolch/runtime/agent/StrolchRealm.java b/src/main/java/li/strolch/runtime/agent/StrolchRealm.java new file mode 100644 index 000000000..1b8971cb6 --- /dev/null +++ b/src/main/java/li/strolch/runtime/agent/StrolchRealm.java @@ -0,0 +1,57 @@ +/* + * Copyright 2013 Robert von Burg + * + * 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 li.strolch.runtime.agent; + +import li.strolch.model.query.StrolchQuery; + +/** + * @author Robert von Burg + */ +public class StrolchRealm { + + public static final String DEFAULT_REALM = StrolchQuery.DEFAULT_REALM; + + private String realm; + private ResourceMap resourceMap; + private OrderMap orderMap; + + public StrolchRealm(String realm, ResourceMap resourceMap, OrderMap orderMap) { + this.realm = realm; + this.resourceMap = resourceMap; + this.orderMap = orderMap; + } + + /** + * @return the realm + */ + public String getRealm() { + return this.realm; + } + + /** + * @return the resourceMap + */ + public ResourceMap getResourceMap() { + return this.resourceMap; + } + + /** + * @return the orderMap + */ + public OrderMap getOrderMap() { + return this.orderMap; + } +} diff --git a/src/main/java/li/strolch/runtime/agent/TransientElementMapHandler.java b/src/main/java/li/strolch/runtime/agent/TransientElementMapHandler.java index 4eb1e4554..3835bf833 100644 --- a/src/main/java/li/strolch/runtime/agent/TransientElementMapHandler.java +++ b/src/main/java/li/strolch/runtime/agent/TransientElementMapHandler.java @@ -17,11 +17,14 @@ package li.strolch.runtime.agent; import java.io.File; import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; import li.strolch.model.xml.XmlModelDefaultHandler.XmlModelStatistics; import li.strolch.model.xml.XmlModelFileHandler; import li.strolch.runtime.configuration.ComponentConfiguration; import li.strolch.runtime.configuration.RuntimeConfiguration; +import li.strolch.runtime.configuration.StrolchConfigurationException; import ch.eitchnet.utils.helper.StringHelper; /** @@ -29,7 +32,7 @@ import ch.eitchnet.utils.helper.StringHelper; */ public class TransientElementMapHandler extends InMemoryElementMapHandler { - private File modelFile; + private Map realmModelFiles; /** * @param container @@ -41,29 +44,52 @@ public class TransientElementMapHandler extends InMemoryElementMapHandler { @Override public void initialize(ComponentConfiguration configuration) { + super.initialize(configuration); + this.realmModelFiles = new HashMap<>(); RuntimeConfiguration runtimeConfiguration = configuration.getRuntimeConfiguration(); - File modelFile = runtimeConfiguration.getDataFile(StrolchAgent.PROP_DATA_STORE_FILE, null, - runtimeConfiguration, true); - this.modelFile = modelFile; + for (String realm : this.realms.keySet()) { + String key = getDataStoreFilePropKey(realm); - this.resourceMap = new InMemoryResourceMap(); - this.orderMap = new InMemoryOrderMap(); + if (!runtimeConfiguration.hasProperty(key)) { + String msg = "There is no data store file for realm {0}. Set a property with key {1}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, realm, key); + throw new StrolchConfigurationException(msg); + } + + File modelFile = runtimeConfiguration.getDataFile(key, null, runtimeConfiguration, true); + this.realmModelFiles.put(realm, modelFile); + } super.initialize(configuration); } + private String getDataStoreFilePropKey(String realm) { + if (realm.equals(StrolchRealm.DEFAULT_REALM)) + return StrolchAgent.PROP_DATA_STORE_FILE; + return StrolchAgent.PROP_DATA_STORE_FILE + "." + realm; //$NON-NLS-1$ + } + @Override public void start() { - InMemoryElementListener elementListener = new InMemoryElementListener(this.resourceMap, this.orderMap); - XmlModelFileHandler handler = new XmlModelFileHandler(elementListener, this.modelFile); - handler.parseFile(); - XmlModelStatistics statistics = handler.getStatistics(); - String durationS = StringHelper.formatNanoDuration(statistics.durationNanos); - logger.info(MessageFormat.format("Loading XML Model file {0} took {1}.", this.modelFile.getName(), durationS)); //$NON-NLS-1$ - logger.info(MessageFormat.format("Loaded {0} Orders", statistics.nrOfOrders)); //$NON-NLS-1$ - logger.info(MessageFormat.format("Loaded {0} Resources", statistics.nrOfResources)); //$NON-NLS-1$ + for (String realm : this.realms.keySet()) { + + StrolchRealm strolchRealm = this.realms.get(realm); + ResourceMap resourceMap = strolchRealm.getResourceMap(); + OrderMap orderMap = strolchRealm.getOrderMap(); + + File modelFile = this.realmModelFiles.get(realm); + InMemoryElementListener elementListener = new InMemoryElementListener(resourceMap, orderMap); + XmlModelFileHandler handler = new XmlModelFileHandler(elementListener, modelFile); + handler.parseFile(); + XmlModelStatistics statistics = handler.getStatistics(); + String durationS = StringHelper.formatNanoDuration(statistics.durationNanos); + logger.info(MessageFormat.format( + "Loading XML Model file {0} for realm {1} took {2}.", modelFile.getName(), realm, durationS)); //$NON-NLS-1$ + logger.info(MessageFormat.format("Loaded {0} Orders", statistics.nrOfOrders)); //$NON-NLS-1$ + logger.info(MessageFormat.format("Loaded {0} Resources", statistics.nrOfResources)); //$NON-NLS-1$ + } super.start(); } diff --git a/src/main/java/li/strolch/runtime/configuration/AbstractionConfiguration.java b/src/main/java/li/strolch/runtime/configuration/AbstractionConfiguration.java index c281a348e..684e91bac 100644 --- a/src/main/java/li/strolch/runtime/configuration/AbstractionConfiguration.java +++ b/src/main/java/li/strolch/runtime/configuration/AbstractionConfiguration.java @@ -42,10 +42,24 @@ public abstract class AbstractionConfiguration { return this.name; } + public boolean hasProperty(String key) { + return this.configurationValues.containsKey(key); + } + public Set getPropertyKeys() { return new HashSet<>(this.configurationValues.keySet()); } + public String[] getStringArray(String key, String defValue) { + String value = getValue(key, defValue); + String[] values = value.split(","); //$NON-NLS-1$ + for (int i = 0; i < values.length; i++) { + values[i] = values[i].trim(); + } + + return values; + } + public String getString(String key, String defValue) { return getValue(key, defValue); } diff --git a/src/test/java/li/strolch/runtime/test/component/ComponentContainerTest.java b/src/test/java/li/strolch/runtime/test/component/ComponentContainerTest.java index 74a2e8a16..6193ee4b8 100644 --- a/src/test/java/li/strolch/runtime/test/component/ComponentContainerTest.java +++ b/src/test/java/li/strolch/runtime/test/component/ComponentContainerTest.java @@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory; @SuppressWarnings("nls") public class ComponentContainerTest { + public static final String PATH_REALM_CONTAINER = "src/test/resources/realmtest"; public static final String PATH_TRANSIENT_CONTAINER = "src/test/resources/transienttest"; public static final String PATH_EMPTY_CONTAINER = "src/test/resources/emptytest"; @@ -62,6 +63,19 @@ public class ComponentContainerTest { } } + @Test + public void shouldStartRealmTestContainer() { + + try { + StrolchAgent agent = startContainer(PATH_REALM_CONTAINER); + testContainer(agent); + destroyContainer(agent); + } catch (Exception e) { + logger.error(e.getMessage(), e); + throw e; + } + } + public static StrolchAgent startContainer(String rootPath) { File rootPathF = new File(rootPath); return startContainer(rootPathF); diff --git a/src/test/resources/realmtest/config/StrolchConfiguration.xml b/src/test/resources/realmtest/config/StrolchConfiguration.xml new file mode 100644 index 000000000..ce5ba9e7c --- /dev/null +++ b/src/test/resources/realmtest/config/StrolchConfiguration.xml @@ -0,0 +1,36 @@ + + + + StrolchRuntimeTest + + TRANSIENT + myRealm + StrolchModel.xml + true + + + + ServiceHandler + li.strolch.runtime.test.component.ServiceHandlerTest + li.strolch.runtime.test.component.ServiceHandlerTestImpl + PersistenceHandler + + + + + PostInitializer + li.strolch.runtime.test.component.PostInitializerTest + li.strolch.runtime.test.component.PostInitializerTestImpl + ServiceHandler + + + + + PersistenceHandler + li.strolch.runtime.test.component.PersistenceHandlerTest + li.strolch.runtime.test.component.PersistenceHandlerTestImpl + + true + + + \ No newline at end of file diff --git a/src/test/resources/realmtest/data/Orders.xml b/src/test/resources/realmtest/data/Orders.xml new file mode 100644 index 000000000..55358bcaa --- /dev/null +++ b/src/test/resources/realmtest/data/Orders.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/test/resources/realmtest/data/Resources.xml b/src/test/resources/realmtest/data/Resources.xml new file mode 100644 index 000000000..e6259cb83 --- /dev/null +++ b/src/test/resources/realmtest/data/Resources.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/test/resources/realmtest/data/StrolchModel.xml b/src/test/resources/realmtest/data/StrolchModel.xml new file mode 100644 index 000000000..cb2396975 --- /dev/null +++ b/src/test/resources/realmtest/data/StrolchModel.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file