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