diff --git a/.gitignore b/.gitignore index 8524ee842..4a40bd1ce 100644 --- a/.gitignore +++ b/.gitignore @@ -326,4 +326,5 @@ Temporary Items ################################### # VSCode -.vscode \ No newline at end of file +.vscode +docgen/renv \ No newline at end of file diff --git a/README.md b/README.md index c866493af..4822695ab 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ To use this project in your project, simply add the following dependency to your gov.hhs.aspr.ms.gcm simulation - 4.2.0 + 4.4.0 ``` @@ -53,7 +53,7 @@ Data managers and actors are organized into plugins. A GCM model is thus compose ### Requirements - Maven 3.8.x - Java 17 -- Your favroite IDE for developing Java projects +- Your favorite IDE for developing Java projects - Modeling Utilities located [here](https://github.com/HHS/ASPR-ms-util) *Note that Modeling Utilities is in Maven Central, so there is no need to clone and build it. @@ -69,7 +69,7 @@ To build this project: The documentation can be found at [https://hhs.github.io/ASPR-8/](https://hhs.github.io/ASPR-8/) ## Lessons -The documentation contains lessons which the code can be found in [lessons](lessons). +Code for all lessons in the documentation above can be found in [lessons](lessons). [contributors-shield]: https://img.shields.io/github/contributors/HHS/ASPR-8 diff --git a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ActorContext.java b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ActorContext.java index 5397c77ce..41a843456 100644 --- a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ActorContext.java +++ b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ActorContext.java @@ -13,6 +13,7 @@ * managers to actors. It is supplied by the engine each time it interacts with * an actor. Actors are defined by this context. If this context is passed to a * method invocation, then that method is an actor method. + * */ public final class ActorContext { @@ -251,5 +252,31 @@ public List retrievePlans() { public Optional getSimulationHaltTime() { return simulation.getSimulationHaltTime(); } + + /** + * Returns the plugin data object associated with the given class reference + * + * @throws ContractException + * + */ + public Optional getPluginData(Class pluginDataClass) { + return simulation.getPluginData(pluginDataClass); + } + + /** + * Returns the plugin data objects associated with the given class reference + * + * @throws ContractException {@linkplain NucleusError#NULL_PLUGIN_DATA_CLASS} if + * the class reference is null + */ + public List getPluginDatas(Class pluginDataClass) { + return simulation.getPluginDatas(pluginDataClass); + } } diff --git a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/DataManagerContext.java b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/DataManagerContext.java index dfbbaa6b8..0345e0cb9 100644 --- a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/DataManagerContext.java +++ b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/DataManagerContext.java @@ -315,5 +315,31 @@ public DataManagerId getDataManagerId() { public Optional getSimulationHaltTime() { return simulation.getSimulationHaltTime(); } + + /** + * Returns the plugin data object associated with the given class reference + * + * @throws ContractException + *
    + *
  • {@linkplain NucleusError#NULL_PLUGIN_DATA_CLASS} + * if the class reference is null
  • + *
  • {@linkplain NucleusError#AMBIGUOUS_PLUGIN_DATA_CLASS} + * if more than one plugin data object matches the + * class reference
  • + *
+ */ + public Optional getPluginData(Class pluginDataClass) { + return simulation.getPluginData(pluginDataClass); + } + + /** + * Returns the plugin data objects associated with the given class reference + * + * @throws ContractException {@linkplain NucleusError#NULL_PLUGIN_DATA_CLASS} if + * the class reference is null + */ + public List getPluginDatas(Class pluginDataClass) { + return simulation.getPluginDatas(pluginDataClass); + } } diff --git a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ReportContext.java b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ReportContext.java index 938a57fe3..94fe84987 100644 --- a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ReportContext.java +++ b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ReportContext.java @@ -202,5 +202,31 @@ public List retrievePlans() { public Optional getSimulationHaltTime() { return simulation.getSimulationHaltTime(); } + + /** + * Returns the plugin data object associated with the given class reference + * + * @throws ContractException + *
    + *
  • {@linkplain NucleusError#NULL_PLUGIN_DATA_CLASS} + * if the class reference is null
  • + *
  • {@linkplain NucleusError#AMBIGUOUS_PLUGIN_DATA_CLASS} + * if more than one plugin data object matches the + * class reference
  • + *
+ */ + public Optional getPluginData(Class pluginDataClass) { + return simulation.getPluginData(pluginDataClass); + } + + /** + * Returns the plugin data objects associated with the given class reference + * + * @throws ContractException {@linkplain NucleusError#NULL_PLUGIN_DATA_CLASS} if + * the class reference is null + */ + public List getPluginDatas(Class pluginDataClass) { + return simulation.getPluginDatas(pluginDataClass); + } } diff --git a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DataManagerContext.java b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DataManagerContext.java index de788dfb7..3ce1cd0ba 100644 --- a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DataManagerContext.java +++ b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DataManagerContext.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -1333,4 +1334,163 @@ public void testGetDataManagerId() { .execute();// } + + private static class LocalPluginData implements PluginData { + + public static class Builder implements PluginDataBuilder { + @Override + public LocalPluginData build() { + return new LocalPluginData(); + } + } + + @Override + public PluginDataBuilder toBuilder() { + return new Builder(); + } + } + + private static class LocalPluginData2 implements PluginData { + + public static class Builder implements PluginDataBuilder { + @Override + public LocalPluginData2 build() { + return new LocalPluginData2(); + } + } + + @Override + public PluginDataBuilder toBuilder() { + return new Builder(); + } + } + + @Test + @UnitTestMethod(target = DimensionContext.class, name = "getPluginData", args = { Class.class }) + public void testGetPluginData() { + + TestPluginData.Builder pluginDataBuilder = TestPluginData.builder(); + pluginDataBuilder.addTestDataManager("dm", ()->new TestDataManager()); + + pluginDataBuilder.addTestDataManagerPlan("dm", new TestDataManagerPlan(0, (c) -> { + Optional optional1 = c.getPluginData(LocalPluginData.class); + assertTrue(optional1.isPresent()); + Optional optional2 = c.getPluginData(LocalPluginData2.class); + assertFalse(optional2.isPresent()); + + })); + + // build the plugin + TestPluginData testPluginData = pluginDataBuilder.build(); + Plugin testPlugin = TestPlugin.getTestPlugin(testPluginData); + + Plugin localPlugin = Plugin.builder()// + .setPluginId(new SimplePluginId("localPlugin"))// + .addPluginData(new LocalPluginData())// + .build(); + + // run the simulation + Simulation.builder()// + .addPlugin(testPlugin)// + .addPlugin(localPlugin)// + .build()// + .execute();// + + // precondition test: if more than one plugin data object matches the class + // reference + ContractException contractException = assertThrows(ContractException.class, () -> { + Plugin lp = Plugin.builder()// + .setPluginId(new SimplePluginId("localPlugin"))// + .addPluginData(new LocalPluginData())// + .addPluginData(new LocalPluginData())// + .build(); + + Simulation.builder()// + .addPlugin(lp)// + .addPlugin(TestPlugin.getTestPlugin( + + TestPluginData.builder()// + .addTestDataManager("dm", ()->new TestDataManager())// + .addTestActorPlan("dm", new TestActorPlan(0, (c) -> { + c.getPluginData(LocalPluginData.class); + })).build()))// + .build()// + .execute();// + }); + assertEquals(NucleusError.AMBIGUOUS_PLUGIN_DATA_CLASS, contractException.getErrorType()); + + // precondition test: if the class reference is null + contractException = assertThrows(ContractException.class, () -> { + Simulation.builder()// + .addPlugin(TestPlugin.getTestPlugin( + TestPluginData.builder()// + .addTestDataManager("dm", ()->new TestDataManager()) + .addTestActorPlan("dm", new TestActorPlan(0, (c) -> { + c.getPluginData(null); + })).build()))// + .build()// + .execute();// + }); + assertEquals(NucleusError.NULL_PLUGIN_DATA_CLASS, contractException.getErrorType()); + + } + + @Test + @UnitTestMethod(target = DimensionContext.class, name = "getPluginDatas", args = { Class.class }) + public void testGetPluginDatas() { + /* + * Returns the plugin data objects associated with the given class reference + * + * @throws ContractException {@linkplain NucleusError#NULL_PLUGIN_DATA_CLASS} if + * the class reference is null + */ + TestPluginData.Builder pluginDataBuilder = TestPluginData.builder(); + pluginDataBuilder.addTestDataManager("dm",()->new TestDataManager()); + pluginDataBuilder.addTestDataManagerPlan("dm", new TestDataManagerPlan(0, (c) -> { + List localPluginDatas = c.getPluginDatas(LocalPluginData.class); + assertNotNull(localPluginDatas); + assertEquals(2,localPluginDatas.size()); + + List localPluginData2s = c.getPluginDatas(LocalPluginData2.class); + assertNotNull(localPluginData2s); + assertEquals(0,localPluginData2s.size()); + + List pluginDatas = c.getPluginDatas(PluginData.class); + assertNotNull(pluginDatas); + assertEquals(3,pluginDatas.size()); + + })); + + // build the plugin + TestPluginData testPluginData = pluginDataBuilder.build(); + Plugin testPlugin = TestPlugin.getTestPlugin(testPluginData); + + Plugin localPlugin = Plugin.builder()// + .setPluginId(new SimplePluginId("localPlugin"))// + .addPluginData(new LocalPluginData())// + .addPluginData(new LocalPluginData())// + .build(); + + // run the simulation + Simulation.builder()// + .addPlugin(testPlugin)// + .addPlugin(localPlugin)// + .build()// + .execute();// + + // precondition test: if the class reference is null + ContractException contractException = assertThrows(ContractException.class, () -> { + Simulation.builder()// + .addPlugin(TestPlugin.getTestPlugin( + TestPluginData.builder()// + .addTestDataManager("dm", ()->new TestDataManager())// + .addTestActorPlan("dm", new TestActorPlan(0, (c) -> { + c.getPluginDatas(null); + })).build()))// + .build()// + .execute();// + }); + assertEquals(NucleusError.NULL_PLUGIN_DATA_CLASS, contractException.getErrorType()); + + } } diff --git a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DimesionContext.java b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DimesionContext.java index 199f3e5ea..a7a93f46c 100644 --- a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DimesionContext.java +++ b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DimesionContext.java @@ -502,4 +502,6 @@ public void testBuild() { assertEquals(NucleusError.NULL_SIMULATION_STATE, contractException.getErrorType()); } + + } diff --git a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_Experiment.java b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_Experiment.java index 023d270c0..cd44c9ca5 100644 --- a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_Experiment.java +++ b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_Experiment.java @@ -398,7 +398,7 @@ private void testSetHaltOnException() { testSetHaltOnException_Implicit(); } - @Test + private void testSetHaltOnException_Explicit_True() { // This test will run the experiment two times in single thread mode diff --git a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_ReportContext.java b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_ReportContext.java index ff511fd34..4bc174c53 100644 --- a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_ReportContext.java +++ b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_ReportContext.java @@ -13,6 +13,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -820,4 +821,164 @@ private void planRetrievalSimCloseSubscribe(ReportContext context, List {})); + + pluginDataBuilder.addTestReportPlan("report", new TestReportPlan(0, (c) -> { + Optional optional1 = c.getPluginData(LocalPluginData.class); + assertTrue(optional1.isPresent()); + Optional optional2 = c.getPluginData(LocalPluginData2.class); + assertFalse(optional2.isPresent()); + + })); + + // build the plugin + TestPluginData testPluginData = pluginDataBuilder.build(); + Plugin testPlugin = TestPlugin.getTestPlugin(testPluginData); + + Plugin localPlugin = Plugin.builder()// + .setPluginId(new SimplePluginId("localPlugin"))// + .addPluginData(new LocalPluginData())// + .build(); + + // run the simulation + Simulation.builder()// + .addPlugin(testPlugin)// + .addPlugin(localPlugin)// + .build()// + .execute();// + + // precondition test: if more than one plugin data object matches the class + // reference + ContractException contractException = assertThrows(ContractException.class, () -> { + Plugin lp = Plugin.builder()// + .setPluginId(new SimplePluginId("localPlugin"))// + .addPluginData(new LocalPluginData())// + .addPluginData(new LocalPluginData())// + .build(); + + Simulation.builder()// + .addPlugin(lp)// + .addPlugin(TestPlugin.getTestPlugin( + TestPluginData.builder()// + .addTestActorPlan("actor", new TestActorPlan(10, (c) -> {}))// + .addTestReportPlan("report", new TestReportPlan(0, (c) -> { + c.getPluginData(LocalPluginData.class); + })).build()))// + .build()// + .execute();// + }); + assertEquals(NucleusError.AMBIGUOUS_PLUGIN_DATA_CLASS, contractException.getErrorType()); + + // precondition test: if the class reference is null + contractException = assertThrows(ContractException.class, () -> { + Simulation.builder()// + .addPlugin(TestPlugin.getTestPlugin( + TestPluginData.builder()// + .addTestActorPlan("actor", new TestActorPlan(10, (c) -> {}))// + .addTestReportPlan("dm", new TestReportPlan(0, (c) -> { + c.getPluginData(null); + })).build()))// + .build()// + .execute();// + }); + assertEquals(NucleusError.NULL_PLUGIN_DATA_CLASS, contractException.getErrorType()); + + } + + @Test + @UnitTestMethod(target = ReportContext.class, name = "getPluginDatas", args = { Class.class }) + public void testGetPluginDatas() { + /* + * Returns the plugin data objects associated with the given class reference + * + * @throws ContractException {@linkplain NucleusError#NULL_PLUGIN_DATA_CLASS} if + * the class reference is null + */ + TestPluginData.Builder pluginDataBuilder = TestPluginData.builder(); + pluginDataBuilder.addTestActorPlan("actor", new TestActorPlan(10, (c) -> {})); + pluginDataBuilder.addTestReportPlan("report", new TestReportPlan(4, (c) -> { + List localPluginDatas = c.getPluginDatas(LocalPluginData.class); + assertNotNull(localPluginDatas); + assertEquals(2,localPluginDatas.size()); + + List localPluginData2s = c.getPluginDatas(LocalPluginData2.class); + assertNotNull(localPluginData2s); + assertEquals(0,localPluginData2s.size()); + + List pluginDatas = c.getPluginDatas(PluginData.class); + assertNotNull(pluginDatas); + assertEquals(3,pluginDatas.size()); + + })); + + // build the plugin + TestPluginData testPluginData = pluginDataBuilder.build(); + Plugin testPlugin = TestPlugin.getTestPlugin(testPluginData); + + Plugin localPlugin = Plugin.builder()// + .setPluginId(new SimplePluginId("localPlugin"))// + .addPluginData(new LocalPluginData())// + .addPluginData(new LocalPluginData())// + .build(); + + // run the simulation + Simulation.builder()// + .addPlugin(testPlugin)// + .addPlugin(localPlugin)// + .build()// + .execute();// + + // precondition test: if the class reference is null + ContractException contractException = assertThrows(ContractException.class, () -> { + Simulation.builder()// + .addPlugin(TestPlugin.getTestPlugin( + TestPluginData.builder()// + .addTestActorPlan("actor", new TestActorPlan(10, (c) -> {}))// + .addTestReportPlan("report", new TestReportPlan(0, (c) -> { + c.getPluginDatas(null); + })).build()))// + .build()// + .execute();// + }); + assertEquals(NucleusError.NULL_PLUGIN_DATA_CLASS, contractException.getErrorType()); + + } + }