diff --git a/Core/build.gradle b/Core/build.gradle index fdb95ca..dec3211 100644 --- a/Core/build.gradle +++ b/Core/build.gradle @@ -3,7 +3,7 @@ plugins { } group 'com.scaleoutsoftware.digitaltwin' -version '3.0.4' +version '3.2.2' sourceCompatibility = JavaVersion.VERSION_12 @@ -19,10 +19,21 @@ configurations { archives } -task myJavadocs(type: Javadoc) { +task createJavadocs(type: Javadoc) { source = sourceSets.main.allJava } +task javadocJar(type: Jar, dependsOn: createJavadocs) { + setArchiveClassifier('javadoc') + from javadoc.destinationDir +} + + +task sourcesJar(type: Jar, dependsOn: classes) { + setArchiveClassifier('sources') + from sourceSets.main.allSource +} + jar { manifest { attributes ('Implementation-Title': project.name, @@ -30,4 +41,10 @@ jar { } } +task copyRuntime(type: GradleBuild) { + tasks = ['javadocJar', 'sourcesJar'] +} + +build.finalizedBy copyRuntime + diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertMessage.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertMessage.java index 4383a90..7e0d3f4 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertMessage.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertMessage.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2021 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.java index 88bd238..8f718aa 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2021 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/CacheOperationStatus.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/CacheOperationStatus.java new file mode 100644 index 0000000..119b0be --- /dev/null +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/CacheOperationStatus.java @@ -0,0 +1,48 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * Status of a cache operation. + */ +public enum CacheOperationStatus { + + /** + * The object was successfully retrieved. + */ + + ObjectRetrieved, + + /** + * The object was successfully added/updated. + */ + ObjectPut, + + /** + * The object could not be retrieved because it was not found. + */ + ObjectDoesNotExist, + + /** + * The object was removed successfully. + */ + ObjectRemoved, + + /** + * The cache was cleared successfully. + */ + CacheCleared +} diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/CacheResult.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/CacheResult.java new file mode 100644 index 0000000..9dc13c7 --- /dev/null +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/CacheResult.java @@ -0,0 +1,39 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * Represents a response from a {@link SharedData} operation. + */ +public interface CacheResult { + /** + * Gets the key or null to the object associated with the result. + * @return the key or null. + */ + public String getKey(); + + /** + * Get the object returned from a Get operation. + * @return the object or null. + */ + public byte[] getValue(); + + /** + * Gets the status of the cache operation. + * @return the operation status. + */ + CacheOperationStatus getStatus(); +} diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.java index 84cfaa6..4b4333d 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2018 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -45,6 +45,11 @@ public abstract class DigitalTwinBase { */ public long NextSimulationTime = 0L; + /** + * Default constructor. + */ + public DigitalTwinBase() {} + /** * Retrieve the next simulation time in milliseconds. * @return the next simulation time in milliseconds. diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.java index 9b591c8..6ea0ce0 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2022 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/InitContext.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/InitContext.java index a90b53d..4cb7014 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/InitContext.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/InitContext.java @@ -1,3 +1,18 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; import java.time.Duration; @@ -7,6 +22,12 @@ * digital twin. */ public abstract class InitContext { + + /** + * Default constructor. + */ + public InitContext() {} + /** * Starts a new timer for the digital twin * @param timerName the timer name @@ -19,6 +40,18 @@ public abstract class InitContext { */ public abstract TimerActionResult startTimer(String timerName, Duration interval, TimerType timerType, TimerHandler timerHandler); + /** + * Retrieve a {@link SharedData} accessor for this model's shared data. + * @return a {@link SharedData} instance. + */ + public abstract SharedData getSharedModelData(); + + /** + * Retrieve a {@link SharedData} accessor for globally shared data. + * @return a {@link SharedData} instance. + */ + public abstract SharedData getSharedGlobalData(); + /** * Get the model-unique Id identifier of the initializing digital twin instance. * @return the id identifier. diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/InitSimulationContext.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/InitSimulationContext.java new file mode 100644 index 0000000..62ae315 --- /dev/null +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/InitSimulationContext.java @@ -0,0 +1,21 @@ +package com.scaleoutsoftware.digitaltwin.core; + +import java.util.Date; + +/** + * The InitSimulationContext is passed as a parameter to the {@link SimulationProcessor#onInitSimulation(InitSimulationContext, DigitalTwinBase, Date)} method of + * digital twin instance when a simulation is initializing. + */ +public interface InitSimulationContext { + /** + * Retrieve a {@link SharedData} accessor for this model's shared data. + * @return a {@link SharedData} instance. + */ + public abstract SharedData getSharedModelData(); + + /** + * Retrieve a {@link SharedData} accessor for globally shared data. + * @return a {@link SharedData} instance. + */ + public abstract SharedData getSharedGlobalData(); +} diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageFactory.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageFactory.java index 954c08f..1e89eed 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageFactory.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageFactory.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2018 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.java index c9cdd7f..a608741 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2018 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,6 +23,12 @@ * @param the type of messages processed by the real-time digital twin */ public abstract class MessageProcessor extends MessageProcessorBase implements Serializable { + + /** + * Default constructor. + */ + public MessageProcessor() {} + /** * Processes a set of incoming messages and determines whether to update the real-time digital twin. * @param context optional context for processing. diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.java index 179dd6d..befa76d 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2018 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,6 +20,12 @@ * @param the type of the DigitalTwin */ public abstract class MessageProcessorBase { + + /** + * Default constructor. + */ + public MessageProcessorBase() {} + /** * Helper method to ensure proper typing for the user methods. * @param context the processing context diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/ModelSchema.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/ModelSchema.java index 18daad3..970ab1a 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/ModelSchema.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/ModelSchema.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2018 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -27,16 +27,19 @@ public class ModelSchema { private final String simulationProcessorType; private final String messageType; private final String assemblyName; + private final String entryPoint; private final String azureDigitalTwinModelName; private final String persistenceProvider; private final boolean enablePersistence; private final boolean enableSimulationSupport; + private final boolean enableMessageRecording; private final List alertProviders; private ModelSchema() { - modelType = messageProcessorType = simulationProcessorType = messageType = assemblyName = azureDigitalTwinModelName = persistenceProvider = null; + modelType = messageProcessorType = simulationProcessorType = messageType = assemblyName = entryPoint = azureDigitalTwinModelName = persistenceProvider = null; enablePersistence = false; enableSimulationSupport = false; + enableMessageRecording = false; alertProviders = null; } @@ -66,9 +69,121 @@ public ModelSchema( enableSimulationSupport = false; messageType = msgClass; assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; alertProviders = null; azureDigitalTwinModelName = null; enablePersistence = false; + enableMessageRecording = false; + persistenceProvider = null; + } + + /** + * Model schema with a defined entry point. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param ep the invocation grid entry point. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String ep) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = null; + enableSimulationSupport = false; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = ep; + alertProviders = null; + azureDigitalTwinModelName = null; + enablePersistence = false; + enableMessageRecording = false; + persistenceProvider = null; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, and a message class. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = null; + enableSimulationSupport = false; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; + alertProviders = null; + azureDigitalTwinModelName = null; + enablePersistence = false; + enableMessageRecording = emr; + persistenceProvider = null; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, and a message class. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param ep the invocation grid entry point. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String ep, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = null; + enableSimulationSupport = false; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = ep; + alertProviders = null; + azureDigitalTwinModelName = null; + enablePersistence = false; + enableMessageRecording = emr; persistenceProvider = null; } @@ -101,8 +216,10 @@ public ModelSchema( enableSimulationSupport = false; messageType = msgClass; assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; azureDigitalTwinModelName = null; enablePersistence = false; + enableMessageRecording = false; persistenceProvider = null; alertProviders = alertingProviders; } @@ -136,13 +253,146 @@ public ModelSchema( } modelType = dtClass; messageProcessorType = mpClass; - simulationProcessorType = null; - enableSimulationSupport = false; + simulationProcessorType = spClass; + enableSimulationSupport = true; messageType = msgClass; assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; azureDigitalTwinModelName = null; enablePersistence = false; persistenceProvider = null; + enableMessageRecording = false; + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, and + * alert provider configurations. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param spClass the simulation processor class implementation. + * @param ep the invocation grid entry point. + * @param alertingProviders the alerting provider configurations. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String spClass, + String ep, + List alertingProviders) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) || + (spClass == null || spClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass), + (spClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = spClass; + enableSimulationSupport = true; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = ep; + azureDigitalTwinModelName = null; + enablePersistence = false; + persistenceProvider = null; + enableMessageRecording = false; + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, and + * alert provider configurations. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param spClass the simulation processor class implementation. + * @param alertingProviders the alerting provider configurations. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String spClass, + List alertingProviders, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) || + (spClass == null || spClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass), + (spClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = spClass; + enableSimulationSupport = true; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; + azureDigitalTwinModelName = null; + enablePersistence = false; + persistenceProvider = null; + enableMessageRecording = emr; + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, and + * alert provider configurations. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param spClass the simulation processor class implementation. + * @param alertingProviders the alerting provider configurations. + * @param ep the invocation grid entry point. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String spClass, + String ep, + List alertingProviders, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) || + (spClass == null || spClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass), + (spClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = spClass; + enableSimulationSupport = true; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = ep; + azureDigitalTwinModelName = null; + enablePersistence = false; + persistenceProvider = null; + enableMessageRecording = emr; alertProviders = alertingProviders; } @@ -178,7 +428,9 @@ public ModelSchema( simulationProcessorType = null; enableSimulationSupport = false; messageType = msgClass; + enableMessageRecording = false; assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; persistenceProvider = persistenceType.name(); switch (persistenceType) { case AzureDigitalTwinsService: @@ -187,6 +439,8 @@ public ModelSchema( break; case SQLite: case SQLServer: + case DynamoDb: + case CosmosDb: enablePersistence = true; azureDigitalTwinModelName = null; break; @@ -199,6 +453,66 @@ public ModelSchema( } /** + * Creates a model schema from a digital twin class, a message processor class, a message class, and + * alert provider configurations. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param adtName the Azure Digital Twin model name. + * @param persistenceType the persistence provider type. + * @param alertingProviders the alerting provider configurations. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String adtName, + PersistenceProviderType persistenceType, + List alertingProviders, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = null; + enableSimulationSupport = false; + messageType = msgClass; + enableMessageRecording = emr; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; + persistenceProvider = persistenceType.name(); + switch (persistenceType) { + case AzureDigitalTwinsService: + azureDigitalTwinModelName = adtName; + enablePersistence = true; + break; + case SQLite: + case SQLServer: + case DynamoDb: + enablePersistence = true; + azureDigitalTwinModelName = null; + break; + default: + azureDigitalTwinModelName = null; + enablePersistence = false; + break; + } + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, + * a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + * and an alert provider configuration. * * @param dtClass the digital twin class implementation. * @param mpClass the message processor class implementation. @@ -230,8 +544,71 @@ public ModelSchema( messageProcessorType = mpClass; simulationProcessorType = simulationProcessorClass; enableSimulationSupport = true; + enableMessageRecording = false; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; + persistenceProvider = persistenceType.name(); + switch (persistenceType) { + case AzureDigitalTwinsService: + azureDigitalTwinModelName = adtName; + enablePersistence = true; + break; + case SQLite: + case SQLServer: + case DynamoDb: + enablePersistence = true; + azureDigitalTwinModelName = null; + break; + default: + azureDigitalTwinModelName = null; + enablePersistence = false; + break; + } + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, + * a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + * and an alert provider configuration. + * + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param simulationProcessorClass the simulation processor class implementation. + * @param adtName the Azure Digital Twin model name. + * @param persistenceType the persistence provider type. + * @param alertingProviders the alerting provider configurations. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String simulationProcessorClass, + String adtName, + PersistenceProviderType persistenceType, + List alertingProviders, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = simulationProcessorClass; + enableSimulationSupport = true; + enableMessageRecording = emr; messageType = msgClass; assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; persistenceProvider = persistenceType.name(); switch (persistenceType) { case AzureDigitalTwinsService: @@ -240,6 +617,72 @@ public ModelSchema( break; case SQLite: case SQLServer: + case DynamoDb: + case CosmosDb: + enablePersistence = true; + azureDigitalTwinModelName = null; + break; + default: + azureDigitalTwinModelName = null; + enablePersistence = false; + break; + } + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, + * a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + * and an alert provider configuration. + * + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param simulationProcessorClass the simulation processor class implementation. + * @param adtName the Azure Digital Twin model name. + * @param persistenceType the persistence provider type. + * @param alertingProviders the alerting provider configurations. + * @param ep the invocation grid entry point. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String simulationProcessorClass, + String adtName, + String ep, + PersistenceProviderType persistenceType, + List alertingProviders, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = simulationProcessorClass; + enableSimulationSupport = true; + enableMessageRecording = emr; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = ep; + persistenceProvider = persistenceType.name(); + switch (persistenceType) { + case AzureDigitalTwinsService: + azureDigitalTwinModelName = adtName; + enablePersistence = true; + break; + case SQLite: + case SQLServer: + case DynamoDb: + case CosmosDb: enablePersistence = true; azureDigitalTwinModelName = null; break; @@ -322,4 +765,21 @@ public String getAzureDigitalTwinModelName() { * @return the persistence provider type. */ public PersistenceProviderType getPersistenceProvider() { return PersistenceProviderType.fromString(persistenceProvider); } + + /** + * Retrieves the message recording enabled status. True if this model should persist messages when message recording is active, + * false otherwise. + * @return True if message recording is enabled, false otherwise. + */ + public boolean messageRecordingEnabled() { + return enableMessageRecording; + } + + /** + * Retrieves the packaged model's entry point (fully-qualified class name -- FQCN -- of a Java main) for launching. + * @return the entry point for launching. + */ + public String getEntryPoint() { + return entryPoint; + } } diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.java index f75ad0c..434bf75 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2021 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.java index 0ac9523..ba81125 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2021 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -26,6 +26,15 @@ public enum PersistenceProviderType implements Serializable { * Enum for the Azure Digital Twin service. */ AzureDigitalTwinsService("AzureDigitalTwinsService", 1), + /** + * Enum for CosmosDB + */ + CosmosDb("Azure Cosmos DB", 6), + + /** + * Enum for DynamoDB + */ + DynamoDb("DynamoDB", 5), /** * Enum for SQLite */ @@ -36,17 +45,34 @@ public enum PersistenceProviderType implements Serializable { SQLServer("SQLServer", 3), /** - * + * Enum for an unconfigured PersistenceProvider */ Unconfigured("", 0); - private String _name; - private int _value; + private final String _name; + private final int _value; PersistenceProviderType(String name, int ordinal) { _name = name; _value = ordinal; } + + /** + * Retrieve the name of the persistence provider type. + * @return the name of the persistence provider type. + */ + public String getName() { + return _name; + } + + /** + * Retrieve the ordinal value (used by the DTBuidler service). + * @return the ordinal value. + */ + public int getServiceOrdinalValue() { + return _value; + } + /** * Return the PersistenceProviderType from a string value. We do not rely on Java's naming * because the string values need to be cross-platform and the names may be different in each language. @@ -62,6 +88,13 @@ public static PersistenceProviderType fromString(String name) { return SQLite; case "SQLServer": return SQLServer; + case "DynamoDB": + return DynamoDb; + case "Azure Cosmos DB": + return CosmosDb; + case "Default": + case "default": + return Unconfigured; default: return null; } @@ -78,12 +111,18 @@ public static PersistenceProviderType fromString(String name) { */ public static PersistenceProviderType fromOrdinal(int ordinal) { switch(ordinal) { + case 0: + return Unconfigured; case 1: return AzureDigitalTwinsService; case 3: return SQLServer; case 4: return SQLite; + case 5: + return DynamoDb; + case 6: + return CosmosDb; default: return null; } diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.java index c785eff..2af1dc8 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2018 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -26,6 +26,11 @@ */ public abstract class ProcessingContext implements Serializable { + /** + * Default constructor. + */ + public ProcessingContext() {} + /** *

* Sends a message to a data source. This will route messages through the connector back to the data source. @@ -140,7 +145,7 @@ public abstract class ProcessingContext implements Serializable { /** *

- * This method sends an alert message to supported systems. See "TODO: Link to docs" for more details on supported systems. + * This method sends an alert message to supported systems. *

* *

@@ -222,4 +227,17 @@ public abstract class ProcessingContext implements Serializable { * @return the {@link SimulationController} or null if no simulation is running. */ public abstract SimulationController getSimulationController(); + + /** + * Retrieve a {@link SharedData} accessor for this model's shared data. + * @return a {@link SharedData} instance. + */ + public abstract SharedData getSharedModelData(); + + /** + * Retrieve a {@link SharedData} accessor for globally shared data. + * @return a {@link SharedData} instance. + */ + public abstract SharedData getSharedGlobalData(); + } diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.java index 45b2ed6..279f0fa 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2018 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SendingResult.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SendingResult.java index 94ea82f..9b3731b 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SendingResult.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SendingResult.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2018 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SharedData.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SharedData.java new file mode 100644 index 0000000..5c1392d --- /dev/null +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SharedData.java @@ -0,0 +1,49 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * SharedData is used to access a model's, or globally, shared cache. + */ +public interface SharedData { + /** + * Retrieves an existing object from the cache. + * @param key the key mapping to a value. + * @return A cache result. + */ + public CacheResult get(String key); + + /** + * Put a new key/value mapping into the cache. + * @param key the key mapping to a value. + * @param value the value. + * @return a cache result. + */ + public CacheResult put(String key, byte[] value); + + /** + * Remove a key/value mapping from the cache. + * @param key the key mapping to a value. + * @return a cache result. + */ + public CacheResult remove(String key); + + /** + * Clear the shared data cache. + * @return a cache result. + */ + public CacheResult clear(); +} diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationController.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationController.java index 14d32fd..314f6eb 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationController.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationController.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2022 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.scaleoutsoftware.digitaltwin.core; import java.time.Duration; +import java.util.Date; /** * The SimulationController interface is used to interact with the running DigitalTwin simulation. @@ -30,6 +31,18 @@ public interface SimulationController { */ Duration getSimulationTimeIncrement(); + /** + * + */ + + /** + *

+ * Retrieves the simulation start time. + *

+ * @return the simulation start time. + */ + Date getSimulationStartTime(); + /** *

* Delay simulation processing for this DigitalTwin instance for a duration of time. @@ -64,6 +77,20 @@ public interface SimulationController { */ SendingResult delay(Duration duration); + /** + *

+ * Delay simulation processing for this DigitalTwin instance, indefinitely. + *

+ * + *

+ * Simulation processing will be delayed until this instance is run with {@link SimulationController#runThisInstance()}. + *

+ * + * @return {@link SendingResult#Handled} if the delay was processed or {@link SendingResult#NotHandled} + * if the delay was not processed. + */ + SendingResult delayIndefinitely(); + /** *

* Asynchronously send a JSON serialized message to a DigitalTwin instance that will be processed by the DigitalTwin @@ -144,9 +171,20 @@ public interface SimulationController { */ SendingResult deleteThisInstance(); + /** + * Run this instance during this simulation step. The instance will be run using the models {@link SimulationProcessor#processModel(ProcessingContext, DigitalTwinBase, Date)} + * implementation. + * + * This will cause the simulation sub-system to run this instance regardless of the instances current + * {@link DigitalTwinBase#NextSimulationTime}. + */ + void runThisInstance(); + /** * Stop the simulation. * @return a {@link SimulationStatus#InstanceRequestedStop}. */ SimulationStatus stopSimulation(); + + } diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.java index e10e22c..a98d396 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2022 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -24,6 +24,11 @@ */ public abstract class SimulationProcessor implements Serializable { + /** + * Default constructor. + */ + public SimulationProcessor() {} + /** * Processes simulation events for a real-time digital twin. * @param context the processing context. @@ -33,4 +38,29 @@ public abstract class SimulationProcessor implements * {@link ProcessingResult#NoUpdate} to ignore the changes. */ public abstract ProcessingResult processModel(ProcessingContext context, T instance, Date epoch); + + /** + *

+ * Optional method that is called per-instance when a simulation is started. Default behavior is a no-op. + *

+ * + *

+ * onInitSimulation can be used when internal digital twin starting state is set outside the context of a digital twins init method and may be changed + * between simulation runs. + *

+ *
    + *
  • Set variables in global or shared data.
  • + *
  • Run a simulation.
  • + *
  • onInitSimulation is called (per-instance) and digital twin instances set internal state based on the values in shared data.
  • + *
  • Complete simulation and evaluate the result.
  • + *
+ * + * @param context The simulation init context. + * @param instance The digital twin instance. + * @param epoch the simulation start time. + * @return {@link ProcessingResult#UpdateDigitalTwin} or {@link ProcessingResult#NoUpdate}. Default behavior: {@link ProcessingResult#NoUpdate}. + */ + public ProcessingResult onInitSimulation(InitSimulationContext context, T instance, Date epoch) { + return ProcessingResult.NoUpdate; + } } diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.java index 68712dc..93f8ee4 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.java @@ -1,3 +1,18 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; /** diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.java index 40d53a5..852174e 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2022 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -53,7 +53,8 @@ private TimerActionResult(int val) { * Convert an ordinal into a {@link TimerActionResult}. * * 0 = {@link TimerActionResult#Success}, 1 = {@link TimerActionResult#FailedTooManyTimers}, - * 2 = {@link TimerActionResult#FailedNoSuchTimer}, 3 = {@link TimerActionResult#FailedInternalError} + * 2 = {@link TimerActionResult#FailedNoSuchTimer}, 3 = {@link TimerActionResult#FailedTimerAlreadyExists}, + * 4 = {@link TimerActionResult#FailedInternalError} * @param val the ordinal value. * @return the associated {@link TimerActionResult} or throws an IllegalArgumentException for an unexpected * ordinal value. @@ -67,6 +68,8 @@ public static TimerActionResult fromOrdinal(int val) { case 2: return FailedNoSuchTimer; case 3: + return FailedTimerAlreadyExists; + case 4: return FailedInternalError; default: throw new IllegalArgumentException("No known TimerActionResult from value: " + val); diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerHandler.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerHandler.java index 60b82aa..6380324 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerHandler.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerHandler.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2022 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.java index dbd0758..e9c151d 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2022 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerType.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerType.java index 41fee8c..66626e1 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerType.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerType.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2022 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/package-info.java b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/package-info.java index ee0bf8c..4ccf77f 100644 --- a/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/package-info.java +++ b/Core/src/main/java/com/scaleoutsoftware/digitaltwin/core/package-info.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2018 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Development/build.gradle b/Development/build.gradle index 9b4f594..238509d 100644 --- a/Development/build.gradle +++ b/Development/build.gradle @@ -4,7 +4,7 @@ plugins { } group 'com.scaleoutsoftware.digitaltwin' -version '3.0.6' +version '3.2.2' sourceCompatibility = JavaVersion.VERSION_12 @@ -18,10 +18,38 @@ repositories { dependencies { implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.20.0' testImplementation group: 'junit', name: 'junit', version: '4.12' - implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5' + implementation group: 'com.google.code.gson', name: 'gson', version: '2.11.0' // public build configuration - implementation group: 'com.scaleoutsoftware.digitaltwin', name: 'core', version: '3.0.4' + //implementation group: 'com.scaleoutsoftware.digitaltwin', name: 'core', version: '3.0.9' // local build configuration - //implementation fileTree(dir: '..\\Core\\build\\libs\\', include: '*.jar') + implementation fileTree(dir: '..\\Core\\build\\libs\\', include: '*.jar') } + +task createJavadocs(type: Javadoc) { + source = sourceSets.main.allJava + classpath = sourceSets.main.runtimeClasspath +} + +task javadocJar(type: Jar, dependsOn: createJavadocs) { + setArchiveClassifier('javadoc') + from javadoc.destinationDir +} + +task sourcesJar(type: Jar, dependsOn: classes) { + setArchiveClassifier('sources') + from sourceSets.main.allSource +} + +jar { + manifest { + attributes ('Implementation-Title': project.name, + 'Implementation-Version': project.version) + } +} + +task copyRuntime(type: GradleBuild) { + tasks = ['javadocJar', 'sourcesJar'] +} + +build.finalizedBy copyRuntime diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/Constants.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/Constants.java index c5f8044..5948de6 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/Constants.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/Constants.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,4 +17,83 @@ class Constants { public static final int MAX_TIMER_COUNT = 5; + /** + * + * Returns a hash that is suitable for inserting an object into a hash-based collection. + *

+ * ----------------------------------------------------------------------------- + * MurmurHash3 was written by Austin Appleby, and is placed in the public + * domain. The author hereby disclaims copyright to this source code. + * + * Note - The x86 and x64 versions do _not_ produce the same results, as the + * algorithms are optimized for their respective platforms. You can still + * compile and run any of them on any platform, but your performance with the + * non-native version will be less than optimal. + * Original code from: + * https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp + * ----------------------------------------------------------------------------- + * + * This implementation is tweaked to initialize with a hard-coded seed and to return a long instead of a + * 32-bit unsigned integer (since Java doesn't easily support unsigned integers). + * @param data The byte array to be hashed. + * @return Hash code for the array, with values ranging from 0 to 4,294,967,295. + */ + static long getHash(byte[] data) { + if(data == null) { + throw new IllegalArgumentException("Hash data was null."); + } + + final int seed = 947203; // Scaleout's implementation-specific seed. + final int c1 = 0xcc9e2d51; + final int c2 = 0x1b873593; + + int len = data.length; + int h1 = seed; + int roundedEnd = len & 0xfffffffc; // round down to 4 byte block + + for (int i = 0; i < roundedEnd; i += 4) { + // little endian load order + int k1 = (data[i] & 0xff) | ((data[i + 1] & 0xff) << 8) | ((data[i + 2] & 0xff) << 16) | (data[i + 3] << 24); + k1 *= c1; + k1 = (k1 << 15) | (k1 >>> 17); // ROTL32(k1,15); + k1 *= c2; + + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> 19); // ROTL32(h1,13); + h1 = h1 * 5 + 0xe6546b64; + } + + // tail (leftover bytes that didn't fit into a 4-byte block) + int k1 = 0; + + switch (len & 0x03) { + case 3: + k1 = (data[roundedEnd + 2] & 0xff) << 16; + // fallthrough + case 2: + k1 |= (data[roundedEnd + 1] & 0xff) << 8; + // fallthrough + case 1: + k1 |= (data[roundedEnd] & 0xff); + k1 *= c1; + k1 = (k1 << 15) | (k1 >>> 17); // ROTL32(k1,15); + k1 *= c2; + h1 ^= k1; + } + + // finalization + h1 ^= len; + + // fmix(h1); + h1 ^= h1 >>> 16; + h1 *= 0x85ebca6b; + h1 ^= h1 >>> 13; + h1 *= 0xc2b2ae35; + h1 ^= h1 >>> 16; + + // Other languages want to represent the hash as an unsigned int, but java doesn't easily have + // unsigned types. So we move the signed integer's bits into an "unsigned" long, which + // is big enough to hold all the positive values of an unsigned int. + return h1 & 0x00000000ffffffffL; + } } diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/LogMessage.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/LogMessage.java index 23e5775..4708e20 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/LogMessage.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/LogMessage.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/ProxyState.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/ProxyState.java index 9875074..0dd7e68 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/ProxyState.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/ProxyState.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEvent.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEvent.java index ebd133b..686936e 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEvent.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEvent.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -37,6 +37,10 @@ abstract class SimulationEvent implements Comparable { abstract void setProxyState(ProxyState newState); + abstract void handleResetNextSimulationTime(); + + abstract void simulationInit(Date simulationStartTime); + long getPriority() { return _priority; } @@ -49,12 +53,14 @@ String getId() { return _id; } + String getModel() {return _model;} + void setNextSimulationTime(long nextSimulationTime) { _nextSimulationTime = nextSimulationTime; handleResetNextSimulationTime(); } - abstract void handleResetNextSimulationTime(); + @Override public int compareTo(SimulationEvent other) { diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.java index ea490af..f917da6 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTimerImpl.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTimerImpl.java index 864b861..49f9b5d 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTimerImpl.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTimerImpl.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -55,4 +55,9 @@ void setProxyState(ProxyState newState) { @Override void handleResetNextSimulationTime() { } + + @Override + void simulationInit(Date simulationStartTime) { + + } } diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTwinImpl.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTwinImpl.java index e040d9f..27e4147 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTwinImpl.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTwinImpl.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,20 +15,24 @@ */ package com.scaleoutsoftware.digitaltwin.development; -import com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase; -import com.scaleoutsoftware.digitaltwin.core.ProcessingContext; -import com.scaleoutsoftware.digitaltwin.core.SimulationProcessor; +import com.scaleoutsoftware.digitaltwin.core.*; +import java.nio.charset.StandardCharsets; import java.util.Date; +import java.util.Objects; class SimulationEventTwinImpl extends SimulationEvent { SimulationProcessor _processor; TwinProxy _proxy; + SharedData _modelSharedData; + SharedData _globalSharedData; - SimulationEventTwinImpl(long priority, TwinProxy proxy, SimulationProcessor processor) { + SimulationEventTwinImpl(long priority, TwinProxy proxy, SimulationProcessor processor, SharedData modelSharedData, SharedData globalSharedData) { super(proxy.getInstance().Model, proxy.getInstance().Id, priority); - _proxy = proxy; - _processor = processor; + _proxy = proxy; + _processor = processor; + _modelSharedData = modelSharedData; + _globalSharedData = globalSharedData; } @Override @@ -63,4 +67,27 @@ void handleResetNextSimulationTime() { base.NextSimulationTime = _nextSimulationTime; _proxy.setInstance(base); } + + @Override + void simulationInit(Date simulationStartTime) { + InitSimulationContext context = new WorkbenchInitSimulationContext(_globalSharedData, _modelSharedData); + synchronized (_proxy) { + DigitalTwinBase base = _proxy.getInstance(); + _processor.onInitSimulation(context, base, simulationStartTime); + _proxy.setInstance(base); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SimulationEventTwinImpl that = (SimulationEventTwinImpl) o; + return this._proxy.getInstance().getId().compareTo(that._id) == 0 && this._proxy.getInstance().getModel().compareTo(that._model) == 0; + } + + @Override + public int hashCode() { + return (int)Constants.getHash(_id.getBytes(StandardCharsets.UTF_8)); + } } diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationScheduler.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationScheduler.java index 3b3566c..fa46b98 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationScheduler.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationScheduler.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -29,37 +29,40 @@ class SimulationScheduler { static AtomicInteger PROCESSED = new AtomicInteger(0); static AtomicInteger QUEUED = new AtomicInteger(0); static AtomicInteger SENT = new AtomicInteger(0); - private static final int NUM_SIMULATION_WORKERS = Runtime.getRuntime().availableProcessors(); - private final List _workers = new ArrayList<>(NUM_SIMULATION_WORKERS); - private final ExecutorService _simulationService = Executors.newFixedThreadPool(NUM_SIMULATION_WORKERS, new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r, "SimulationWorker"); - t.setName(t.getName()+"-"+t.getId()); - t.setDaemon(true); - return t; - } - }); + private final List _workers; + private final ExecutorService _simulationService; private final String _modelName; private final SimulationProcessor _simulationProcessor; private final Logger _logger = LogManager.getLogger(SimulationScheduler.class); private long _curSimulationTime; + private Date _simulationStartTime; private boolean _isActive; public SimulationScheduler(String modelName, Class digitalTwinClass, SimulationProcessor modelProcessor, - TwinExecutionEngine executor) { + TwinExecutionEngine executor, + int numWorkers) { _modelName = modelName; _simulationProcessor = modelProcessor; - for(int i = 0; i < NUM_SIMULATION_WORKERS; i++) { - _workers.add(new SimulationWorker(i, _modelName, _simulationProcessor, digitalTwinClass, executor)); + _workers = new ArrayList<>(numWorkers); + _simulationService = Executors.newFixedThreadPool(numWorkers, new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r, "SimulationWorker"); + t.setName(t.getName()+"-"+t.getId()); + t.setDaemon(true); + return t; + } + }); + for(int i = 0; i < numWorkers; i++) { + _workers.add(new SimulationWorker(i, _modelName, _simulationProcessor, digitalTwinClass, executor, this)); } } - // -------------- public methods ---------------- - public SimulationStep runSimulation(SimulationStepArgs runSimulationEventArgs) { + // -------------- package private methods ---------------- + SimulationStep runSimulation(SimulationStepArgs runSimulationEventArgs) { _logger.info("Received run simulation event with args: " + runSimulationEventArgs.getCurSimulationTime() + " iterationSize: " + runSimulationEventArgs.getIterationSize() + " flags: " + runSimulationEventArgs.getSimulationFlags() ); long current = System.currentTimeMillis(); SimulationStep ret; @@ -71,12 +74,17 @@ public SimulationStep runSimulation(SimulationStepArgs runSimulationEventArgs) { worker.shutdown(); } return new SimulationStep(SimulationStatus.UserRequested,_curSimulationTime); + } if(runSimulationEventArgs.getSimulationFlags() == WorkbenchSimulationFlags.Start) { + _logger.info("Starting simulation; initializing instances."); + for(SimulationWorker worker : _workers) { + worker.initSimulation(new Date(runSimulationEventArgs.getCurSimulationTime())); + } + return new SimulationStep(SimulationStatus.Running,_curSimulationTime); } else { ret = runSimulationStep(runSimulationEventArgs); } _logger.info(String.format("runSim complete in %s ms... returning next: %s", (System.currentTimeMillis()-current), ret)); - _logger.info(String.format("Queued: %s Processed: %s Sent: %s", QUEUED.getAndSet(0), PROCESSED.getAndSet(0), SENT.getAndSet(0))); return ret; } @@ -91,6 +99,16 @@ void setStatus(boolean active) { _isActive = active; } + Date getSimulationStartTime() { + return _simulationStartTime; + } + + void setSimulationStartTime(Date simulationStartTime) { + _simulationStartTime = simulationStartTime; + } + + + // -------------- private methods ---------------- private SimulationStep runSimulationStep(SimulationStepArgs args) { long currentTimeMs = System.currentTimeMillis(); @@ -146,87 +164,14 @@ void stopTimer(String modelName, String id, String timerName) { worker.stopTimer(modelName, id, timerName); } - private int findSlotId(String id) { - return (int)((getHash(id.getBytes(StandardCharsets.UTF_8))) % (long)NUM_SIMULATION_WORKERS); + void runThisInstance(String model, String id) throws WorkbenchException { + SimulationWorker worker = _workers.get(findSlotId(id)); + worker.runThisInstance(model, id); } - /** - * - * Returns a hash that is suitable for inserting an object into a hash-based collection. - *

- * ----------------------------------------------------------------------------- - * MurmurHash3 was written by Austin Appleby, and is placed in the public - * domain. The author hereby disclaims copyright to this source code. - * - * Note - The x86 and x64 versions do _not_ produce the same results, as the - * algorithms are optimized for their respective platforms. You can still - * compile and run any of them on any platform, but your performance with the - * non-native version will be less than optimal. - * Original code from: - * https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp - * ----------------------------------------------------------------------------- - * - * This implementation is tweaked to initialize with a hard-coded seed and to return a long instead of a - * 32-bit unsigned integer (since Java doesn't easily support unsigned integers). - * @param data The byte array to be hashed. - * @return Hash code for the array, with values ranging from 0 to 4,294,967,295. - */ - static long getHash(byte[] data) { - if(data == null) { - throw new IllegalArgumentException("Hash data was null."); - } - - final int seed = 947203; // Scaleout's implementation-specific seed. - final int c1 = 0xcc9e2d51; - final int c2 = 0x1b873593; - - int len = data.length; - int h1 = seed; - int roundedEnd = len & 0xfffffffc; // round down to 4 byte block - - for (int i = 0; i < roundedEnd; i += 4) { - // little endian load order - int k1 = (data[i] & 0xff) | ((data[i + 1] & 0xff) << 8) | ((data[i + 2] & 0xff) << 16) | (data[i + 3] << 24); - k1 *= c1; - k1 = (k1 << 15) | (k1 >>> 17); // ROTL32(k1,15); - k1 *= c2; - - h1 ^= k1; - h1 = (h1 << 13) | (h1 >>> 19); // ROTL32(h1,13); - h1 = h1 * 5 + 0xe6546b64; - } - - // tail (leftover bytes that didn't fit into a 4-byte block) - int k1 = 0; - - switch (len & 0x03) { - case 3: - k1 = (data[roundedEnd + 2] & 0xff) << 16; - // fallthrough - case 2: - k1 |= (data[roundedEnd + 1] & 0xff) << 8; - // fallthrough - case 1: - k1 |= (data[roundedEnd] & 0xff); - k1 *= c1; - k1 = (k1 << 15) | (k1 >>> 17); // ROTL32(k1,15); - k1 *= c2; - h1 ^= k1; - } - - // finalization - h1 ^= len; + private int findSlotId(String id) { + return (int)((Constants.getHash(id.getBytes(StandardCharsets.UTF_8))) % (long)_workers.size()); + } - // fmix(h1); - h1 ^= h1 >>> 16; - h1 *= 0x85ebca6b; - h1 ^= h1 >>> 13; - h1 *= 0xc2b2ae35; - h1 ^= h1 >>> 16; - // Other languages want to represent the hash as an unsigned int, but java doesn't easily have - // unsigned types. So we move the signed integer's bits into an "unsigned" long, which - // is big enough to hold all the positive values of an unsigned int. - return h1 & 0x00000000ffffffffL; - } } diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStep.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStep.java index 3913423..c2a6dba 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStep.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStep.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStepArgs.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStepArgs.java index cfe6774..c65ad79 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStepArgs.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStepArgs.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationTime.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationTime.java index 021eaa5..e09c0e7 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationTime.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationTime.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationWorker.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationWorker.java index ce759fd..ebaa891 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationWorker.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationWorker.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,28 +23,34 @@ import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Predicate; class SimulationWorker implements Callable { private final Logger _logger = LogManager.getLogger(SimulationWorker.class); private final PriorityQueue _timeOrderedQueue = new PriorityQueue<>(); private final ConcurrentHashMap _timers = new ConcurrentHashMap<>(); + private final ConcurrentHashMap _events = new ConcurrentHashMap<>(); private final int _slotId; private final String _modelName; private final SimulationProcessor _simulationProcessor; private final TwinExecutionEngine _twinExecutionEngine; + private final SimulationScheduler _simulationScheduler; private long _curSimulationTime; private long _simulationInterval; private long _nextSimulationTime; + private boolean _running; public SimulationWorker(int slotId, String model, SimulationProcessor modelProcessor, Class digitalTwinClass, - TwinExecutionEngine engine) { + TwinExecutionEngine engine, + SimulationScheduler scheduler) { _slotId = slotId; _modelName = model; _simulationProcessor = modelProcessor; _twinExecutionEngine = engine; + _simulationScheduler = scheduler; } public void reset(SimulationStepArgs runSimulationEventArgs) { @@ -55,43 +61,98 @@ public void reset(SimulationStepArgs runSimulationEventArgs) { public void shutdown() { _timeOrderedQueue.clear(); + _events.clear(); + _timers.clear(); } public void addTwinToQueue(TwinProxy proxy) { - SimulationEvent event = new SimulationEventTwinImpl(0, proxy, _simulationProcessor); + SimulationEvent event = new SimulationEventTwinImpl(_curSimulationTime, proxy, _simulationProcessor, new WorkbenchSharedData(_twinExecutionEngine.getGlobalSharedData()), new WorkbenchSharedData(_twinExecutionEngine.getModelData(_modelName))); _timeOrderedQueue.add(event); + _events.put(String.format("%s%s",event.getModel(),event.getId()), event); + } + + public void addTwinToQueue(SimulationEvent event) { + _timeOrderedQueue.add(event); + _events.put(String.format("%s%s",event.getModel(),event.getId()), event); } public void addTimerToQueue(TwinProxy proxy, String modelName, String id, String timerName, TimerType type, Duration interval, TimerHandler handler) { SimulationEvent event = new SimulationEventTimerImpl(modelName, id, interval.toMillis(), timerName, proxy, handler); _timers.put(timerName, event); _timeOrderedQueue.add(event); + _events.put(String.format("%s%s",event.getModel(),event.getId()), event); } public void stopTimer(String model, String id, String timerName) { SimulationEvent event = _timers.remove(String.format("%s%s%s",model, id,timerName)); event.setProxyState(ProxyState.Removed); + _events.remove(String.format("%s%s",event.getModel(),event.getId())); + } + + void initSimulation(Date startTime) { + for(SimulationEvent event : _events.values()) { + event.simulationInit(startTime); + } + } + + public void runThisInstance(String model, String id) throws WorkbenchException { + SimulationEvent event = _events.remove(String.format("%s%s",model,id)); + if(event == null) { + TwinProxy proxy = _twinExecutionEngine.getTwinProxy(model, id); + event = new SimulationEventTwinImpl(_curSimulationTime, proxy, _simulationProcessor, new WorkbenchSharedData(_twinExecutionEngine.getGlobalSharedData()), new WorkbenchSharedData(_twinExecutionEngine.getModelData(_modelName))); + } else { + _timeOrderedQueue.remove(event); + } + WorkbenchSimulationController simulationController = new WorkbenchSimulationController(_twinExecutionEngine, _simulationScheduler); + WorkbenchProcessingContext processingContext = new WorkbenchProcessingContext(_twinExecutionEngine, simulationController); + processingContext.reset(model, id, null); + Date date = new Date(); + date.setTime(_curSimulationTime); + event.processSimulationEvent(processingContext, date); + if(simulationController.delayRequested()) { + long delay = simulationController.getRequestedDelay(); + if(delay == 0x0000e677d21fdbffL) { + event.setPriority(simulationController.getRequestedDelay()); + event.setNextSimulationTime(simulationController.getRequestedDelay()); + } else if (delay == 0L) { + event.setPriority(_curSimulationTime); + event.setNextSimulationTime(_curSimulationTime); + } else { + event.setPriority(_curSimulationTime + simulationController.getRequestedDelay()); + event.setNextSimulationTime(_curSimulationTime + simulationController.getRequestedDelay()); + } + } else { + event.setPriority(_curSimulationTime + _simulationInterval); + event.setNextSimulationTime(_curSimulationTime + _simulationInterval); + } + _events.put(String.format("%s%s",model,id), event); + _timeOrderedQueue.add(event); } @Override public SimulationStep call() throws Exception { + synchronized (this) { + _running = true; + } SimulationTime simulationTime = new SimulationTime(_curSimulationTime, _simulationInterval); long lowestNextSimulationTime = Long.MAX_VALUE; long nextQueueTm = Long.MAX_VALUE; boolean keepProcessing = true; boolean delayed = false; + boolean addToBuffer = true; List buffer = new LinkedList<>(); - WorkbenchSimulationController simulationController = new WorkbenchSimulationController(_twinExecutionEngine); + WorkbenchSimulationController simulationController = new WorkbenchSimulationController(_twinExecutionEngine, _simulationScheduler); WorkbenchProcessingContext processingContext = new WorkbenchProcessingContext(_twinExecutionEngine, simulationController); Date currentTime = new Date(); currentTime.setTime(_curSimulationTime); int processed = 0; do { + addToBuffer = true; SimulationEvent next = _timeOrderedQueue.poll(); if(next != null) { if(next.getProxyState() == ProxyState.Active) { processed++; - nextQueueTm = next.getPriority(); + nextQueueTm = next.getPriority(); if(next.getPriority() <= simulationTime.getCurrentSimulationTime()) { simulationController.reset(_modelName, next.getId()); processingContext.reset(_modelName, next.getId(), null); @@ -102,10 +163,20 @@ public SimulationStep call() throws Exception { _logger.error("simulation processor threw an exception.", e); result = ProcessingResult.NoUpdate; } - if(simulationController.getRequestedDelay() != Long.MIN_VALUE && simulationController.getRequestedDelay() != 0) { + if(simulationController.delayRequested()) { delayed = true; - next.setPriority(simulationTime.getCurrentSimulationTime() + simulationController.getRequestedDelay()); - next.setNextSimulationTime(simulationTime.getCurrentSimulationTime() + simulationController.getRequestedDelay()); + long delay = simulationController.getRequestedDelay(); + if(delay == 0x0000e677d21fdbffL) { + next.setPriority(simulationController.getRequestedDelay()); + next.setNextSimulationTime(simulationController.getRequestedDelay()); + } else if (delay == 0L) { + next.setPriority(_curSimulationTime); + next.setNextSimulationTime(_curSimulationTime); + addToBuffer = false; + } else { + next.setPriority(simulationTime.getCurrentSimulationTime() + simulationController.getRequestedDelay()); + next.setNextSimulationTime(simulationTime.getCurrentSimulationTime() + simulationController.getRequestedDelay()); + } } else { next.setPriority(simulationTime.getNextSimulationTime()); next.setNextSimulationTime(simulationTime.getNextSimulationTime()); @@ -116,15 +187,25 @@ public SimulationStep call() throws Exception { if(simulationController.deleted()) { result = ProcessingResult.NoUpdate; } - + if(!simulationController.enqueue()) { + // the user called "runThisInstance" -- the work item has already been re-enqueued for the + // current time slice. + addToBuffer = false; + } } else { + synchronized (this) { + _running = false; + } keepProcessing = false; } - if(!simulationController.deleted()) { + if(!simulationController.deleted() && addToBuffer) { buffer.add(next); } } } else { + synchronized (this) { + _running = false; + } keepProcessing = false; nextQueueTm = Long.MAX_VALUE; } diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinExecutionEngine.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinExecutionEngine.java index 7cf4952..bd34eca 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinExecutionEngine.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinExecutionEngine.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -34,6 +34,8 @@ class TwinExecutionEngine implements Closeable { private ConcurrentHashMap> _messageProcessorValueTypes; private ConcurrentHashMap> _modelInstances; private ConcurrentHashMap> _alertProviders; + private ConcurrentHashMap> _modelsSharedData; + private HashMap _globalSharedData; private Workbench _workbench; private ConcurrentHashMap _simulationSchedulers; private ConcurrentHashMap _realTimeTimers; @@ -52,6 +54,8 @@ void init( ) { _simulationProcessors = new ConcurrentHashMap<>(); _messageProcessorValueTypes = new ConcurrentHashMap<>(); _modelInstances = new ConcurrentHashMap<>(); + _modelsSharedData = new ConcurrentHashMap<>(); + _globalSharedData = new HashMap<>(); _alertProviders = new ConcurrentHashMap<>(); _simulationSchedulers = new ConcurrentHashMap<>(); _realTimeTimers = new ConcurrentHashMap<>(); @@ -65,13 +69,13 @@ void addDigitalTwin(String digitalTwinModelName, MessageProcessor digitalTwinMes _messageProcessorValueTypes.put(digitalTwinModelName, messageClass); } - void addDigitalTwin(String digitalTwinModelName, MessageProcessor digitalTwinMessageProcessor, SimulationProcessor simulationProcessor, Class dtType, Class messageClass) { + void addDigitalTwin(String digitalTwinModelName, MessageProcessor digitalTwinMessageProcessor, SimulationProcessor simulationProcessor, Class dtType, Class messageClass, int numWorkers) { _modelNames.add(digitalTwinModelName); _digitalTwins.put(digitalTwinModelName, dtType); _messageProcessors.put(digitalTwinModelName, digitalTwinMessageProcessor); _simulationProcessors.put(digitalTwinModelName, simulationProcessor); _messageProcessorValueTypes.put(digitalTwinModelName, messageClass); - _simulationSchedulers.put(digitalTwinModelName, new SimulationScheduler(digitalTwinModelName, dtType, simulationProcessor, this)); + _simulationSchedulers.put(digitalTwinModelName, new SimulationScheduler(digitalTwinModelName, dtType, simulationProcessor, this, numWorkers)); } void addTimer(String modelName, String id, String timerName, TimerType type, Duration interval, TimerHandler handler) { @@ -159,6 +163,16 @@ DigitalTwinBase getTwinInstance(String model, String id) { return ret; } + TwinProxy getTwinProxy(String model, String id) { + TwinProxy proxy = null; + ConcurrentHashMap instances = _modelInstances.get(model); + if(instances != null) { + proxy = instances.get(id); + return proxy; + } + return proxy; + } + String generateModelSchema(String model) throws WorkbenchException { if(_digitalTwins.get(model) != null) { ModelSchema schema; @@ -214,12 +228,12 @@ SendingResult sendToSource(String source, String model, String id, String msg) t } SendingResult sendToSource(String source, String model, String id, List jsonSerializableMessage) throws WorkbenchException { - if(_modelNames.contains(source)) { + if (_modelNames.contains(source)) { run(source, id, null, jsonSerializableMessage); return SendingResult.Handled; } else { String msg = _gson.toJson(jsonSerializableMessage); - ConcurrentHashMap> messagesByModel = _workbench.SOURCE_MESSAGES.getOrDefault(model, new ConcurrentHashMap>()); + ConcurrentHashMap> messagesByModel = _workbench.SOURCE_MESSAGES.getOrDefault(model, new ConcurrentHashMap>()); List messages = messagesByModel.getOrDefault(id, new LinkedList<>()); messages.add(msg); messagesByModel.put(id, messages); @@ -241,6 +255,18 @@ SimulationStep runSimulationStep(SimulationStepArgs args) { return status; } + HashMap getModelData(String model) { + HashMap sharedData = _modelsSharedData.get(model); + if(sharedData == null) sharedData = new HashMap<>(); + _modelsSharedData.put(model, sharedData); + return sharedData; + } + + HashMap getGlobalSharedData() { + return _globalSharedData; + } + + public void logMessage(String model, LogMessage message) { ConcurrentLinkedQueue prev = _workbench.LOGGED_MESSAGES.get(model); if(prev == null) { @@ -315,7 +341,15 @@ ProcessingResult run(String model, String id, String source, String serializedLi instance = proxy.getInstance(); } MessageProcessor mp = _messageProcessors.get(model); - WorkbenchProcessingContext context = new WorkbenchProcessingContext(_workbench._twinExecutionEngine); + HashMap sharedData = _modelsSharedData.get(model); + if(sharedData == null) sharedData = new HashMap<>(); + _modelsSharedData.put(model, sharedData); + SimulationController simulationController = null; + SimulationScheduler scheduler = _simulationSchedulers.get(model); + if(scheduler != null) { + simulationController = new WorkbenchSimulationController(this, scheduler); + } + WorkbenchProcessingContext context = new WorkbenchProcessingContext(_workbench._twinExecutionEngine, sharedData, _globalSharedData, simulationController); context.reset(model, id, source, instance); ProcessingResult res = mp.processMessages(context, instance, new WorkbenchMessageListFactory(serializedList, _messageProcessorValueTypes.get(model))); if(context.forceSave()) res = ProcessingResult.UpdateDigitalTwin; @@ -360,8 +394,19 @@ ProcessingResult run(String model, String id, String source, List messag instance = proxy.getInstance(); } MessageProcessor mp = _messageProcessors.get(model); - WorkbenchProcessingContext context = new WorkbenchProcessingContext(_workbench._twinExecutionEngine); + HashMap sharedData = _modelsSharedData.get(model); + if(sharedData == null) sharedData = new HashMap<>(); + _modelsSharedData.put(model, sharedData); + WorkbenchSimulationController simulationController = null; + SimulationScheduler scheduler = _simulationSchedulers.get(model); + if(scheduler != null) { + simulationController = new WorkbenchSimulationController(this, scheduler); + } + WorkbenchProcessingContext context = new WorkbenchProcessingContext(_workbench._twinExecutionEngine, sharedData, _globalSharedData, simulationController); context.reset(model, id, source, instance); + if(simulationController != null) { + simulationController.reset(model, id); + } ProcessingResult res = mp.processMessages(context, instance, new WorkbenchMessageListFactory(messages, _messageProcessorValueTypes.get(model))); if(context.forceSave()) res = ProcessingResult.UpdateDigitalTwin; switch(res) { diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinProxy.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinProxy.java index 0839071..4811ab7 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinProxy.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinProxy.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/Workbench.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/Workbench.java index 3448b55..0cc6a07 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/Workbench.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/Workbench.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -259,6 +259,7 @@ public class Workbench implements AutoCloseable { private long _now, _next; private SimulationStep _result = null; private boolean _simulationStarted = false; + private int _numWorkers = Runtime.getRuntime().availableProcessors(); /** @@ -268,6 +269,16 @@ public Workbench() { _twinExecutionEngine = new TwinExecutionEngine(this); } + /** + * Instantiate the workbench. + * @param numSimulationWorkers the number of simulation workers to use. Default is {@link Runtime#availableProcessors()}. + */ + public Workbench(int numSimulationWorkers) { + _twinExecutionEngine = new TwinExecutionEngine(this); + if(_numWorkers <= 0) throw new IllegalArgumentException("numSimulationWorkers must be greater-than 0."); + _numWorkers = numSimulationWorkers; + } + /** * Adds a real-time digital twin model to the workbench. @@ -311,7 +322,7 @@ public void addSimulationModel(String modelName, M } validate(digitalTwinMessageProcessor, dtType); - _twinExecutionEngine.addDigitalTwin(modelName, digitalTwinMessageProcessor, simulationProcessor, dtType, messageClass); + _twinExecutionEngine.addDigitalTwin(modelName, digitalTwinMessageProcessor, simulationProcessor, dtType, messageClass, _numWorkers); } /** @@ -363,6 +374,8 @@ public SimulationStep runSimulation(long startTime, long endTime, double speedup SimulationStep ret, result = null; SimulationStepArgs args; long now, curTime, start, end, deltaTm, delta, wait, numItv; + args = new SimulationStepArgs(startTime, interval, WorkbenchSimulationFlags.Start); + _twinExecutionEngine.runSimulationStep(args); SimulationStatus status = SimulationStatus.Running; now = curTime = startTime; while(status == SimulationStatus.Running && @@ -374,7 +387,7 @@ public SimulationStep runSimulation(long startTime, long endTime, double speedup end = System.currentTimeMillis(); delta = result.getTime() - curTime; numItv = delta/interval; - numItv = delta%numItv != 0 ? numItv+1 : numItv; + numItv = numItv > 0 ? delta%numItv != 0 ? numItv+1 : numItv : numItv; deltaTm = end-start; wait = deltaTm >= interval ? 0L : (long)((interval-deltaTm)/speedup); status = result.getStatus(); @@ -437,7 +450,7 @@ public SimulationStep step() throws WorkbenchException { _result = _twinExecutionEngine.runSimulationStep(args); delta = _result.getTime() - _curTime; numItv = delta/_interval; - numItv = delta%numItv != 0 ? numItv+1 : numItv; + numItv = numItv > 0 ? delta%numItv != 0 ? numItv+1 : numItv : numItv+1; _curTime = _curTime+(numItv*_interval); _next = _curTime; return new SimulationStep(_result.getStatus(), _now); @@ -537,6 +550,29 @@ public List getAlertMessages(String model, String alertProvider) t return Arrays.asList(perModelMessages.get(alertProvider).toArray(new AlertMessage[0])); } + /** + * Retrieve the {@link SharedData} for a model. + * @param model the model name. + * @return the {@link SharedData} for a model. + * @throws WorkbenchException if an exception occurs while creating the working shared data. + */ + public SharedData getSharedModelData(String model) throws WorkbenchException { + if(_twinExecutionEngine.hasModel(model)) { + return new WorkbenchSharedData(_twinExecutionEngine.getModelData(model)); + } else { + throw new WorkbenchException("Workbench does not contain model " + model); + } + } + + /** + * Retrieve the global {@link SharedData}. + * @return the global {@link SharedData} of this workbench. + * @throws WorkbenchException if an exception occurs while creating the working shared data. + */ + public SharedData getSharedGlobalData() throws WorkbenchException { + return new WorkbenchSharedData(_twinExecutionEngine.getGlobalSharedData()); + } + /** * Generates a ModelSchema for the defined model * @@ -707,6 +743,25 @@ static void validate(MessageProcessor digit } } + /** + * Add a key/value pair to {@link SharedData} for a model. + * @param modelName the model name. + * @param key the key. + * @param value the value. + */ + public void addSharedModelData(String modelName, String key, byte[] value) { + _twinExecutionEngine.getModelData(modelName).put(key, value); + } + + /** + * Add a key/value pair to the global {@link SharedData}. + * @param key the key. + * @param value the value. + */ + public void addGlobalModelData(String key, byte[] value) { + _twinExecutionEngine.getGlobalSharedData().put(key, value); + } + @Override public void close() throws Exception { _twinExecutionEngine.close(); diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.java index 27beb77..b983f6c 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchInitContext.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchInitContext.java index 29e6a48..8cc55b0 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchInitContext.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchInitContext.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -37,6 +37,16 @@ public TimerActionResult startTimer(String timerName return WorkbenchTimerService.startTimer(_twinExecutionEngine, (T)_instance, _model, _id, timerName, duration, timerType, timerHandler); } + @Override + public SharedData getSharedModelData() { + return new WorkbenchSharedData(_twinExecutionEngine.getModelData(_model)); + } + + @Override + public SharedData getSharedGlobalData() { + return new WorkbenchSharedData(_twinExecutionEngine.getGlobalSharedData()); + } + @Override public String getId() { return _id; diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchInitSimulationContext.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchInitSimulationContext.java new file mode 100644 index 0000000..3128ad8 --- /dev/null +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchInitSimulationContext.java @@ -0,0 +1,39 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.InitSimulationContext; +import com.scaleoutsoftware.digitaltwin.core.SharedData; + +class WorkbenchInitSimulationContext implements InitSimulationContext { + SharedData _globalData; + SharedData _modelData; + + WorkbenchInitSimulationContext(SharedData globalData, SharedData modelData) { + _globalData = globalData; + _modelData = modelData; + } + + @Override + public SharedData getSharedModelData() { + return _modelData; + } + + @Override + public SharedData getSharedGlobalData() { + return _globalData; + } +} diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchMessageListFactory.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchMessageListFactory.java index 9bedd7d..43b0a06 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchMessageListFactory.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchMessageListFactory.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchProcessingContext.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchProcessingContext.java index f08c7fc..2846a09 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchProcessingContext.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchProcessingContext.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -31,11 +31,15 @@ class WorkbenchProcessingContext extends ProcessingContext { String _source; DigitalTwinBase _twinInstance; SimulationController _controller; + HashMap _modelData; + HashMap _globalData; boolean _forceSave; - WorkbenchProcessingContext(TwinExecutionEngine twinExecutionEngine) { + WorkbenchProcessingContext(TwinExecutionEngine twinExecutionEngine, HashMap modelSharedData, HashMap globalSharedData, SimulationController simulationController) { _twinExecutionEngine = twinExecutionEngine; - _controller = null; + _controller = simulationController; + _modelData = modelSharedData; + _globalData = globalSharedData; } WorkbenchProcessingContext(TwinExecutionEngine twinExecutionEngine, SimulationController controller) { @@ -49,6 +53,8 @@ void reset(String model, String id, String source, DigitalTwinBase instance) { _twinInstance = instance; _forceSave = false; _source = source; + _modelData = _twinExecutionEngine.getModelData(model); + _globalData = _twinExecutionEngine.getGlobalSharedData(); } void reset(String model, String id, String source) { @@ -56,6 +62,8 @@ void reset(String model, String id, String source) { _id = id; _forceSave = false; _source = source; + _modelData = _twinExecutionEngine.getModelData(model); + _globalData = _twinExecutionEngine.getGlobalSharedData(); } void resetInstance(DigitalTwinBase instance) { @@ -106,8 +114,14 @@ public SendingResult sendToDigitalTwin(String model, String id, byte[] bytes) { public SendingResult sendToDigitalTwin(String model, String id, Object jsonSerializableMessage) { try { if(_twinExecutionEngine.getTwinInstance(model, id) != null) { - List jsonSerializableMessages = new LinkedList<>(); - jsonSerializableMessages.add(jsonSerializableMessage); + List jsonSerializableMessages; + if(jsonSerializableMessage instanceof List) { + jsonSerializableMessages = (List)jsonSerializableMessage; + } else { + jsonSerializableMessages = new LinkedList<>(); + jsonSerializableMessages.add(jsonSerializableMessage); + } + return _twinExecutionEngine.run(model, id, null, jsonSerializableMessages) != null ? SendingResult.Handled : SendingResult.NotHandled; } else { return SendingResult.NotHandled; @@ -210,4 +224,14 @@ public Date getCurrentTime() { public SimulationController getSimulationController() { return _controller; } + + @Override + public SharedData getSharedModelData() { + return new WorkbenchSharedData(_modelData); + } + + @Override + public SharedData getSharedGlobalData() { + return new WorkbenchSharedData(_globalData); + } } diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSharedData.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSharedData.java new file mode 100644 index 0000000..0712e9a --- /dev/null +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSharedData.java @@ -0,0 +1,112 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus; +import com.scaleoutsoftware.digitaltwin.core.CacheResult; +import com.scaleoutsoftware.digitaltwin.core.SharedData; + +import java.util.HashMap; + +class WorkbenchSharedData implements SharedData { + private final HashMap data; + + public WorkbenchSharedData(HashMap shared) { + data = shared; + } + @Override + public CacheResult get(String s) { + return new CacheResult() { + @Override + public String getKey() { + return s; + } + + @Override + public byte[] getValue() { + return data.getOrDefault(s, null); + } + + @Override + public CacheOperationStatus getStatus() { + return data.containsKey(s) ? CacheOperationStatus.ObjectRetrieved : CacheOperationStatus.ObjectDoesNotExist; + } + }; + } + + @Override + public CacheResult put(String s, byte[] bytes) { + data.put(s, bytes); + return new CacheResult() { + @Override + public String getKey() { + return s; + } + + @Override + public byte[] getValue() { + return bytes; + } + + @Override + public CacheOperationStatus getStatus() { + return CacheOperationStatus.ObjectPut; + } + }; + } + + @Override + public CacheResult remove(String s) { + byte[] v = data.remove(s); + return new CacheResult() { + @Override + public String getKey() { + return s; + } + + @Override + public byte[] getValue() { + return v; + } + + @Override + public CacheOperationStatus getStatus() { + return v == null ? CacheOperationStatus.ObjectDoesNotExist : CacheOperationStatus.ObjectRemoved; + } + }; + } + + @Override + public CacheResult clear() { + data.clear(); + return new CacheResult() { + @Override + public String getKey() { + return null; + } + + @Override + public byte[] getValue() { + return null; + } + + @Override + public CacheOperationStatus getStatus() { + return CacheOperationStatus.CacheCleared; + } + }; + } +} diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationController.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationController.java index 1a5e54b..611d7af 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationController.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationController.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,19 +19,24 @@ import java.nio.charset.StandardCharsets; import java.time.Duration; +import java.util.Date; import java.util.LinkedList; import java.util.List; class WorkbenchSimulationController implements SimulationController { TwinExecutionEngine _engine; + SimulationScheduler _scheduler; private long _requestedDelay; + private boolean _delayRequested; private boolean _deleted; + private boolean _enqueue; private String _modelName; private String _id; private SimulationStatus _simulationStatus = SimulationStatus.Running; - public WorkbenchSimulationController(TwinExecutionEngine engine) { - _engine = engine; + public WorkbenchSimulationController(TwinExecutionEngine engine, SimulationScheduler scheduler) { + _engine = engine; + _scheduler = scheduler; } @Override @@ -39,9 +44,22 @@ public Duration getSimulationTimeIncrement() { return null; } + @Override + public Date getSimulationStartTime() { + return _scheduler.getSimulationStartTime(); + } + @Override public SendingResult delay(Duration duration) { _requestedDelay = duration.toMillis(); + _delayRequested = true; + return SendingResult.Handled; + } + + @Override + public SendingResult delayIndefinitely() { + _requestedDelay = 0x0000e677d21fdbffL; + _delayRequested = true; return SendingResult.Handled; } @@ -116,17 +134,34 @@ public SendingResult deleteThisInstance() { return SendingResult.Handled; } + @Override + public void runThisInstance() { + try { + _scheduler.runThisInstance(_modelName, _id); + _enqueue = false; + } catch (WorkbenchException e) { + throw new RuntimeException(e); + } + + } + @Override public SimulationStatus stopSimulation() { _simulationStatus = SimulationStatus.InstanceRequestedStop; return _simulationStatus; } + public boolean delayRequested() { + return _delayRequested; + } + public void reset(String modelName, String id) { _modelName = modelName; _id = id; _requestedDelay = Long.MIN_VALUE; + _delayRequested = false; _deleted = false; + _enqueue = true; } public long getRequestedDelay() { @@ -137,6 +172,10 @@ public boolean deleted() { return _deleted; } + public boolean enqueue() { + return _enqueue; + } + public SimulationStatus getSimulationStatus() { return _simulationStatus; } diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationFlags.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationFlags.java index 8910290..4e7acff 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationFlags.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationFlags.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package com.scaleoutsoftware.digitaltwin.development; enum WorkbenchSimulationFlags { + // Start the simulation + Start, // Run the simulation Run, // Stop the simulation diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerService.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerService.java index 1c99c4f..c5911a7 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerService.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerService.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerTask.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerTask.java index def85a3..6118b9e 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerTask.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerTask.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/package-info.java b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/package-info.java index 5738555..c8df4a2 100644 --- a/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/package-info.java +++ b/Development/src/main/java/com/scaleoutsoftware/digitaltwin/development/package-info.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Development/src/test/java/com/scaleoutsoftware/digitaltwin/development/TestWorkbench.java b/Development/src/test/java/com/scaleoutsoftware/digitaltwin/development/TestWorkbench.java index 1be1f3c..4864388 100644 --- a/Development/src/test/java/com/scaleoutsoftware/digitaltwin/development/TestWorkbench.java +++ b/Development/src/test/java/com/scaleoutsoftware/digitaltwin/development/TestWorkbench.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2023 by ScaleOut Software, Inc. + Copyright (c) 2025 by ScaleOut Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -93,6 +93,42 @@ public ProcessingResult onTimedMessage(String s, DigitalTwinBase digitalTwinBase case "StopTimer": processingContext.stopTimer("timer"); break; + case "SharedData": + SharedData sharedData = processingContext.getSharedModelData(); + CacheResult result = sharedData.put("Hello", "Some string...".getBytes(StandardCharsets.UTF_8)); + if(result.getStatus() == CacheOperationStatus.ObjectPut) { + System.out.println("Successfully stored object in model storage."); + } + result = sharedData.get("Hello"); + if(result.getStatus() == CacheOperationStatus.ObjectRetrieved) { + System.out.println("Successfully retrieved " + new String(result.getValue(), StandardCharsets.UTF_8) + " from model storage."); + } + result = sharedData.remove("Hello"); + if(result.getStatus() == CacheOperationStatus.ObjectRemoved) { + System.out.println("Successfully removed " + new String(result.getValue(), StandardCharsets.UTF_8) + " from model storage."); + } + result = sharedData.put("modelTest", "assert".getBytes(StandardCharsets.UTF_8)); + sharedData = processingContext.getSharedGlobalData(); + result = sharedData.put("Hello", "Some string...".getBytes(StandardCharsets.UTF_8)); + if(result.getStatus() == CacheOperationStatus.ObjectPut) { + System.out.println("Successfully stored object in global storage."); + } + result = sharedData.get("Hello"); + if(result.getStatus() == CacheOperationStatus.ObjectRetrieved) { + System.out.println("Successfully retrieved " + new String(result.getValue(), StandardCharsets.UTF_8) + " from global storage."); + } + result = sharedData.remove("Hello"); + if(result.getStatus() == CacheOperationStatus.ObjectRemoved) { + System.out.println("Successfully removed " + new String(result.getValue(), StandardCharsets.UTF_8) + " from global storage."); + } + result = sharedData.put("globalTest", "assert".getBytes(StandardCharsets.UTF_8)); + break; + case "WakeUp": + SimulationController controller = processingContext.getSimulationController(); + instance._stringProp = "WakeUp"; + System.out.println("Calling run this twin..."); + controller.runThisInstance(); + break; default: break; } @@ -189,15 +225,22 @@ public ProcessingResult processModel(ProcessingContext processingContext, Simula } public static class SimpleSimProcessor extends SimulationProcessor implements Serializable { - private Gson _gson = new Gson(); - - private AtomicInteger timesInvoked = new AtomicInteger(0); - private boolean _useJson; + private Gson _gson = new Gson(); + private AtomicInteger timesInvoked = new AtomicInteger(0); + private boolean _useJson; + private String _modelIdToMessage; + private String _instanceIdToMessage; public SimpleSimProcessor(boolean json) { _useJson = json; } + public SimpleSimProcessor(String modelIdToMessage, String instanceIdToMessage) { + _useJson = false; + _modelIdToMessage = modelIdToMessage; + _instanceIdToMessage = instanceIdToMessage; + } + public int getTimesInvoked() { return timesInvoked.get(); } @@ -229,6 +272,20 @@ public ProcessingResult onTimedMessage(String s, DigitalTwinBase digitalTwinBase } else if (simpleDigitalTwin.getId().contains("alert")) { processingContext.sendAlert("alert", new AlertMessage(simpleDigitalTwin.getId(), simpleDigitalTwin.getId(), simpleDigitalTwin._stringProp)); return ProcessingResult.UpdateDigitalTwin; + } else if (simpleDigitalTwin.getId().contains("sleeper")) { + if(simpleDigitalTwin._stringProp.compareTo("WakeUp") == 0) { + System.out.println("Model ran after runThisInstance"); + simpleDigitalTwin._stringProp = "asleep"; + } + System.out.println("Going to sleep..."); + controller.delayIndefinitely(); + return ProcessingResult.UpdateDigitalTwin; + } else if (simpleDigitalTwin.getId().contains("waker")) { + System.out.println("Waking up sleeper..."); + processingContext.sendToDigitalTwin(_modelIdToMessage, _instanceIdToMessage, new SimpleMessage("WakeUp", 23)); + return ProcessingResult.UpdateDigitalTwin; + } else if (simpleDigitalTwin.getId().compareTo("initSimulation") == 0) { + return ProcessingResult.UpdateDigitalTwin; } long delay = Long.parseLong(simpleDigitalTwin.getId()); controller.delay(Duration.ofSeconds(delay)); @@ -241,6 +298,15 @@ public ProcessingResult onTimedMessage(String s, DigitalTwinBase digitalTwinBase } return ProcessingResult.UpdateDigitalTwin; } + + @Override + public ProcessingResult onInitSimulation(InitSimulationContext ctx, SimpleDigitalTwin simpleDigitalTwin, Date date) { + if(simpleDigitalTwin.getId().compareTo("initSimulation") == 0) { + timesInvoked.set(1000); + } + + return ProcessingResult.UpdateDigitalTwin; + } } @Test @@ -267,7 +333,7 @@ public void TestWorkbenchOnlySimulationInstances() throws WorkbenchException { workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); - for (int i = 0; i < 1; i++) { + for (int i = 1; i < 2; i++) { DigitalTwinBase instance = new SimpleDigitalTwin("hello" + i); workbench.addInstance("SimSimple", "" + i, instance); } @@ -344,9 +410,12 @@ public void TestWorkbenchSpeedup() throws WorkbenchException { } long start = System.currentTimeMillis(); - result = workbench.runSimulation(System.currentTimeMillis(), System.currentTimeMillis() + 60000, 100, 1000); + long stop = start + 60000; + result = workbench.runSimulation(System.currentTimeMillis(), stop, 100, 1000); Assert.assertSame(SimulationStatus.EndTimeReached, result.getStatus()); - Assert.assertEquals(1308, processor.getTimesInvoked()); + + // each id (0-999) delays for it's id in seconds + Assert.assertEquals(1249, processor.getTimesInvoked()); } catch (Exception e) { throw new RuntimeException(e); } @@ -380,7 +449,8 @@ public void TestWorkbenchDebug() throws WorkbenchException{ long stop = System.currentTimeMillis(); System.out.println("RunTime: " + (stop-start)); Assert.assertSame(SimulationStatus.EndTimeReached, result.getStatus()); - Assert.assertEquals(1308, processor.getTimesInvoked()); + // each id (0-999) delays for it's id in seconds, processor.getTimesInvoked()); + Assert.assertEquals(1249, processor.getTimesInvoked()); } catch (Exception e) { throw new RuntimeException(e); } @@ -398,10 +468,9 @@ public void testWorkbenchDebugOnlySimulationInstances() throws WorkbenchExceptio workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); - for (int i = 0; i < 1; i++) { - DigitalTwinBase instance = new SimpleDigitalTwin("hello" + i); - workbench.addInstance("SimSimple", "" + i, instance); - } + + DigitalTwinBase instance = new SimpleDigitalTwin("hello" + 100); + workbench.addInstance("SimSimple", "" + 100, instance); long startTimeMs = System.currentTimeMillis(); stopTimeMs = startTimeMs + 60000; @@ -684,10 +753,9 @@ public void TestWorkbenchPeek() throws Exception { workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); - for (int i = 0; i < 1; i++) { - DigitalTwinBase instance = new SimpleDigitalTwin("hello" + i); - workbench.addInstance("SimSimple", "" + i, instance); - } + + DigitalTwinBase instance = new SimpleDigitalTwin("hello" + 100); + workbench.addInstance("SimSimple", "" + 100, instance); long startTimeMs = System.currentTimeMillis(); stopTimeMs = startTimeMs + 60000; @@ -717,7 +785,7 @@ public void TestWorkbenchGenerateModelSchema() throws Exception { workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); String schemaAsJson = workbench.generateModelSchema("Simple"); - Assert.assertEquals(schemaAsJson, "{\"modelType\":\"com.scaleoutsoftware.digitaltwin.development.TestWorkbench$SimpleDigitalTwin\",\"messageProcessorType\":\"com.scaleoutsoftware.digitaltwin.development.TestWorkbench$SimpleMessageProcessor\",\"messageType\":\"com.scaleoutsoftware.digitaltwin.development.TestWorkbench$SimpleMessage\",\"assemblyName\":\"NOT_USED_BY_JAVA_MODELS\",\"enablePersistence\":false,\"enableSimulationSupport\":false,\"alertProviders\":[]}"); + Assert.assertSame(schemaAsJson, "{\"modelType\":\"com.scaleoutsoftware.digitaltwin.development.TestWorkbench$SimpleDigitalTwin\",\"messageProcessorType\":\"com.scaleoutsoftware.digitaltwin.development.TestWorkbench$SimpleMessageProcessor\",\"messageType\":\"com.scaleoutsoftware.digitaltwin.development.TestWorkbench$SimpleMessage\",\"assemblyName\":\"NOT_USED_BY_JAVA_MODELS\",\"enablePersistence\":false,\"enableSimulationSupport\":false,\"alertProviders\":[]}"); String dir = workbench.generateModelSchema("SimSimple", System.getProperty("user.dir")); Assert.assertEquals(String.format("%s\\model.json", System.getProperty("user.dir")), dir); } catch (Exception e) { @@ -732,6 +800,72 @@ public void TestWorkbenchGenerateModelSchemaExceptionally() throws Exception { workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); String schemaAsJson = workbench.generateModelSchema(""); + Assert.assertNotNull(schemaAsJson); + } catch (Exception e) { + throw e; + } + } + + @Test + public void TestWorkbenchSharedData() throws Exception { + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + LinkedList messages = new LinkedList<>(); + messages.add(new SimpleMessage("SharedData", 29)); + workbench.send("Simple", "23", messages); + CacheResult result = workbench.getSharedModelData("Simple").get("modelTest"); + Assert.assertEquals(CacheOperationStatus.ObjectRetrieved, result.getStatus()); + Assert.assertEquals("modelTest", result.getKey()); + Assert.assertEquals("assert", new String(result.getValue(), StandardCharsets.UTF_8)); + result = workbench.getSharedGlobalData("Simple").get("globalTest"); + Assert.assertEquals(CacheOperationStatus.ObjectRetrieved, result.getStatus()); + Assert.assertEquals("globalTest", result.getKey()); + Assert.assertEquals("assert", new String(result.getValue(), StandardCharsets.UTF_8)); + } catch (Exception e) { + throw e; + } + } + + @Test + public void TestWorkbenchRunThisInstance() throws Exception { + try (Workbench workbench = new Workbench()) { + workbench.addSimulationModel("Simple", new SimpleMessageProcessor(), new SimpleSimProcessor("Simple2", "sleeper"), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("Simple2", new SimpleMessageProcessor(), new SimpleSimProcessor(false), SimpleDigitalTwin.class, SimpleMessage.class); + + workbench.addInstance("Simple", "waker", new SimpleDigitalTwin("waker")); + workbench.addInstance("Simple2", "sleeper", new SimpleDigitalTwin("sleeper")); + long startTimeMs = System.currentTimeMillis(); + long stopTimeMs = startTimeMs + 15000L; + long step = 1000L; + workbench.runSimulation(startTimeMs, stopTimeMs, 1, step); + SimpleDigitalTwin waker = (SimpleDigitalTwin) workbench.getInstances("Simple").get("waker"); + SimpleDigitalTwin sleeper = (SimpleDigitalTwin) workbench.getInstances("Simple2").get("sleeper"); + Assert.assertNotNull(waker); + Assert.assertNotNull(sleeper); + Assert.assertEquals("waker", waker._stringProp); + Assert.assertEquals("asleep", sleeper._stringProp); + } catch (Exception e) { + throw e; + } + } + + @Test + public void TestWorkbenchInitSimulation() throws Exception { + try (Workbench workbench = new Workbench()) { + SimpleSimProcessor processor = new SimpleSimProcessor(false); + workbench.addSimulationModel("Simple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + + workbench.addInstance("Simple", "initSimulation", new SimpleDigitalTwin("waker")); + + long simRuntimeMs = 15000L; + long startTimeMs = System.currentTimeMillis(); + long stopTimeMs = startTimeMs + simRuntimeMs; + int speedup = 1; + long step = 1000L; + long expectedInvokes = simRuntimeMs/1000L; + int initSimExpectedInvokes = 1000; + workbench.runSimulation(startTimeMs, stopTimeMs, speedup, step); + Assert.assertEquals(expectedInvokes + initSimExpectedInvokes, processor.timesInvoked.get()); } catch (Exception e) { throw e; } diff --git a/docs/allclasses-index.html b/docs/allclasses-index.html index bddcce0..a1e1471 100644 --- a/docs/allclasses-index.html +++ b/docs/allclasses-index.html @@ -2,7 +2,7 @@ -All Classes and Interfaces (digitaltwin-core-docs 3.0.4 API) +All Classes and Interfaces (digitaltwin-core-docs 3.0.5 API) @@ -67,6 +67,14 @@

All Classes and Interfaces<
Configuration for an alert provider.
+ +
+
Status of a cache operation.
+
+ +
+
Represents a response from a SharedData operation.
+
A real-time digital twin of a data source.
@@ -80,47 +88,56 @@

All Classes and Interfaces<
The InitContext is passed as a parameter to the DigitalTwinBase.init(InitContext) method of an initializing digital twin.

- -
+ +
+
The InitSimulationContext is passed as a parameter to the SimulationProcessor.onInitSimulation(InitSimulationContext, DigitalTwinBase, Date) method of + digital twin instance when a simulation is initializing.
+
+ +
A messaged that was logged by a digital twin.
- -
+ +
Message list factory retrieves message lists for a MessageProcessor
- -
+ +
Processes messages for a real-time digital twin.
- -
+ +
Base class for the MessageProcessor to help with typing.
- -
+ +
The ModelSchema class is used as a Java object representation of the model.json schema file used for deploying a digital twin model to the real-time digital twin cloud service.
- -
+ +
An interface that can be used for persisting/retrieving the state of real-time digital twins.
- -
+ +
Available PersistenceProvider types.
- -
+ +
Context object that allows the user to send a message to a DataSource.
- -
+ +
The result from a message processor which indicates to update the state object or to ignore
- -
+ +
Marks a message as Delivered or not Delivered
+ +
+
SharedData is used to access a model's, or globally, shared cache.
+
The SimulationController interface is used to interact with the running DigitalTwin simulation.
diff --git a/docs/allpackages-index.html b/docs/allpackages-index.html index 3040f57..cdc7533 100644 --- a/docs/allpackages-index.html +++ b/docs/allpackages-index.html @@ -2,7 +2,7 @@ -All Packages (digitaltwin-core-docs 3.0.4 API) +All Packages (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/AlertMessage.html b/docs/com/scaleoutsoftware/digitaltwin/core/AlertMessage.html index f552c72..75ab8d8 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/AlertMessage.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/AlertMessage.html @@ -2,7 +2,7 @@ -AlertMessage (digitaltwin-core-docs 3.0.4 API) +AlertMessage (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.html b/docs/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.html index 838eb7a..ae33977 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.html @@ -2,7 +2,7 @@ -AlertProviderConfiguration (digitaltwin-core-docs 3.0.4 API) +AlertProviderConfiguration (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/CacheOperationStatus.html b/docs/com/scaleoutsoftware/digitaltwin/core/CacheOperationStatus.html new file mode 100644 index 0000000..9ff6c42 --- /dev/null +++ b/docs/com/scaleoutsoftware/digitaltwin/core/CacheOperationStatus.html @@ -0,0 +1,256 @@ + + + + +CacheOperationStatus (digitaltwin-core-docs 3.0.5 API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +

Enum Class CacheOperationStatus

+
+
java.lang.Object +
java.lang.Enum<CacheOperationStatus> +
com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
+
+
+
+
+
All Implemented Interfaces:
+
Serializable, Comparable<CacheOperationStatus>, Constable
+
+
+
public enum CacheOperationStatus +extends Enum<CacheOperationStatus>
+
Status of a cache operation.
+
+
+ +
+
+
    + +
  • +
    +

    Enum Constant Details

    +
      +
    • +
      +

      ObjectRetrieved

      +
      public static final CacheOperationStatus ObjectRetrieved
      +
      The object was successfully retrieved.
      +
      +
    • +
    • +
      +

      ObjectPut

      +
      public static final CacheOperationStatus ObjectPut
      +
      The object was successfully added/updated.
      +
      +
    • +
    • +
      +

      ObjectDoesNotExist

      +
      public static final CacheOperationStatus ObjectDoesNotExist
      +
      The object could not be retrieved because it was not found.
      +
      +
    • +
    • +
      +

      ObjectRemoved

      +
      public static final CacheOperationStatus ObjectRemoved
      +
      The object was removed successfully.
      +
      +
    • +
    • +
      +

      CacheCleared

      +
      public static final CacheOperationStatus CacheCleared
      +
      The cache was cleared successfully.
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      values

      +
      public static CacheOperationStatus[] values()
      +
      Returns an array containing the constants of this enum class, in +the order they are declared.
      +
      +
      Returns:
      +
      an array containing the constants of this enum class, in the order they are declared
      +
      +
      +
    • +
    • +
      +

      valueOf

      +
      public static CacheOperationStatus valueOf(String name)
      +
      Returns the enum constant of this class with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this class. (Extraneous whitespace characters are +not permitted.)
      +
      +
      Parameters:
      +
      name - the name of the enum constant to be returned.
      +
      Returns:
      +
      the enum constant with the specified name
      +
      Throws:
      +
      IllegalArgumentException - if this enum class has no constant with the specified name
      +
      NullPointerException - if the argument is null
      +
      +
      +
    • +
    +
    +
  • +
+
+ +
+
+
+ + diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/CacheResult.html b/docs/com/scaleoutsoftware/digitaltwin/core/CacheResult.html new file mode 100644 index 0000000..9334a2c --- /dev/null +++ b/docs/com/scaleoutsoftware/digitaltwin/core/CacheResult.html @@ -0,0 +1,163 @@ + + + + +CacheResult (digitaltwin-core-docs 3.0.5 API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +

Interface CacheResult

+
+
+
+
public interface CacheResult
+
Represents a response from a SharedData operation.
+
+
+
    + +
  • +
    +

    Method Summary

    +
    +
    +
    +
    +
    Modifier and Type
    +
    Method
    +
    Description
    + + +
    +
    Gets the key or null to the object associated with the result.
    +
    + + +
    +
    Gets the status of the cache operation.
    +
    +
    byte[]
    + +
    +
    Get the object returned from a Get operation.
    +
    +
    +
    +
    +
    +
  • +
+
+
+
    + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getKey

      +
      String getKey()
      +
      Gets the key or null to the object associated with the result.
      +
      +
      Returns:
      +
      the key or null.
      +
      +
      +
    • +
    • +
      +

      getValue

      +
      byte[] getValue()
      +
      Get the object returned from a Get operation.
      +
      +
      Returns:
      +
      the object or null.
      +
      +
      +
    • +
    • +
      +

      getStatus

      + +
      Gets the status of the cache operation.
      +
      +
      Returns:
      +
      the operation status.
      +
      +
      +
    • +
    +
    +
  • +
+
+ +
+
+
+ + diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.html b/docs/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.html index d22f132..c013270 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.html @@ -2,7 +2,7 @@ -DigitalTwinBase (digitaltwin-core-docs 3.0.4 API) +DigitalTwinBase (digitaltwin-core-docs 3.0.5 API) @@ -123,7 +123,9 @@

Constructor Summary

Constructor
Description
-
 
+
+
Default constructor.
+
@@ -220,6 +222,7 @@

Constructor Details

DigitalTwinBase

public DigitalTwinBase()
+
Default constructor.
diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.html b/docs/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.html index e7de9da..71116ad 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.html @@ -2,7 +2,7 @@ -DigitalTwinTimerMessage (digitaltwin-core-docs 3.0.4 API) +DigitalTwinTimerMessage (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/InitContext.html b/docs/com/scaleoutsoftware/digitaltwin/core/InitContext.html index 65bae14..4d362ae 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/InitContext.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/InitContext.html @@ -2,7 +2,7 @@ -InitContext (digitaltwin-core-docs 3.0.4 API) +InitContext (digitaltwin-core-docs 3.0.5 API) @@ -91,7 +91,9 @@

Constructor Summary

Constructor
Description
-
 
+
+
Default constructor.
+
@@ -116,6 +118,16 @@

Method Summary

Get the Model identifier of the initializing digital twin instance.
+
abstract SharedData
+ +
+
Retrieve a SharedData accessor for globally shared data.
+
+
abstract SharedData
+ +
+
Retrieve a SharedData accessor for this model's shared data.
+
startTimer(String timerName, Duration interval, @@ -145,6 +157,7 @@

Constructor Details

InitContext

public InitContext()
+
Default constructor.
@@ -179,6 +192,28 @@

startTimer

  • +
    +

    getSharedModelData

    +
    public abstract SharedData getSharedModelData()
    +
    Retrieve a SharedData accessor for this model's shared data.
    +
    +
    Returns:
    +
    a SharedData instance.
    +
    +
    +
  • +
  • +
    +

    getSharedGlobalData

    +
    public abstract SharedData getSharedGlobalData()
    +
    Retrieve a SharedData accessor for globally shared data.
    +
    +
    Returns:
    +
    a SharedData instance.
    +
    +
    +
  • +
  • getId

    public abstract String getId()
    diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/InitSimulationContext.html b/docs/com/scaleoutsoftware/digitaltwin/core/InitSimulationContext.html new file mode 100644 index 0000000..0640172 --- /dev/null +++ b/docs/com/scaleoutsoftware/digitaltwin/core/InitSimulationContext.html @@ -0,0 +1,148 @@ + + + + +InitSimulationContext (digitaltwin-core-docs 3.0.5 API) + + + + + + + + + + + + + + +
    + +
    +
    + +
    + +

    Interface InitSimulationContext

    +
    +
    +
    +
    public interface InitSimulationContext
    +
    The InitSimulationContext is passed as a parameter to the SimulationProcessor.onInitSimulation(InitSimulationContext, DigitalTwinBase, Date) method of + digital twin instance when a simulation is initializing.
    +
    +
    + +
    +
    +
      + +
    • +
      +

      Method Details

      +
        +
      • +
        +

        getSharedModelData

        +
        SharedData getSharedModelData()
        +
        Retrieve a SharedData accessor for this model's shared data.
        +
        +
        Returns:
        +
        a SharedData instance.
        +
        +
        +
      • +
      • +
        +

        getSharedGlobalData

        +
        SharedData getSharedGlobalData()
        +
        Retrieve a SharedData accessor for globally shared data.
        +
        +
        Returns:
        +
        a SharedData instance.
        +
        +
        +
      • +
      +
      +
    • +
    +
    + +
    +
    +
    + + diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/MessageFactory.html b/docs/com/scaleoutsoftware/digitaltwin/core/MessageFactory.html index fd9882a..b9941e1 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/MessageFactory.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/MessageFactory.html @@ -2,7 +2,7 @@ -MessageFactory (digitaltwin-core-docs 3.0.4 API) +MessageFactory (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.html b/docs/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.html index 87c25e4..87308d2 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.html @@ -2,7 +2,7 @@ -MessageProcessor (digitaltwin-core-docs 3.0.4 API) +MessageProcessor (digitaltwin-core-docs 3.0.5 API) @@ -110,7 +110,9 @@

    Constructor Summary

    Constructor
    Description
    -
     
    +
    +
    Default constructor.
    +
  • @@ -160,6 +162,7 @@

    Constructor Details

    MessageProcessor

    public MessageProcessor()
    +
    Default constructor.
    diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.html b/docs/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.html index ab6edc5..d9eca63 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.html @@ -2,7 +2,7 @@ -MessageProcessorBase (digitaltwin-core-docs 3.0.4 API) +MessageProcessorBase (digitaltwin-core-docs 3.0.5 API) @@ -98,7 +98,9 @@

    Constructor Summary

    Constructor
    Description
    -
     
    +
    +
    Default constructor.
    +
    @@ -141,6 +143,7 @@

    Constructor Details

    MessageProcessorBase

    public MessageProcessorBase()
    +
    Default constructor.
    diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/ModelSchema.html b/docs/com/scaleoutsoftware/digitaltwin/core/ModelSchema.html index 45f653c..dd17e2c 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/ModelSchema.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/ModelSchema.html @@ -2,7 +2,7 @@ -ModelSchema (digitaltwin-core-docs 3.0.4 API) +ModelSchema (digitaltwin-core-docs 3.0.5 API) @@ -96,12 +96,45 @@

    Constructor Summary

    Creates a model schema from a digital twin class, a message processor class, and a message class.
    -
    ModelSchema(String dtClass, +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + boolean emr)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, and a message class.
    +
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String ep)
    +
    +
    Model schema with a defined entry point.
    +
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String ep, + boolean emr)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, and a message class.
    +
    +
    ModelSchema(String dtClass, String mpClass, String msgClass, String adtName, PersistenceProviderType persistenceType, List<AlertProviderConfiguration> alertingProviders)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String adtName, + PersistenceProviderType persistenceType, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    Creates a model schema from a digital twin class, a message processor class, a message class, and alert provider configurations.
    @@ -113,24 +146,86 @@

    Constructor Summary

    String adtName, PersistenceProviderType persistenceType, List<AlertProviderConfiguration> alertingProviders)
    -
     
    -
    ModelSchema(String dtClass, +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    +
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String simulationProcessorClass, + String adtName, + PersistenceProviderType persistenceType, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    +
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String simulationProcessorClass, + String adtName, + String ep, + PersistenceProviderType persistenceType, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    +
    +
    ModelSchema(String dtClass, String mpClass, String msgClass, String spClass, + String ep, List<AlertProviderConfiguration> alertingProviders)
    Creates a model schema from a digital twin class, a message processor class, a message class, and alert provider configurations.
    -
    ModelSchema(String dtClass, +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String spClass, + String ep, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    ModelSchema(String dtClass, String mpClass, String msgClass, + String spClass, List<AlertProviderConfiguration> alertingProviders)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String spClass, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    Creates a model schema from a digital twin class, a message processor class, a message class, and alert provider configurations.
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + List<AlertProviderConfiguration> alertingProviders)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    @@ -161,30 +256,40 @@

    Method Summary

    Retrieve the Azure Digital Twin model name.
    - +
    -
    Retrieve the message processor type (a MessageProcessor implementation).
    +
    Retrieves the packaged model's entry point (fully-qualified class name -- FQCN -- of a Java main) for launching.
    - +
    -
    Retrieve the message type (JSON serializable message implementation).
    +
    Retrieve the message processor type (a MessageProcessor implementation).
    - +
    -
    Retrieve the digital twin model type (a DigitalTwinBase implementation).
    +
    Retrieve the message type (JSON serializable message implementation).
    - - + +
    -
    Retrieve the persistence provider type.
    +
    Retrieve the digital twin model type (a DigitalTwinBase implementation).
    - - + +
    +
    Retrieve the persistence provider type.
    +
    + + +
    Retrieve the simulation processor type (a SimulationProcessor implementation).
    +
    boolean
    + +
    +
    Retrieves the message recording enabled status.
    +
    boolean
    @@ -228,6 +333,59 @@

    ModelSchema

  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String ep)
    +
    Model schema with a defined entry point.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    ep - the invocation grid entry point.
    +
    +
    +
  • +
  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, and a message class.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • +
  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String ep, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, and a message class.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    ep - the invocation grid entry point.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • +
  • ModelSchema

    public ModelSchema(String dtClass, @@ -266,6 +424,74 @@

    ModelSchema

  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String spClass, + String ep, + List<AlertProviderConfiguration> alertingProviders)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    spClass - the simulation processor class implementation.
    +
    ep - the invocation grid entry point.
    +
    alertingProviders - the alerting provider configurations.
    +
    +
    +
  • +
  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String spClass, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    spClass - the simulation processor class implementation.
    +
    alertingProviders - the alerting provider configurations.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • +
  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String spClass, + String ep, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    spClass - the simulation processor class implementation.
    +
    alertingProviders - the alerting provider configurations.
    +
    ep - the invocation grid entry point.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • +
  • ModelSchema

    public ModelSchema(String dtClass, @@ -288,6 +514,30 @@

    ModelSchema

  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String adtName, + PersistenceProviderType persistenceType, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    adtName - the Azure Digital Twin model name.
    +
    persistenceType - the persistence provider type.
    +
    alertingProviders - the alerting provider configurations.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • +
  • ModelSchema

    public ModelSchema(String dtClass, @@ -297,6 +547,9 @@

    ModelSchema

    String adtName, PersistenceProviderType persistenceType, List<AlertProviderConfiguration> alertingProviders)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    Parameters:
    dtClass - the digital twin class implementation.
    @@ -309,6 +562,62 @@

    ModelSchema

  • +
  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String simulationProcessorClass, + String adtName, + PersistenceProviderType persistenceType, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    simulationProcessorClass - the simulation processor class implementation.
    +
    adtName - the Azure Digital Twin model name.
    +
    persistenceType - the persistence provider type.
    +
    alertingProviders - the alerting provider configurations.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • +
  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String simulationProcessorClass, + String adtName, + String ep, + PersistenceProviderType persistenceType, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    simulationProcessorClass - the simulation processor class implementation.
    +
    adtName - the Azure Digital Twin model name.
    +
    persistenceType - the persistence provider type.
    +
    alertingProviders - the alerting provider configurations.
    +
    ep - the invocation grid entry point.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • @@ -427,6 +736,29 @@

    getPersistenceProvider

    +
  • +
    +

    messageRecordingEnabled

    +
    public boolean messageRecordingEnabled()
    +
    Retrieves the message recording enabled status. True if this model should persist messages when message recording is active, + false otherwise.
    +
    +
    Returns:
    +
    True if message recording is enabled, false otherwise.
    +
    +
    +
  • +
  • +
    +

    getEntryPoint

    +
    public String getEntryPoint()
    +
    Retrieves the packaged model's entry point (fully-qualified class name -- FQCN -- of a Java main) for launching.
    +
    +
    Returns:
    +
    the entry point for launching.
    +
    +
    +
  • diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.html b/docs/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.html index 7f6fc37..214c380 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.html @@ -2,7 +2,7 @@ -PersistenceProvider (digitaltwin-core-docs 3.0.4 API) +PersistenceProvider (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.html b/docs/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.html index da4a79b..cff66a9 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.html @@ -2,7 +2,7 @@ -PersistenceProviderType (digitaltwin-core-docs 3.0.4 API) +PersistenceProviderType (digitaltwin-core-docs 3.0.5 API) @@ -109,6 +109,14 @@

    Enum Constant Summary

    Enum for the Azure Digital Twin service.
    + +
    +
    Enum for CosmosDB
    +
    + +
    +
    Enum for DynamoDB
    +
    Enum for SQLite
    @@ -118,7 +126,9 @@

    Enum Constant Summary

    Enum for SQLServer
    -
     
    +
    +
    Enum for an unconfigured PersistenceProvider
    +
    @@ -127,7 +137,7 @@

    Enum Constant Summary

    Method Summary

    -
    +
    Modifier and Type
    @@ -143,6 +153,16 @@

    Method Summary

    Return the PersistenceProviderType from a string value.
    + + +
    +
    Retrieve the name of the persistence provider type.
    +
    +
    int
    + +
    +
    Retrieve the ordinal value (used by the DTBuidler service).
    +
    @@ -182,6 +202,20 @@

    AzureDigitalTwinsService

  • +
    +

    CosmosDb

    +
    public static final PersistenceProviderType CosmosDb
    +
    Enum for CosmosDB
    +
    +
  • +
  • +
    +

    DynamoDb

    +
    public static final PersistenceProviderType DynamoDb
    +
    Enum for DynamoDB
    +
    +
  • +
  • SQLite

    public static final PersistenceProviderType SQLite
    @@ -199,6 +233,7 @@

    SQLServer

    Unconfigured

    public static final PersistenceProviderType Unconfigured
    +
    Enum for an unconfigured PersistenceProvider
  • @@ -241,6 +276,28 @@

    valueOf

  • +
    +

    getName

    +
    public String getName()
    +
    Retrieve the name of the persistence provider type.
    +
    +
    Returns:
    +
    the name of the persistence provider type.
    +
    +
    +
  • +
  • +
    +

    getServiceOrdinalValue

    +
    public int getServiceOrdinalValue()
    +
    Retrieve the ordinal value (used by the DTBuidler service).
    +
    +
    Returns:
    +
    the ordinal value.
    +
    +
    +
  • +
  • fromString

    public static PersistenceProviderType fromString(String name)
    diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.html b/docs/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.html index 383f87d..ea553fe 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.html @@ -2,7 +2,7 @@ -ProcessingContext (digitaltwin-core-docs 3.0.4 API) +ProcessingContext (digitaltwin-core-docs 3.0.5 API) @@ -103,7 +103,9 @@

    Constructor Summary

    Constructor
    Description
    -
     
    +
    +
    Default constructor.
    +
  • @@ -138,6 +140,16 @@

    Method Summary

    Returns the configured persistence provider or null if no persistence provider configuration can be found.
    +
    abstract SharedData
    + +
    +
    Retrieve a SharedData accessor for globally shared data.
    +
    +
    abstract SharedData
    + +
    +
    Retrieve a SharedData accessor for this model's shared data.
    +
    @@ -240,6 +252,7 @@

    Constructor Details

    ProcessingContext

    public ProcessingContext()
    +
    Default constructor.
    @@ -412,7 +425,7 @@

    sendAlert

    public abstract SendingResult sendAlert(String alertingProviderName, AlertMessage alert)

    - This method sends an alert message to supported systems. See "TODO: Link to docs" for more details on supported systems. + This method sends an alert message to supported systems.

    @@ -544,6 +557,28 @@

    getSimulationController

    +
  • +
    +

    getSharedModelData

    +
    public abstract SharedData getSharedModelData()
    +
    Retrieve a SharedData accessor for this model's shared data.
    +
    +
    Returns:
    +
    a SharedData instance.
    +
    +
    +
  • +
  • +
    +

    getSharedGlobalData

    +
    public abstract SharedData getSharedGlobalData()
    +
    Retrieve a SharedData accessor for globally shared data.
    +
    +
    Returns:
    +
    a SharedData instance.
    +
    +
    +
  • diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.html b/docs/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.html index 4d2073a..99cf30d 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.html @@ -2,7 +2,7 @@ -ProcessingResult (digitaltwin-core-docs 3.0.4 API) +ProcessingResult (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/SendingResult.html b/docs/com/scaleoutsoftware/digitaltwin/core/SendingResult.html index 8d9d776..3bce6fe 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/SendingResult.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/SendingResult.html @@ -2,7 +2,7 @@ -SendingResult (digitaltwin-core-docs 3.0.4 API) +SendingResult (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/SharedData.html b/docs/com/scaleoutsoftware/digitaltwin/core/SharedData.html new file mode 100644 index 0000000..a0da3b9 --- /dev/null +++ b/docs/com/scaleoutsoftware/digitaltwin/core/SharedData.html @@ -0,0 +1,188 @@ + + + + +SharedData (digitaltwin-core-docs 3.0.5 API) + + + + + + + + + + + + + + +
    + +
    +
    + +
    + +

    Interface SharedData

    +
    +
    +
    +
    public interface SharedData
    +
    SharedData is used to access a model's, or globally, shared cache.
    +
    +
    +
      + +
    • +
      +

      Method Summary

      +
      +
      +
      +
      +
      Modifier and Type
      +
      Method
      +
      Description
      + + +
      +
      Clear the shared data cache.
      +
      + +
      get(String key)
      +
      +
      Retrieves an existing object from the cache.
      +
      + +
      put(String key, + byte[] value)
      +
      +
      Put a new key/value mapping into the cache.
      +
      + + +
      +
      Remove a key/value mapping from the cache.
      +
      +
      +
      +
      +
      +
    • +
    +
    +
    +
      + +
    • +
      +

      Method Details

      +
        +
      • +
        +

        get

        +
        CacheResult get(String key)
        +
        Retrieves an existing object from the cache.
        +
        +
        Parameters:
        +
        key - the key mapping to a value.
        +
        Returns:
        +
        A cache result.
        +
        +
        +
      • +
      • +
        +

        put

        +
        CacheResult put(String key, + byte[] value)
        +
        Put a new key/value mapping into the cache.
        +
        +
        Parameters:
        +
        key - the key mapping to a value.
        +
        value - the value.
        +
        Returns:
        +
        a cache result.
        +
        +
        +
      • +
      • +
        +

        remove

        +
        CacheResult remove(String key)
        +
        Remove a key/value mapping from the cache.
        +
        +
        Parameters:
        +
        key - the key mapping to a value.
        +
        Returns:
        +
        a cache result.
        +
        +
        +
      • +
      • +
        +

        clear

        +
        CacheResult clear()
        +
        Clear the shared data cache.
        +
        +
        Returns:
        +
        a cache result.
        +
        +
        +
      • +
      +
      +
    • +
    +
    + +
    +
    +
    + + diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/SimulationController.html b/docs/com/scaleoutsoftware/digitaltwin/core/SimulationController.html index eab1111..df4c127 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/SimulationController.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/SimulationController.html @@ -2,7 +2,7 @@ -SimulationController (digitaltwin-core-docs 3.0.4 API) +SimulationController (digitaltwin-core-docs 3.0.5 API) @@ -115,41 +115,58 @@

    Method Summary

    Delay simulation processing for this DigitalTwin instance for a duration of time.
    -
    deleteInstance(String modelName, - String instanceId)
    +
    -
    Delete and remove a digital twin instance from simulation processing.
    +
    + Delay simulation processing for this DigitalTwin instance, indefinitely.
    - +
    deleteInstance(String modelName, + String instanceId)
    -
    Delete and remove this digital twin instance from simulation processing.
    +
    Delete and remove a digital twin instance from simulation processing.
    -
    emitTelemetry(String modelName, - byte[] telemetryMessage)
    +
    +
    Delete and remove this digital twin instance from simulation processing.
    +
    + +
    emitTelemetry(String modelName, + byte[] telemetryMessage)
    +
    Asynchronously send a JSON serialized message to a DigitalTwin instance that will be processed by the DigitalTwin models MessageProcessor.processMessages(ProcessingContext, DigitalTwinBase, Iterable) method.
    - -
    emitTelemetry(String modelName, + +
    emitTelemetry(String modelName, Object jsonSerializableMessage)
    -
    +
    Asynchronously send a JSON serializable message to a DigitalTwin instance that will be processed by the DigitalTwin models MessageProcessor.processMessages(ProcessingContext, DigitalTwinBase, Iterable) method.
    + + +
    +
    + Retrieves the simulation start time.
    +
    Retrieves the current simulation time increment.
    - - +
    void
    +
    +
    Run this instance during this simulation step.
    +
    + + +
    Stop the simulation.
    @@ -180,6 +197,19 @@

    getSimulationTimeIncrement

  • +
    +

    getSimulationStartTime

    +
    Date getSimulationStartTime()
    +

    + Retrieves the simulation start time. +

    +
    +
    Returns:
    +
    the simulation start time.
    +
    +
    +
  • +
  • delay

    SendingResult delay(Duration duration)
    @@ -219,6 +249,24 @@

    delay

  • +
    +

    delayIndefinitely

    +
    SendingResult delayIndefinitely()
    +

    + Delay simulation processing for this DigitalTwin instance, indefinitely. +

    + +

    + Simulation processing will be delayed until this instance is run with runThisInstance(). +

    +
    +
    Returns:
    +
    SendingResult.Handled if the delay was processed or SendingResult.NotHandled + if the delay was not processed.
    +
    +
    +
  • +
  • emitTelemetry

    SendingResult emitTelemetry(String modelName, @@ -348,6 +396,17 @@

    deleteThisInstance

  • +
    +

    runThisInstance

    +
    void runThisInstance()
    +
    Run this instance during this simulation step. The instance will be run using the models SimulationProcessor.processModel(ProcessingContext, DigitalTwinBase, Date) + implementation. + + This will cause the simulation sub-system to run this instance regardless of the instances current + DigitalTwinBase.NextSimulationTime.
    +
    +
  • +
  • stopSimulation

    SimulationStatus stopSimulation()
    diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.html b/docs/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.html index 7f4fc19..64de0a7 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.html @@ -2,7 +2,7 @@ -SimulationProcessor (digitaltwin-core-docs 3.0.4 API) +SimulationProcessor (digitaltwin-core-docs 3.0.5 API) @@ -107,7 +107,9 @@

    Constructor Summary

    Constructor
    Description
    -
     
    +
    +
    Default constructor.
    +
  • @@ -116,17 +118,25 @@

    Constructor Summary

    Method Summary

    -
    +
    Modifier and Type
    Method
    Description
    - -
    processModel(ProcessingContext context, + +
    onInitSimulation(InitSimulationContext context, + T instance, + Date epoch)
    +
    +
    + Optional method that is called per-instance when a simulation is started.
    +
    + +
    processModel(ProcessingContext context, T instance, Date epoch)
    -
    +
    Processes simulation events for a real-time digital twin.
    @@ -150,6 +160,7 @@

    Constructor Details

    SimulationProcessor

    public SimulationProcessor()
    +
    Default constructor.
    @@ -178,6 +189,36 @@

    +

    onInitSimulation

    +
    public ProcessingResult onInitSimulation(InitSimulationContext context, + T instance, + Date epoch)
    +

    + Optional method that is called per-instance when a simulation is started. Default behavior is a no-op. +

    + +

    + onInitSimulation can be used when internal digital twin starting state is set outside the context of a digital twins init method and may be changed + between simulation runs. +

    +
      +
    • Set variables in global or shared data.
    • +
    • Run a simulation.
    • +
    • onInitSimulation is called (per-instance) and digital twin instances set internal state based on the values in shared data.
    • +
    • Complete simulation and evaluate the result.
    • +
    +
    +
    Parameters:
    +
    context - The simulation init context.
    +
    instance - The digital twin instance.
    +
    epoch - the simulation start time.
    +
    Returns:
    +
    ProcessingResult.UpdateDigitalTwin or ProcessingResult.NoUpdate. Default behavior: ProcessingResult.NoUpdate.
    +
    +
    + diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.html b/docs/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.html index c0f7ab0..95a1b09 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.html @@ -2,7 +2,7 @@ -SimulationStatus (digitaltwin-core-docs 3.0.4 API) +SimulationStatus (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.html b/docs/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.html index eb5dd4c..9cb2a82 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.html @@ -2,7 +2,7 @@ -TimerActionResult (digitaltwin-core-docs 3.0.4 API) +TimerActionResult (digitaltwin-core-docs 3.0.5 API) @@ -255,7 +255,8 @@

    fromOrdinal

    + 2 = FailedNoSuchTimer, 3 = FailedTimerAlreadyExists, + 4 = FailedInternalError
    Parameters:
    val - the ordinal value.
    diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/TimerHandler.html b/docs/com/scaleoutsoftware/digitaltwin/core/TimerHandler.html index c07d3f3..60c2c72 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/TimerHandler.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/TimerHandler.html @@ -2,7 +2,7 @@ -TimerHandler (digitaltwin-core-docs 3.0.4 API) +TimerHandler (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.html b/docs/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.html index 27958fe..b2824fe 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.html @@ -2,7 +2,7 @@ -TimerMetadata (digitaltwin-core-docs 3.0.4 API) +TimerMetadata (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/TimerType.html b/docs/com/scaleoutsoftware/digitaltwin/core/TimerType.html index 3264684..cef4477 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/TimerType.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/TimerType.html @@ -2,7 +2,7 @@ -TimerType (digitaltwin-core-docs 3.0.4 API) +TimerType (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/package-summary.html b/docs/com/scaleoutsoftware/digitaltwin/core/package-summary.html index db0c1b6..9fa1f27 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/package-summary.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/package-summary.html @@ -2,7 +2,7 @@ -com.scaleoutsoftware.digitaltwin.core (digitaltwin-core-docs 3.0.4 API) +com.scaleoutsoftware.digitaltwin.core (digitaltwin-core-docs 3.0.5 API) @@ -83,6 +83,14 @@

    Package
    Configuration for an alert provider.
    + +
    +
    Status of a cache operation.
    +
    + +
    +
    Represents a response from a SharedData operation.
    +
    A real-time digital twin of a data source.
    @@ -96,43 +104,52 @@

    Package
    The InitContext is passed as a parameter to the DigitalTwinBase.init(InitContext) method of an initializing digital twin.

    - +
    +
    The InitSimulationContext is passed as a parameter to the SimulationProcessor.onInitSimulation(InitSimulationContext, DigitalTwinBase, Date) method of + digital twin instance when a simulation is initializing.
    +
    + +
    Message list factory retrieves message lists for a MessageProcessor
    - -
    + +
    Processes messages for a real-time digital twin.
    - -
    + +
    Base class for the MessageProcessor to help with typing.
    - -
    + +
    The ModelSchema class is used as a Java object representation of the model.json schema file used for deploying a digital twin model to the real-time digital twin cloud service.
    - -
    + +
    An interface that can be used for persisting/retrieving the state of real-time digital twins.
    - -
    + +
    Available PersistenceProvider types.
    - -
    + +
    Context object that allows the user to send a message to a DataSource.
    - -
    + +
    The result from a message processor which indicates to update the state object or to ignore
    - -
    + +
    Marks a message as Delivered or not Delivered
    + +
    +
    SharedData is used to access a model's, or globally, shared cache.
    +
    The SimulationController interface is used to interact with the running DigitalTwin simulation.
    diff --git a/docs/com/scaleoutsoftware/digitaltwin/core/package-tree.html b/docs/com/scaleoutsoftware/digitaltwin/core/package-tree.html index 21271e7..d2f2c59 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/core/package-tree.html +++ b/docs/com/scaleoutsoftware/digitaltwin/core/package-tree.html @@ -2,7 +2,7 @@ -com.scaleoutsoftware.digitaltwin.core Class Hierarchy (digitaltwin-core-docs 3.0.4 API) +com.scaleoutsoftware.digitaltwin.core Class Hierarchy (digitaltwin-core-docs 3.0.5 API) @@ -79,8 +79,11 @@

    Class Hierarchy

    Interface Hierarchy

    @@ -92,6 +95,7 @@

    Enum Class Hierarchy

    • java.lang.Enum<E> (implements java.lang.Comparable<T>, java.lang.constant.Constable, java.io.Serializable)
        +
      • com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
      • com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType (implements java.io.Serializable)
      • com.scaleoutsoftware.digitaltwin.core.ProcessingResult
      • com.scaleoutsoftware.digitaltwin.core.SendingResult
      • diff --git a/docs/com/scaleoutsoftware/digitaltwin/development/LogMessage.html b/docs/com/scaleoutsoftware/digitaltwin/development/LogMessage.html index 4ec280c..f94cc8d 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/development/LogMessage.html +++ b/docs/com/scaleoutsoftware/digitaltwin/development/LogMessage.html @@ -2,7 +2,7 @@ -LogMessage (digitaltwin-core-docs 3.0.4 API) +LogMessage (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.html b/docs/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.html index b80b113..de93f73 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.html +++ b/docs/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.html @@ -2,7 +2,7 @@ -SimulationEventResult (digitaltwin-core-docs 3.0.4 API) +SimulationEventResult (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/development/SimulationStep.html b/docs/com/scaleoutsoftware/digitaltwin/development/SimulationStep.html index 9695d0f..cc34461 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/development/SimulationStep.html +++ b/docs/com/scaleoutsoftware/digitaltwin/development/SimulationStep.html @@ -2,7 +2,7 @@ -SimulationStep (digitaltwin-core-docs 3.0.4 API) +SimulationStep (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/development/Workbench.html b/docs/com/scaleoutsoftware/digitaltwin/development/Workbench.html index 52e4e46..cc54152 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/development/Workbench.html +++ b/docs/com/scaleoutsoftware/digitaltwin/development/Workbench.html @@ -2,7 +2,7 @@ -Workbench (digitaltwin-core-docs 3.0.4 API) +Workbench (digitaltwin-core-docs 3.0.5 API) @@ -321,6 +321,10 @@

        Constructor Summary

        Instantiate the workbench.
        +
        Workbench(int numSimulationWorkers)
        +
        +
        Instantiate the workbench.
        +
    @@ -342,21 +346,34 @@

    Method Summary

    Adds an alert provider configuration to the specified model on this workbench.
    void
    -
    addInstance(String modelName, +
    addGlobalModelData(String key, + byte[] value)
    +
    +
    Add a key/value pair to the global SharedData.
    +
    +
    void
    +
    addInstance(String modelName, String id, DigitalTwinBase instance)
    -
    +
    Adds a digital twin instance to the workbench.
    -
    <T extends DigitalTwinBase, +
    <T extends DigitalTwinBase, V>
    void
    -
    addRealTimeModel(String modelName, +
    addRealTimeModel(String modelName, MessageProcessor<T,V> digitalTwinMessageProcessor, Class<T> dtType, Class<V> messageClass)
    -
    +
    Adds a real-time digital twin model to the workbench.
    +
    void
    +
    addSharedModelData(String modelName, + String key, + byte[] value)
    +
    +
    Add a key/value pair to SharedData for a model.
    +
    <T extends DigitalTwinBase, V>
    void
    addSimulationModel(String modelName, @@ -398,6 +415,16 @@

    Method Summary

    Retrieves messages logged by digital twin instances for a specified mdoel.
    + + +
    +
    Retrieve the global SharedData.
    +
    + + +
    +
    Retrieve the SharedData for a model.
    +
    @@ -460,6 +487,17 @@

    Workbench

    Instantiate the workbench.
    +
  • +
    +

    Workbench

    +
    public Workbench(int numSimulationWorkers)
    +
    Instantiate the workbench.
    +
    +
    Parameters:
    +
    numSimulationWorkers - the number of simulation workers to use. Default is Runtime.availableProcessors().
    +
    +
    +
  • @@ -695,6 +733,36 @@

    getAlertMessages

  • +
    +

    getSharedModelData

    +
    public SharedData getSharedModelData(String model) + throws WorkbenchException
    +
    Retrieve the SharedData for a model.
    +
    +
    Parameters:
    +
    model - the model name.
    +
    Returns:
    +
    the SharedData for a model.
    +
    Throws:
    +
    WorkbenchException - if an exception occurs while creating the working shared data.
    +
    +
    +
  • +
  • +
    +

    getSharedGlobalData

    +
    public SharedData getSharedGlobalData() + throws WorkbenchException
    +
    Retrieve the global SharedData.
    +
    +
    Returns:
    +
    the global SharedData of this workbench.
    +
    Throws:
    +
    WorkbenchException - if an exception occurs while creating the working shared data.
    +
    +
    +
  • +
  • generateModelSchema

    public String generateModelSchema(String modelName) @@ -751,6 +819,34 @@

    send

  • +
    +

    addSharedModelData

    +
    public void addSharedModelData(String modelName, + String key, + byte[] value)
    +
    Add a key/value pair to SharedData for a model.
    +
    +
    Parameters:
    +
    modelName - the model name.
    +
    key - the key.
    +
    value - the value.
    +
    +
    +
  • +
  • +
    +

    addGlobalModelData

    +
    public void addGlobalModelData(String key, + byte[] value)
    +
    Add a key/value pair to the global SharedData.
    +
    +
    Parameters:
    +
    key - the key.
    +
    value - the value.
    +
    +
    +
  • +
  • close

    public void close() diff --git a/docs/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.html b/docs/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.html index d76f832..23c4465 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.html +++ b/docs/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.html @@ -2,7 +2,7 @@ -WorkbenchException (digitaltwin-core-docs 3.0.4 API) +WorkbenchException (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/development/package-summary.html b/docs/com/scaleoutsoftware/digitaltwin/development/package-summary.html index 996f2e1..fcd247c 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/development/package-summary.html +++ b/docs/com/scaleoutsoftware/digitaltwin/development/package-summary.html @@ -2,7 +2,7 @@ -com.scaleoutsoftware.digitaltwin.development (digitaltwin-core-docs 3.0.4 API) +com.scaleoutsoftware.digitaltwin.development (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/com/scaleoutsoftware/digitaltwin/development/package-tree.html b/docs/com/scaleoutsoftware/digitaltwin/development/package-tree.html index 294e1fb..b449414 100644 --- a/docs/com/scaleoutsoftware/digitaltwin/development/package-tree.html +++ b/docs/com/scaleoutsoftware/digitaltwin/development/package-tree.html @@ -2,7 +2,7 @@ -com.scaleoutsoftware.digitaltwin.development Class Hierarchy (digitaltwin-core-docs 3.0.4 API) +com.scaleoutsoftware.digitaltwin.development Class Hierarchy (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build.gradle b/docs/digitaltwin-core-docs/build.gradle index e51b3be..21815d2 100644 --- a/docs/digitaltwin-core-docs/build.gradle +++ b/docs/digitaltwin-core-docs/build.gradle @@ -3,7 +3,7 @@ plugins { } group 'com.scaleout.digitaltwin' -version '3.0.4' +version '3.0.5' repositories { mavenCentral() diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/allclasses-index.html b/docs/digitaltwin-core-docs/build/docs/javadoc/allclasses-index.html index bddcce0..a1e1471 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/allclasses-index.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/allclasses-index.html @@ -2,7 +2,7 @@ -All Classes and Interfaces (digitaltwin-core-docs 3.0.4 API) +All Classes and Interfaces (digitaltwin-core-docs 3.0.5 API) @@ -67,6 +67,14 @@

    All Classes and Interfaces<
    Configuration for an alert provider.
    + +
    +
    Status of a cache operation.
    +
    + +
    +
    Represents a response from a SharedData operation.
    +
    A real-time digital twin of a data source.
    @@ -80,47 +88,56 @@

    All Classes and Interfaces<
    The InitContext is passed as a parameter to the DigitalTwinBase.init(InitContext) method of an initializing digital twin.

    - -
    + +
    +
    The InitSimulationContext is passed as a parameter to the SimulationProcessor.onInitSimulation(InitSimulationContext, DigitalTwinBase, Date) method of + digital twin instance when a simulation is initializing.
    +
    + +
    A messaged that was logged by a digital twin.
    - -
    + +
    Message list factory retrieves message lists for a MessageProcessor
    - -
    + +
    Processes messages for a real-time digital twin.
    - -
    + +
    Base class for the MessageProcessor to help with typing.
    - -
    + +
    The ModelSchema class is used as a Java object representation of the model.json schema file used for deploying a digital twin model to the real-time digital twin cloud service.
    - -
    + +
    An interface that can be used for persisting/retrieving the state of real-time digital twins.
    - -
    + +
    Available PersistenceProvider types.
    - -
    + +
    Context object that allows the user to send a message to a DataSource.
    - -
    + +
    The result from a message processor which indicates to update the state object or to ignore
    - -
    + +
    Marks a message as Delivered or not Delivered
    + +
    +
    SharedData is used to access a model's, or globally, shared cache.
    +
    The SimulationController interface is used to interact with the running DigitalTwin simulation.
    diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/allpackages-index.html b/docs/digitaltwin-core-docs/build/docs/javadoc/allpackages-index.html index 3040f57..cdc7533 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/allpackages-index.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/allpackages-index.html @@ -2,7 +2,7 @@ -All Packages (digitaltwin-core-docs 3.0.4 API) +All Packages (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/AlertMessage.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/AlertMessage.html index f552c72..75ab8d8 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/AlertMessage.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/AlertMessage.html @@ -2,7 +2,7 @@ -AlertMessage (digitaltwin-core-docs 3.0.4 API) +AlertMessage (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.html index 838eb7a..ae33977 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.html @@ -2,7 +2,7 @@ -AlertProviderConfiguration (digitaltwin-core-docs 3.0.4 API) +AlertProviderConfiguration (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/CacheOperationStatus.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/CacheOperationStatus.html new file mode 100644 index 0000000..9ff6c42 --- /dev/null +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/CacheOperationStatus.html @@ -0,0 +1,256 @@ + + + + +CacheOperationStatus (digitaltwin-core-docs 3.0.5 API) + + + + + + + + + + + + + + +
    + +
    +
    + +
    + +

    Enum Class CacheOperationStatus

    +
    +
    java.lang.Object +
    java.lang.Enum<CacheOperationStatus> +
    com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
    +
    +
    +
    +
    +
    All Implemented Interfaces:
    +
    Serializable, Comparable<CacheOperationStatus>, Constable
    +
    +
    +
    public enum CacheOperationStatus +extends Enum<CacheOperationStatus>
    +
    Status of a cache operation.
    +
    +
    + +
    +
    +
      + +
    • +
      +

      Enum Constant Details

      +
        +
      • +
        +

        ObjectRetrieved

        +
        public static final CacheOperationStatus ObjectRetrieved
        +
        The object was successfully retrieved.
        +
        +
      • +
      • +
        +

        ObjectPut

        +
        public static final CacheOperationStatus ObjectPut
        +
        The object was successfully added/updated.
        +
        +
      • +
      • +
        +

        ObjectDoesNotExist

        +
        public static final CacheOperationStatus ObjectDoesNotExist
        +
        The object could not be retrieved because it was not found.
        +
        +
      • +
      • +
        +

        ObjectRemoved

        +
        public static final CacheOperationStatus ObjectRemoved
        +
        The object was removed successfully.
        +
        +
      • +
      • +
        +

        CacheCleared

        +
        public static final CacheOperationStatus CacheCleared
        +
        The cache was cleared successfully.
        +
        +
      • +
      +
      +
    • + +
    • +
      +

      Method Details

      +
        +
      • +
        +

        values

        +
        public static CacheOperationStatus[] values()
        +
        Returns an array containing the constants of this enum class, in +the order they are declared.
        +
        +
        Returns:
        +
        an array containing the constants of this enum class, in the order they are declared
        +
        +
        +
      • +
      • +
        +

        valueOf

        +
        public static CacheOperationStatus valueOf(String name)
        +
        Returns the enum constant of this class with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this class. (Extraneous whitespace characters are +not permitted.)
        +
        +
        Parameters:
        +
        name - the name of the enum constant to be returned.
        +
        Returns:
        +
        the enum constant with the specified name
        +
        Throws:
        +
        IllegalArgumentException - if this enum class has no constant with the specified name
        +
        NullPointerException - if the argument is null
        +
        +
        +
      • +
      +
      +
    • +
    +
    + +
    +
    +
    + + diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/CacheResult.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/CacheResult.html new file mode 100644 index 0000000..9334a2c --- /dev/null +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/CacheResult.html @@ -0,0 +1,163 @@ + + + + +CacheResult (digitaltwin-core-docs 3.0.5 API) + + + + + + + + + + + + + + +
    + +
    +
    + +
    + +

    Interface CacheResult

    +
    +
    +
    +
    public interface CacheResult
    +
    Represents a response from a SharedData operation.
    +
    +
    +
      + +
    • +
      +

      Method Summary

      +
      +
      +
      +
      +
      Modifier and Type
      +
      Method
      +
      Description
      + + +
      +
      Gets the key or null to the object associated with the result.
      +
      + + +
      +
      Gets the status of the cache operation.
      +
      +
      byte[]
      + +
      +
      Get the object returned from a Get operation.
      +
      +
      +
      +
      +
      +
    • +
    +
    +
    +
      + +
    • +
      +

      Method Details

      +
        +
      • +
        +

        getKey

        +
        String getKey()
        +
        Gets the key or null to the object associated with the result.
        +
        +
        Returns:
        +
        the key or null.
        +
        +
        +
      • +
      • +
        +

        getValue

        +
        byte[] getValue()
        +
        Get the object returned from a Get operation.
        +
        +
        Returns:
        +
        the object or null.
        +
        +
        +
      • +
      • +
        +

        getStatus

        + +
        Gets the status of the cache operation.
        +
        +
        Returns:
        +
        the operation status.
        +
        +
        +
      • +
      +
      +
    • +
    +
    + +
    +
    +
    + + diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.html index d22f132..c013270 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.html @@ -2,7 +2,7 @@ -DigitalTwinBase (digitaltwin-core-docs 3.0.4 API) +DigitalTwinBase (digitaltwin-core-docs 3.0.5 API) @@ -123,7 +123,9 @@

    Constructor Summary

    Constructor
    Description
    -
     
    +
    +
    Default constructor.
    +

  • @@ -220,6 +222,7 @@

    Constructor Details

    DigitalTwinBase

    public DigitalTwinBase()
    +
    Default constructor.
    diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.html index e7de9da..71116ad 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.html @@ -2,7 +2,7 @@ -DigitalTwinTimerMessage (digitaltwin-core-docs 3.0.4 API) +DigitalTwinTimerMessage (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/InitContext.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/InitContext.html index 65bae14..4d362ae 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/InitContext.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/InitContext.html @@ -2,7 +2,7 @@ -InitContext (digitaltwin-core-docs 3.0.4 API) +InitContext (digitaltwin-core-docs 3.0.5 API) @@ -91,7 +91,9 @@

    Constructor Summary

    Constructor
    Description
    -
     
    +
    +
    Default constructor.
    +
    @@ -116,6 +118,16 @@

    Method Summary

    Get the Model identifier of the initializing digital twin instance.
    +
    abstract SharedData
    + +
    +
    Retrieve a SharedData accessor for globally shared data.
    +
    +
    abstract SharedData
    + +
    +
    Retrieve a SharedData accessor for this model's shared data.
    +
    startTimer(String timerName, Duration interval, @@ -145,6 +157,7 @@

    Constructor Details

    InitContext

    public InitContext()
    +
    Default constructor.
    @@ -179,6 +192,28 @@

    startTimer

  • +
    +

    getSharedModelData

    +
    public abstract SharedData getSharedModelData()
    +
    Retrieve a SharedData accessor for this model's shared data.
    +
    +
    Returns:
    +
    a SharedData instance.
    +
    +
    +
  • +
  • +
    +

    getSharedGlobalData

    +
    public abstract SharedData getSharedGlobalData()
    +
    Retrieve a SharedData accessor for globally shared data.
    +
    +
    Returns:
    +
    a SharedData instance.
    +
    +
    +
  • +
  • getId

    public abstract String getId()
    diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/InitSimulationContext.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/InitSimulationContext.html new file mode 100644 index 0000000..0640172 --- /dev/null +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/InitSimulationContext.html @@ -0,0 +1,148 @@ + + + + +InitSimulationContext (digitaltwin-core-docs 3.0.5 API) + + + + + + + + + + + + + + +
    + +
    +
    + +
    + +

    Interface InitSimulationContext

    +
    +
    +
    +
    public interface InitSimulationContext
    +
    The InitSimulationContext is passed as a parameter to the SimulationProcessor.onInitSimulation(InitSimulationContext, DigitalTwinBase, Date) method of + digital twin instance when a simulation is initializing.
    +
    +
    + +
    +
    +
      + +
    • +
      +

      Method Details

      +
        +
      • +
        +

        getSharedModelData

        +
        SharedData getSharedModelData()
        +
        Retrieve a SharedData accessor for this model's shared data.
        +
        +
        Returns:
        +
        a SharedData instance.
        +
        +
        +
      • +
      • +
        +

        getSharedGlobalData

        +
        SharedData getSharedGlobalData()
        +
        Retrieve a SharedData accessor for globally shared data.
        +
        +
        Returns:
        +
        a SharedData instance.
        +
        +
        +
      • +
      +
      +
    • +
    +
    + +
    +
    +
    + + diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/MessageFactory.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/MessageFactory.html index fd9882a..b9941e1 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/MessageFactory.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/MessageFactory.html @@ -2,7 +2,7 @@ -MessageFactory (digitaltwin-core-docs 3.0.4 API) +MessageFactory (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.html index 87c25e4..87308d2 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.html @@ -2,7 +2,7 @@ -MessageProcessor (digitaltwin-core-docs 3.0.4 API) +MessageProcessor (digitaltwin-core-docs 3.0.5 API) @@ -110,7 +110,9 @@

    Constructor Summary

    Constructor
    Description
    -
     
    +
    +
    Default constructor.
    +
  • @@ -160,6 +162,7 @@

    Constructor Details

    MessageProcessor

    public MessageProcessor()
    +
    Default constructor.
    diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.html index ab6edc5..d9eca63 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.html @@ -2,7 +2,7 @@ -MessageProcessorBase (digitaltwin-core-docs 3.0.4 API) +MessageProcessorBase (digitaltwin-core-docs 3.0.5 API) @@ -98,7 +98,9 @@

    Constructor Summary

    Constructor
    Description
    -
     
    +
    +
    Default constructor.
    +
    @@ -141,6 +143,7 @@

    Constructor Details

    MessageProcessorBase

    public MessageProcessorBase()
    +
    Default constructor.
    diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/ModelSchema.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/ModelSchema.html index 45f653c..dd17e2c 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/ModelSchema.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/ModelSchema.html @@ -2,7 +2,7 @@ -ModelSchema (digitaltwin-core-docs 3.0.4 API) +ModelSchema (digitaltwin-core-docs 3.0.5 API) @@ -96,12 +96,45 @@

    Constructor Summary

    Creates a model schema from a digital twin class, a message processor class, and a message class.
    -
    ModelSchema(String dtClass, +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + boolean emr)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, and a message class.
    +
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String ep)
    +
    +
    Model schema with a defined entry point.
    +
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String ep, + boolean emr)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, and a message class.
    +
    +
    ModelSchema(String dtClass, String mpClass, String msgClass, String adtName, PersistenceProviderType persistenceType, List<AlertProviderConfiguration> alertingProviders)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String adtName, + PersistenceProviderType persistenceType, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    Creates a model schema from a digital twin class, a message processor class, a message class, and alert provider configurations.
    @@ -113,24 +146,86 @@

    Constructor Summary

    String adtName, PersistenceProviderType persistenceType, List<AlertProviderConfiguration> alertingProviders)
    -
     
    -
    ModelSchema(String dtClass, +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    +
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String simulationProcessorClass, + String adtName, + PersistenceProviderType persistenceType, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    +
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String simulationProcessorClass, + String adtName, + String ep, + PersistenceProviderType persistenceType, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    +
    +
    ModelSchema(String dtClass, String mpClass, String msgClass, String spClass, + String ep, List<AlertProviderConfiguration> alertingProviders)
    Creates a model schema from a digital twin class, a message processor class, a message class, and alert provider configurations.
    -
    ModelSchema(String dtClass, +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String spClass, + String ep, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    ModelSchema(String dtClass, String mpClass, String msgClass, + String spClass, List<AlertProviderConfiguration> alertingProviders)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + String spClass, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    Creates a model schema from a digital twin class, a message processor class, a message class, and alert provider configurations.
    +
    ModelSchema(String dtClass, + String mpClass, + String msgClass, + List<AlertProviderConfiguration> alertingProviders)
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    @@ -161,30 +256,40 @@

    Method Summary

    Retrieve the Azure Digital Twin model name.
    - +
    -
    Retrieve the message processor type (a MessageProcessor implementation).
    +
    Retrieves the packaged model's entry point (fully-qualified class name -- FQCN -- of a Java main) for launching.
    - +
    -
    Retrieve the message type (JSON serializable message implementation).
    +
    Retrieve the message processor type (a MessageProcessor implementation).
    - +
    -
    Retrieve the digital twin model type (a DigitalTwinBase implementation).
    +
    Retrieve the message type (JSON serializable message implementation).
    - - + +
    -
    Retrieve the persistence provider type.
    +
    Retrieve the digital twin model type (a DigitalTwinBase implementation).
    - - + +
    +
    Retrieve the persistence provider type.
    +
    + + +
    Retrieve the simulation processor type (a SimulationProcessor implementation).
    +
    boolean
    + +
    +
    Retrieves the message recording enabled status.
    +
    boolean
    @@ -228,6 +333,59 @@

    ModelSchema

  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String ep)
    +
    Model schema with a defined entry point.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    ep - the invocation grid entry point.
    +
    +
    +
  • +
  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, and a message class.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • +
  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String ep, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, and a message class.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    ep - the invocation grid entry point.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • +
  • ModelSchema

    public ModelSchema(String dtClass, @@ -266,6 +424,74 @@

    ModelSchema

  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String spClass, + String ep, + List<AlertProviderConfiguration> alertingProviders)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    spClass - the simulation processor class implementation.
    +
    ep - the invocation grid entry point.
    +
    alertingProviders - the alerting provider configurations.
    +
    +
    +
  • +
  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String spClass, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    spClass - the simulation processor class implementation.
    +
    alertingProviders - the alerting provider configurations.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • +
  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String spClass, + String ep, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    spClass - the simulation processor class implementation.
    +
    alertingProviders - the alerting provider configurations.
    +
    ep - the invocation grid entry point.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • +
  • ModelSchema

    public ModelSchema(String dtClass, @@ -288,6 +514,30 @@

    ModelSchema

  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String adtName, + PersistenceProviderType persistenceType, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    adtName - the Azure Digital Twin model name.
    +
    persistenceType - the persistence provider type.
    +
    alertingProviders - the alerting provider configurations.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • +
  • ModelSchema

    public ModelSchema(String dtClass, @@ -297,6 +547,9 @@

    ModelSchema

    String adtName, PersistenceProviderType persistenceType, List<AlertProviderConfiguration> alertingProviders)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    Parameters:
    dtClass - the digital twin class implementation.
    @@ -309,6 +562,62 @@

    ModelSchema

  • +
  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String simulationProcessorClass, + String adtName, + PersistenceProviderType persistenceType, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    simulationProcessorClass - the simulation processor class implementation.
    +
    adtName - the Azure Digital Twin model name.
    +
    persistenceType - the persistence provider type.
    +
    alertingProviders - the alerting provider configurations.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • +
  • +
    +

    ModelSchema

    +
    public ModelSchema(String dtClass, + String mpClass, + String msgClass, + String simulationProcessorClass, + String adtName, + String ep, + PersistenceProviderType persistenceType, + List<AlertProviderConfiguration> alertingProviders, + boolean emr)
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    +
    +
    Parameters:
    +
    dtClass - the digital twin class implementation.
    +
    mpClass - the message processor class implementation.
    +
    msgClass - a JSON serializable message class.
    +
    simulationProcessorClass - the simulation processor class implementation.
    +
    adtName - the Azure Digital Twin model name.
    +
    persistenceType - the persistence provider type.
    +
    alertingProviders - the alerting provider configurations.
    +
    ep - the invocation grid entry point.
    +
    emr - enable message recording for this model.
    +
    +
    +
  • @@ -427,6 +736,29 @@

    getPersistenceProvider

    +
  • +
    +

    messageRecordingEnabled

    +
    public boolean messageRecordingEnabled()
    +
    Retrieves the message recording enabled status. True if this model should persist messages when message recording is active, + false otherwise.
    +
    +
    Returns:
    +
    True if message recording is enabled, false otherwise.
    +
    +
    +
  • +
  • +
    +

    getEntryPoint

    +
    public String getEntryPoint()
    +
    Retrieves the packaged model's entry point (fully-qualified class name -- FQCN -- of a Java main) for launching.
    +
    +
    Returns:
    +
    the entry point for launching.
    +
    +
    +
  • diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.html index 7f6fc37..214c380 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.html @@ -2,7 +2,7 @@ -PersistenceProvider (digitaltwin-core-docs 3.0.4 API) +PersistenceProvider (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.html index da4a79b..cff66a9 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.html @@ -2,7 +2,7 @@ -PersistenceProviderType (digitaltwin-core-docs 3.0.4 API) +PersistenceProviderType (digitaltwin-core-docs 3.0.5 API) @@ -109,6 +109,14 @@

    Enum Constant Summary

    Enum for the Azure Digital Twin service.
    + +
    +
    Enum for CosmosDB
    +
    + +
    +
    Enum for DynamoDB
    +
    Enum for SQLite
    @@ -118,7 +126,9 @@

    Enum Constant Summary

    Enum for SQLServer
    -
     
    +
    +
    Enum for an unconfigured PersistenceProvider
    +
    @@ -127,7 +137,7 @@

    Enum Constant Summary

    Method Summary

    -
    +
    Modifier and Type
    @@ -143,6 +153,16 @@

    Method Summary

    Return the PersistenceProviderType from a string value.
    + + +
    +
    Retrieve the name of the persistence provider type.
    +
    +
    int
    + +
    +
    Retrieve the ordinal value (used by the DTBuidler service).
    +
    @@ -182,6 +202,20 @@

    AzureDigitalTwinsService

  • +
    +

    CosmosDb

    +
    public static final PersistenceProviderType CosmosDb
    +
    Enum for CosmosDB
    +
    +
  • +
  • +
    +

    DynamoDb

    +
    public static final PersistenceProviderType DynamoDb
    +
    Enum for DynamoDB
    +
    +
  • +
  • SQLite

    public static final PersistenceProviderType SQLite
    @@ -199,6 +233,7 @@

    SQLServer

    Unconfigured

    public static final PersistenceProviderType Unconfigured
    +
    Enum for an unconfigured PersistenceProvider
  • @@ -241,6 +276,28 @@

    valueOf

  • +
    +

    getName

    +
    public String getName()
    +
    Retrieve the name of the persistence provider type.
    +
    +
    Returns:
    +
    the name of the persistence provider type.
    +
    +
    +
  • +
  • +
    +

    getServiceOrdinalValue

    +
    public int getServiceOrdinalValue()
    +
    Retrieve the ordinal value (used by the DTBuidler service).
    +
    +
    Returns:
    +
    the ordinal value.
    +
    +
    +
  • +
  • fromString

    public static PersistenceProviderType fromString(String name)
    diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.html index 383f87d..ea553fe 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.html @@ -2,7 +2,7 @@ -ProcessingContext (digitaltwin-core-docs 3.0.4 API) +ProcessingContext (digitaltwin-core-docs 3.0.5 API) @@ -103,7 +103,9 @@

    Constructor Summary

    Constructor
    Description
    -
     
    +
    +
    Default constructor.
    +
  • @@ -138,6 +140,16 @@

    Method Summary

    Returns the configured persistence provider or null if no persistence provider configuration can be found.
    +
    abstract SharedData
    + +
    +
    Retrieve a SharedData accessor for globally shared data.
    +
    +
    abstract SharedData
    + +
    +
    Retrieve a SharedData accessor for this model's shared data.
    +
    @@ -240,6 +252,7 @@

    Constructor Details

    ProcessingContext

    public ProcessingContext()
    +
    Default constructor.
    @@ -412,7 +425,7 @@

    sendAlert

    public abstract SendingResult sendAlert(String alertingProviderName, AlertMessage alert)

    - This method sends an alert message to supported systems. See "TODO: Link to docs" for more details on supported systems. + This method sends an alert message to supported systems.

    @@ -544,6 +557,28 @@

    getSimulationController

    +
  • +
    +

    getSharedModelData

    +
    public abstract SharedData getSharedModelData()
    +
    Retrieve a SharedData accessor for this model's shared data.
    +
    +
    Returns:
    +
    a SharedData instance.
    +
    +
    +
  • +
  • +
    +

    getSharedGlobalData

    +
    public abstract SharedData getSharedGlobalData()
    +
    Retrieve a SharedData accessor for globally shared data.
    +
    +
    Returns:
    +
    a SharedData instance.
    +
    +
    +
  • diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.html index 4d2073a..99cf30d 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.html @@ -2,7 +2,7 @@ -ProcessingResult (digitaltwin-core-docs 3.0.4 API) +ProcessingResult (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SendingResult.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SendingResult.html index 8d9d776..3bce6fe 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SendingResult.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SendingResult.html @@ -2,7 +2,7 @@ -SendingResult (digitaltwin-core-docs 3.0.4 API) +SendingResult (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SharedData.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SharedData.html new file mode 100644 index 0000000..a0da3b9 --- /dev/null +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SharedData.html @@ -0,0 +1,188 @@ + + + + +SharedData (digitaltwin-core-docs 3.0.5 API) + + + + + + + + + + + + + + +
    + +
    +
    + +
    + +

    Interface SharedData

    +
    +
    +
    +
    public interface SharedData
    +
    SharedData is used to access a model's, or globally, shared cache.
    +
    +
    +
      + +
    • +
      +

      Method Summary

      +
      +
      +
      +
      +
      Modifier and Type
      +
      Method
      +
      Description
      + + +
      +
      Clear the shared data cache.
      +
      + +
      get(String key)
      +
      +
      Retrieves an existing object from the cache.
      +
      + +
      put(String key, + byte[] value)
      +
      +
      Put a new key/value mapping into the cache.
      +
      + + +
      +
      Remove a key/value mapping from the cache.
      +
      +
      +
      +
      +
      +
    • +
    +
    +
    +
      + +
    • +
      +

      Method Details

      +
        +
      • +
        +

        get

        +
        CacheResult get(String key)
        +
        Retrieves an existing object from the cache.
        +
        +
        Parameters:
        +
        key - the key mapping to a value.
        +
        Returns:
        +
        A cache result.
        +
        +
        +
      • +
      • +
        +

        put

        +
        CacheResult put(String key, + byte[] value)
        +
        Put a new key/value mapping into the cache.
        +
        +
        Parameters:
        +
        key - the key mapping to a value.
        +
        value - the value.
        +
        Returns:
        +
        a cache result.
        +
        +
        +
      • +
      • +
        +

        remove

        +
        CacheResult remove(String key)
        +
        Remove a key/value mapping from the cache.
        +
        +
        Parameters:
        +
        key - the key mapping to a value.
        +
        Returns:
        +
        a cache result.
        +
        +
        +
      • +
      • +
        +

        clear

        +
        CacheResult clear()
        +
        Clear the shared data cache.
        +
        +
        Returns:
        +
        a cache result.
        +
        +
        +
      • +
      +
      +
    • +
    +
    + +
    +
    +
    + + diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SimulationController.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SimulationController.html index eab1111..df4c127 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SimulationController.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SimulationController.html @@ -2,7 +2,7 @@ -SimulationController (digitaltwin-core-docs 3.0.4 API) +SimulationController (digitaltwin-core-docs 3.0.5 API) @@ -115,41 +115,58 @@

    Method Summary

    Delay simulation processing for this DigitalTwin instance for a duration of time.
    -
    deleteInstance(String modelName, - String instanceId)
    +
    -
    Delete and remove a digital twin instance from simulation processing.
    +
    + Delay simulation processing for this DigitalTwin instance, indefinitely.
    - +
    deleteInstance(String modelName, + String instanceId)
    -
    Delete and remove this digital twin instance from simulation processing.
    +
    Delete and remove a digital twin instance from simulation processing.
    -
    emitTelemetry(String modelName, - byte[] telemetryMessage)
    +
    +
    Delete and remove this digital twin instance from simulation processing.
    +
    + +
    emitTelemetry(String modelName, + byte[] telemetryMessage)
    +
    Asynchronously send a JSON serialized message to a DigitalTwin instance that will be processed by the DigitalTwin models MessageProcessor.processMessages(ProcessingContext, DigitalTwinBase, Iterable) method.
    - -
    emitTelemetry(String modelName, + +
    emitTelemetry(String modelName, Object jsonSerializableMessage)
    -
    +
    Asynchronously send a JSON serializable message to a DigitalTwin instance that will be processed by the DigitalTwin models MessageProcessor.processMessages(ProcessingContext, DigitalTwinBase, Iterable) method.
    + + +
    +
    + Retrieves the simulation start time.
    +
    Retrieves the current simulation time increment.
    - - +
    void
    +
    +
    Run this instance during this simulation step.
    +
    + + +
    Stop the simulation.
    @@ -180,6 +197,19 @@

    getSimulationTimeIncrement

  • +
    +

    getSimulationStartTime

    +
    Date getSimulationStartTime()
    +

    + Retrieves the simulation start time. +

    +
    +
    Returns:
    +
    the simulation start time.
    +
    +
    +
  • +
  • delay

    SendingResult delay(Duration duration)
    @@ -219,6 +249,24 @@

    delay

  • +
    +

    delayIndefinitely

    +
    SendingResult delayIndefinitely()
    +

    + Delay simulation processing for this DigitalTwin instance, indefinitely. +

    + +

    + Simulation processing will be delayed until this instance is run with runThisInstance(). +

    +
    +
    Returns:
    +
    SendingResult.Handled if the delay was processed or SendingResult.NotHandled + if the delay was not processed.
    +
    +
    +
  • +
  • emitTelemetry

    SendingResult emitTelemetry(String modelName, @@ -348,6 +396,17 @@

    deleteThisInstance

  • +
    +

    runThisInstance

    +
    void runThisInstance()
    +
    Run this instance during this simulation step. The instance will be run using the models SimulationProcessor.processModel(ProcessingContext, DigitalTwinBase, Date) + implementation. + + This will cause the simulation sub-system to run this instance regardless of the instances current + DigitalTwinBase.NextSimulationTime.
    +
    +
  • +
  • stopSimulation

    SimulationStatus stopSimulation()
    diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.html index 7f4fc19..64de0a7 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.html @@ -2,7 +2,7 @@ -SimulationProcessor (digitaltwin-core-docs 3.0.4 API) +SimulationProcessor (digitaltwin-core-docs 3.0.5 API) @@ -107,7 +107,9 @@

    Constructor Summary

    Constructor
    Description
    -
     
    +
    +
    Default constructor.
    +
  • @@ -116,17 +118,25 @@

    Constructor Summary

    Method Summary

    -
    +
    Modifier and Type
    Method
    Description
    - -
    processModel(ProcessingContext context, + +
    onInitSimulation(InitSimulationContext context, + T instance, + Date epoch)
    +
    +
    + Optional method that is called per-instance when a simulation is started.
    +
    + +
    processModel(ProcessingContext context, T instance, Date epoch)
    -
    +
    Processes simulation events for a real-time digital twin.
    @@ -150,6 +160,7 @@

    Constructor Details

    SimulationProcessor

    public SimulationProcessor()
    +
    Default constructor.
    @@ -178,6 +189,36 @@

    +

    onInitSimulation

    +
    public ProcessingResult onInitSimulation(InitSimulationContext context, + T instance, + Date epoch)
    +

    + Optional method that is called per-instance when a simulation is started. Default behavior is a no-op. +

    + +

    + onInitSimulation can be used when internal digital twin starting state is set outside the context of a digital twins init method and may be changed + between simulation runs. +

    +
      +
    • Set variables in global or shared data.
    • +
    • Run a simulation.
    • +
    • onInitSimulation is called (per-instance) and digital twin instances set internal state based on the values in shared data.
    • +
    • Complete simulation and evaluate the result.
    • +
    +
    +
    Parameters:
    +
    context - The simulation init context.
    +
    instance - The digital twin instance.
    +
    epoch - the simulation start time.
    +
    Returns:
    +
    ProcessingResult.UpdateDigitalTwin or ProcessingResult.NoUpdate. Default behavior: ProcessingResult.NoUpdate.
    +
    +
    + diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.html index c0f7ab0..95a1b09 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.html @@ -2,7 +2,7 @@ -SimulationStatus (digitaltwin-core-docs 3.0.4 API) +SimulationStatus (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.html index eb5dd4c..9cb2a82 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.html @@ -2,7 +2,7 @@ -TimerActionResult (digitaltwin-core-docs 3.0.4 API) +TimerActionResult (digitaltwin-core-docs 3.0.5 API) @@ -255,7 +255,8 @@

    fromOrdinal

    + 2 = FailedNoSuchTimer, 3 = FailedTimerAlreadyExists, + 4 = FailedInternalError
    Parameters:
    val - the ordinal value.
    diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerHandler.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerHandler.html index c07d3f3..60c2c72 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerHandler.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerHandler.html @@ -2,7 +2,7 @@ -TimerHandler (digitaltwin-core-docs 3.0.4 API) +TimerHandler (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.html index 27958fe..b2824fe 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.html @@ -2,7 +2,7 @@ -TimerMetadata (digitaltwin-core-docs 3.0.4 API) +TimerMetadata (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerType.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerType.html index 3264684..cef4477 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerType.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/TimerType.html @@ -2,7 +2,7 @@ -TimerType (digitaltwin-core-docs 3.0.4 API) +TimerType (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/package-summary.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/package-summary.html index db0c1b6..9fa1f27 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/package-summary.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/package-summary.html @@ -2,7 +2,7 @@ -com.scaleoutsoftware.digitaltwin.core (digitaltwin-core-docs 3.0.4 API) +com.scaleoutsoftware.digitaltwin.core (digitaltwin-core-docs 3.0.5 API) @@ -83,6 +83,14 @@

    Package
    Configuration for an alert provider.
    + +
    +
    Status of a cache operation.
    +
    + +
    +
    Represents a response from a SharedData operation.
    +
    A real-time digital twin of a data source.
    @@ -96,43 +104,52 @@

    Package
    The InitContext is passed as a parameter to the DigitalTwinBase.init(InitContext) method of an initializing digital twin.

    - +
    +
    The InitSimulationContext is passed as a parameter to the SimulationProcessor.onInitSimulation(InitSimulationContext, DigitalTwinBase, Date) method of + digital twin instance when a simulation is initializing.
    +
    + +
    Message list factory retrieves message lists for a MessageProcessor
    - -
    + +
    Processes messages for a real-time digital twin.
    - -
    + +
    Base class for the MessageProcessor to help with typing.
    - -
    + +
    The ModelSchema class is used as a Java object representation of the model.json schema file used for deploying a digital twin model to the real-time digital twin cloud service.
    - -
    + +
    An interface that can be used for persisting/retrieving the state of real-time digital twins.
    - -
    + +
    Available PersistenceProvider types.
    - -
    + +
    Context object that allows the user to send a message to a DataSource.
    - -
    + +
    The result from a message processor which indicates to update the state object or to ignore
    - -
    + +
    Marks a message as Delivered or not Delivered
    + +
    +
    SharedData is used to access a model's, or globally, shared cache.
    +
    The SimulationController interface is used to interact with the running DigitalTwin simulation.
    diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/package-tree.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/package-tree.html index 21271e7..d2f2c59 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/package-tree.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/core/package-tree.html @@ -2,7 +2,7 @@ -com.scaleoutsoftware.digitaltwin.core Class Hierarchy (digitaltwin-core-docs 3.0.4 API) +com.scaleoutsoftware.digitaltwin.core Class Hierarchy (digitaltwin-core-docs 3.0.5 API) @@ -79,8 +79,11 @@

    Class Hierarchy

    Interface Hierarchy

    @@ -92,6 +95,7 @@

    Enum Class Hierarchy

    • java.lang.Enum<E> (implements java.lang.Comparable<T>, java.lang.constant.Constable, java.io.Serializable)
        +
      • com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
      • com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType (implements java.io.Serializable)
      • com.scaleoutsoftware.digitaltwin.core.ProcessingResult
      • com.scaleoutsoftware.digitaltwin.core.SendingResult
      • diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/LogMessage.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/LogMessage.html index 4ec280c..f94cc8d 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/LogMessage.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/LogMessage.html @@ -2,7 +2,7 @@ -LogMessage (digitaltwin-core-docs 3.0.4 API) +LogMessage (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.html index b80b113..de93f73 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.html @@ -2,7 +2,7 @@ -SimulationEventResult (digitaltwin-core-docs 3.0.4 API) +SimulationEventResult (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/SimulationStep.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/SimulationStep.html index 9695d0f..cc34461 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/SimulationStep.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/SimulationStep.html @@ -2,7 +2,7 @@ -SimulationStep (digitaltwin-core-docs 3.0.4 API) +SimulationStep (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/Workbench.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/Workbench.html index 52e4e46..cc54152 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/Workbench.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/Workbench.html @@ -2,7 +2,7 @@ -Workbench (digitaltwin-core-docs 3.0.4 API) +Workbench (digitaltwin-core-docs 3.0.5 API) @@ -321,6 +321,10 @@

        Constructor Summary

        Instantiate the workbench.
        +
        Workbench(int numSimulationWorkers)
        +
        +
        Instantiate the workbench.
        +
    @@ -342,21 +346,34 @@

    Method Summary

    Adds an alert provider configuration to the specified model on this workbench.
    void
    -
    addInstance(String modelName, +
    addGlobalModelData(String key, + byte[] value)
    +
    +
    Add a key/value pair to the global SharedData.
    +
    +
    void
    +
    addInstance(String modelName, String id, DigitalTwinBase instance)
    -
    +
    Adds a digital twin instance to the workbench.
    -
    <T extends DigitalTwinBase, +
    <T extends DigitalTwinBase, V>
    void
    -
    addRealTimeModel(String modelName, +
    addRealTimeModel(String modelName, MessageProcessor<T,V> digitalTwinMessageProcessor, Class<T> dtType, Class<V> messageClass)
    -
    +
    Adds a real-time digital twin model to the workbench.
    +
    void
    +
    addSharedModelData(String modelName, + String key, + byte[] value)
    +
    +
    Add a key/value pair to SharedData for a model.
    +
    <T extends DigitalTwinBase, V>
    void
    addSimulationModel(String modelName, @@ -398,6 +415,16 @@

    Method Summary

    Retrieves messages logged by digital twin instances for a specified mdoel.
    + + +
    +
    Retrieve the global SharedData.
    +
    + + +
    +
    Retrieve the SharedData for a model.
    +
    @@ -460,6 +487,17 @@

    Workbench

    Instantiate the workbench.
    +
  • +
    +

    Workbench

    +
    public Workbench(int numSimulationWorkers)
    +
    Instantiate the workbench.
    +
    +
    Parameters:
    +
    numSimulationWorkers - the number of simulation workers to use. Default is Runtime.availableProcessors().
    +
    +
    +
  • @@ -695,6 +733,36 @@

    getAlertMessages

  • +
    +

    getSharedModelData

    +
    public SharedData getSharedModelData(String model) + throws WorkbenchException
    +
    Retrieve the SharedData for a model.
    +
    +
    Parameters:
    +
    model - the model name.
    +
    Returns:
    +
    the SharedData for a model.
    +
    Throws:
    +
    WorkbenchException - if an exception occurs while creating the working shared data.
    +
    +
    +
  • +
  • +
    +

    getSharedGlobalData

    +
    public SharedData getSharedGlobalData() + throws WorkbenchException
    +
    Retrieve the global SharedData.
    +
    +
    Returns:
    +
    the global SharedData of this workbench.
    +
    Throws:
    +
    WorkbenchException - if an exception occurs while creating the working shared data.
    +
    +
    +
  • +
  • generateModelSchema

    public String generateModelSchema(String modelName) @@ -751,6 +819,34 @@

    send

  • +
    +

    addSharedModelData

    +
    public void addSharedModelData(String modelName, + String key, + byte[] value)
    +
    Add a key/value pair to SharedData for a model.
    +
    +
    Parameters:
    +
    modelName - the model name.
    +
    key - the key.
    +
    value - the value.
    +
    +
    +
  • +
  • +
    +

    addGlobalModelData

    +
    public void addGlobalModelData(String key, + byte[] value)
    +
    Add a key/value pair to the global SharedData.
    +
    +
    Parameters:
    +
    key - the key.
    +
    value - the value.
    +
    +
    +
  • +
  • close

    public void close() diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.html index d76f832..23c4465 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.html @@ -2,7 +2,7 @@ -WorkbenchException (digitaltwin-core-docs 3.0.4 API) +WorkbenchException (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/package-summary.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/package-summary.html index 996f2e1..fcd247c 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/package-summary.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/package-summary.html @@ -2,7 +2,7 @@ -com.scaleoutsoftware.digitaltwin.development (digitaltwin-core-docs 3.0.4 API) +com.scaleoutsoftware.digitaltwin.development (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/package-tree.html b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/package-tree.html index 294e1fb..b449414 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/package-tree.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/com/scaleoutsoftware/digitaltwin/development/package-tree.html @@ -2,7 +2,7 @@ -com.scaleoutsoftware.digitaltwin.development Class Hierarchy (digitaltwin-core-docs 3.0.4 API) +com.scaleoutsoftware.digitaltwin.development Class Hierarchy (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/help-doc.html b/docs/digitaltwin-core-docs/build/docs/javadoc/help-doc.html index 2af3cbe..16c9fe8 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/help-doc.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/help-doc.html @@ -2,7 +2,7 @@ -API Help (digitaltwin-core-docs 3.0.4 API) +API Help (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/index-all.html b/docs/digitaltwin-core-docs/build/docs/javadoc/index-all.html index e149a6e..282504b 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/index-all.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/index-all.html @@ -2,7 +2,7 @@ -Index (digitaltwin-core-docs 3.0.4 API) +Index (digitaltwin-core-docs 3.0.5 API) @@ -56,6 +56,10 @@

    A

    Adds an alert provider configuration to the specified model on this workbench.
    +
    addGlobalModelData(String, byte[]) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
    +
    +
    Add a key/value pair to the global SharedData.
    +
    addInstance(String, String, DigitalTwinBase) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
    Adds a digital twin instance to the workbench.
    @@ -64,6 +68,10 @@

    A

    Adds a real-time digital twin model to the workbench.
    +
    addSharedModelData(String, String, byte[]) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
    +
    +
    Add a key/value pair to SharedData for a model.
    +
    addSimulationModel(String, MessageProcessor<T, V>, SimulationProcessor<T>, Class<T>, Class<V>) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
    Adds a simulation digital twin model to the workbench.
    @@ -95,6 +103,22 @@

    A

  • C

    +
    CacheCleared - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
    +
    +
    The cache was cleared successfully.
    +
    +
    CacheOperationStatus - Enum Class in com.scaleoutsoftware.digitaltwin.core
    +
    +
    Status of a cache operation.
    +
    +
    CacheResult - Interface in com.scaleoutsoftware.digitaltwin.core
    +
    +
    Represents a response from a SharedData operation.
    +
    +
    clear() - Method in interface com.scaleoutsoftware.digitaltwin.core.SharedData
    +
    +
    Clear the shared data cache.
    +
    close() - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
     
    com.scaleoutsoftware.digitaltwin.core - package com.scaleoutsoftware.digitaltwin.core
    @@ -105,6 +129,10 @@

    C

    Digital twin development API - Develop and test simulation/real-time digital twins.
    +
    CosmosDb - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
    +
    +
    Enum for CosmosDB
    +
    createInstance(String, String, T) - Method in interface com.scaleoutsoftware.digitaltwin.core.SimulationController
    Create a new digital twin instance for simulation processing.
    @@ -125,6 +153,11 @@

    D

    Delay simulation processing for this DigitalTwin instance for a duration of time.
    +
    delayIndefinitely() - Method in interface com.scaleoutsoftware.digitaltwin.core.SimulationController
    +
    +
    + Delay simulation processing for this DigitalTwin instance, indefinitely.
    +
    deleteInstance(String, String) - Method in interface com.scaleoutsoftware.digitaltwin.core.SimulationController
    Delete and remove a digital twin instance from simulation processing.
    @@ -138,7 +171,9 @@

    D

    A real-time digital twin of a data source.
    DigitalTwinBase() - Constructor for class com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase
    -
     
    +
    +
    Default constructor.
    +
    DigitalTwinTimerMessage - Class in com.scaleoutsoftware.digitaltwin.core
    A message sent to a digital twin instance's message processor.
    @@ -147,6 +182,10 @@

    D

    Construct a digital twin timer message.
    +
    DynamoDb - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
    +
    +
    Enum for DynamoDB
    +

    E

    @@ -212,6 +251,10 @@

    G

    Generates a ModelSchema for the parameter modelName and writes the schema to a file on the file system.
    +
    get(String) - Method in interface com.scaleoutsoftware.digitaltwin.core.SharedData
    +
    +
    Retrieves an existing object from the cache.
    +
    getAlertMessages(String, String) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
    Retrieves alert messages from digital twin instances.
    @@ -248,6 +291,10 @@

    G

    Retrieve the entity ID for this alert provider configuration.
    +
    getEntryPoint() - Method in class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    +
    +
    Retrieves the packaged model's entry point (fully-qualified class name -- FQCN -- of a Java main) for launching.
    +
    getId() - Method in class com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase
    The identifier of this DigitalTwin.
    @@ -284,6 +331,10 @@

    G

    Retrieve the integration key for this alert provider configuration.
    +
    getKey() - Method in interface com.scaleoutsoftware.digitaltwin.core.CacheResult
    +
    +
    Gets the key or null to the object associated with the result.
    +
    getLoggedMessages(String, long) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
    Retrieves messages logged by digital twin instances for a specified mdoel.
    @@ -326,6 +377,10 @@

    G

    Retrieve the name of this alert provider configuration.
    +
    getName() - Method in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
    +
    +
    Retrieve the name of the persistence provider type.
    +
    getNextSimulationTimeMs() - Method in class com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase
    Retrieve the next simulation time in milliseconds.
    @@ -374,6 +429,10 @@

    G

    Retrieves a future that will return a property value for a RTDT instance or null if the property doesn't exist.
    +
    getServiceOrdinalValue() - Method in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
    +
    +
    Retrieve the ordinal value (used by the DTBuidler service).
    +
    getSeverity() - Method in class com.scaleoutsoftware.digitaltwin.core.AlertMessage
    Retrieve the severity for this alert message.
    @@ -382,6 +441,38 @@

    G

    Retrieve the severity of this log message.
    +
    getSharedGlobalData() - Method in class com.scaleoutsoftware.digitaltwin.core.InitContext
    +
    +
    Retrieve a SharedData accessor for globally shared data.
    +
    +
    getSharedGlobalData() - Method in interface com.scaleoutsoftware.digitaltwin.core.InitSimulationContext
    +
    +
    Retrieve a SharedData accessor for globally shared data.
    +
    +
    getSharedGlobalData() - Method in class com.scaleoutsoftware.digitaltwin.core.ProcessingContext
    +
    +
    Retrieve a SharedData accessor for globally shared data.
    +
    +
    getSharedGlobalData() - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
    +
    +
    Retrieve the global SharedData.
    +
    +
    getSharedModelData() - Method in class com.scaleoutsoftware.digitaltwin.core.InitContext
    +
    +
    Retrieve a SharedData accessor for this model's shared data.
    +
    +
    getSharedModelData() - Method in interface com.scaleoutsoftware.digitaltwin.core.InitSimulationContext
    +
    +
    Retrieve a SharedData accessor for this model's shared data.
    +
    +
    getSharedModelData() - Method in class com.scaleoutsoftware.digitaltwin.core.ProcessingContext
    +
    +
    Retrieve a SharedData accessor for this model's shared data.
    +
    +
    getSharedModelData(String) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
    +
    +
    Retrieve the SharedData for a model.
    +
    getSimulationController() - Method in class com.scaleoutsoftware.digitaltwin.core.ProcessingContext
    Retrieve the running SimulationController or null if no simulation is running.
    @@ -390,11 +481,20 @@

    G

    Retrieve the simulation processor type (a SimulationProcessor implementation).
    +
    getSimulationStartTime() - Method in interface com.scaleoutsoftware.digitaltwin.core.SimulationController
    +
    +
    + Retrieves the simulation start time.
    +
    getSimulationTimeIncrement() - Method in interface com.scaleoutsoftware.digitaltwin.core.SimulationController
    Retrieves the current simulation time increment.
    +
    getStatus() - Method in interface com.scaleoutsoftware.digitaltwin.core.CacheResult
    +
    +
    Gets the status of the cache operation.
    +
    getStatus() - Method in class com.scaleoutsoftware.digitaltwin.development.SimulationStep
    Retrieve the SimulationStatus of the simulation interval.
    @@ -451,6 +551,10 @@

    G

    Retrieve the URL for this alert provider configuration.
    +
    getValue() - Method in interface com.scaleoutsoftware.digitaltwin.core.CacheResult
    +
    +
    Get the object returned from a Get operation.
    +

    H

    @@ -475,12 +579,19 @@

    I

    digital twin.
    InitContext() - Constructor for class com.scaleoutsoftware.digitaltwin.core.InitContext
    -
     
    +
    +
    Default constructor.
    +
    initializeSimulation(long, long, long) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
    Initializes the simulation so that each interval can be run separately by calling the Workbench.step() function.
    +
    InitSimulationContext - Interface in com.scaleoutsoftware.digitaltwin.core
    +
    +
    The InitSimulationContext is passed as a parameter to the SimulationProcessor.onInitSimulation(InitSimulationContext, DigitalTwinBase, Date) method of + digital twin instance when a simulation is initializing.
    +
    InstanceRequestedStop - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.SimulationStatus
    A digital twin instance has requested the simulation to stop by calling SimulationController.stopSimulation()
    @@ -512,13 +623,21 @@

    M

    Processes messages for a real-time digital twin.
    MessageProcessor() - Constructor for class com.scaleoutsoftware.digitaltwin.core.MessageProcessor
    -
     
    +
    +
    Default constructor.
    +
    MessageProcessorBase<T extends DigitalTwinBase> - Class in com.scaleoutsoftware.digitaltwin.core
    Base class for the MessageProcessor to help with typing.
    MessageProcessorBase() - Constructor for class com.scaleoutsoftware.digitaltwin.core.MessageProcessorBase
    -
     
    +
    +
    Default constructor.
    +
    +
    messageRecordingEnabled() - Method in class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    +
    +
    Retrieves the message recording enabled status.
    +
    Model - Variable in class com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase
    The model this twin instance belongs to.
    @@ -532,18 +651,66 @@

    M

    Creates a model schema from a digital twin class, a message processor class, and a message class.
    +
    ModelSchema(String, String, String, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    +
    +
    Creates a model schema from a digital twin class, a message processor class, and a message class.
    +
    +
    ModelSchema(String, String, String, String) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    +
    +
    Model schema with a defined entry point.
    +
    +
    ModelSchema(String, String, String, String, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    +
    +
    Creates a model schema from a digital twin class, a message processor class, and a message class.
    +
    ModelSchema(String, String, String, String, PersistenceProviderType, List<AlertProviderConfiguration>) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    Creates a model schema from a digital twin class, a message processor class, a message class, and alert provider configurations.
    +
    ModelSchema(String, String, String, String, PersistenceProviderType, List<AlertProviderConfiguration>, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    ModelSchema(String, String, String, String, String, PersistenceProviderType, List<AlertProviderConfiguration>) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    -
     
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    +
    +
    ModelSchema(String, String, String, String, String, PersistenceProviderType, List<AlertProviderConfiguration>, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    +
    +
    ModelSchema(String, String, String, String, String, String, PersistenceProviderType, List<AlertProviderConfiguration>, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
    +
    +
    ModelSchema(String, String, String, String, String, List<AlertProviderConfiguration>) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    +
    ModelSchema(String, String, String, String, String, List<AlertProviderConfiguration>, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    ModelSchema(String, String, String, String, List<AlertProviderConfiguration>) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    Creates a model schema from a digital twin class, a message processor class, a message class, and alert provider configurations.
    +
    ModelSchema(String, String, String, String, List<AlertProviderConfiguration>, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    +
    +
    Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
    +
    ModelSchema(String, String, String, List<AlertProviderConfiguration>) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
    Creates a model schema from a digital twin class, a message processor class, a message class, and @@ -575,10 +742,31 @@

    N

    O

    +
    ObjectDoesNotExist - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
    +
    +
    The object could not be retrieved because it was not found.
    +
    +
    ObjectPut - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
    +
    +
    The object was successfully added/updated.
    +
    +
    ObjectRemoved - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
    +
    +
    The object was removed successfully.
    +
    +
    ObjectRetrieved - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
    +
    +
    The object was successfully retrieved.
    +
    OneTime - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.TimerType
    This timer should trigger one time.
    +
    onInitSimulation(InitSimulationContext, T, Date) - Method in class com.scaleoutsoftware.digitaltwin.core.SimulationProcessor
    +
    +
    + Optional method that is called per-instance when a simulation is started.
    +
    onTimedMessage(String, T, ProcessingContext) - Method in interface com.scaleoutsoftware.digitaltwin.core.TimerHandler
    Callback to handle a timer message.
    @@ -607,7 +795,9 @@

    P

    Context object that allows the user to send a message to a DataSource.
    ProcessingContext() - Constructor for class com.scaleoutsoftware.digitaltwin.core.ProcessingContext
    -
     
    +
    +
    Default constructor.
    +
    ProcessingResult - Enum Class in com.scaleoutsoftware.digitaltwin.core
    The result from a message processor which indicates to update the state object or to ignore
    @@ -628,6 +818,10 @@

    P

    Processes simulation events for a real-time digital twin.
    +
    put(String, byte[]) - Method in interface com.scaleoutsoftware.digitaltwin.core.SharedData
    +
    +
    Put a new key/value mapping into the cache.
    +

    R

    @@ -635,6 +829,10 @@

    R

    This timer should reoccur on a schedule.
    +
    remove(String) - Method in interface com.scaleoutsoftware.digitaltwin.core.SharedData
    +
    +
    Remove a key/value mapping from the cache.
    +
    Running - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.SimulationStatus
    The simulation is running.
    @@ -643,6 +841,10 @@

    R

    Runs a simulation from the given startTime until the given endTime OR there is no more work to do.
    +
    runThisInstance() - Method in interface com.scaleoutsoftware.digitaltwin.core.SimulationController
    +
    +
    Run this instance during this simulation step.
    +

    S

    @@ -698,6 +900,10 @@

    S

    Set the next simulation time in milliseconds.
    +
    SharedData - Interface in com.scaleoutsoftware.digitaltwin.core
    +
    +
    SharedData is used to access a model's, or globally, shared cache.
    +
    SimulationController - Interface in com.scaleoutsoftware.digitaltwin.core
    The SimulationController interface is used to interact with the running DigitalTwin simulation.
    @@ -713,7 +919,9 @@

    S

    Processes simulation events for a digital twin.
    SimulationProcessor() - Constructor for class com.scaleoutsoftware.digitaltwin.core.SimulationProcessor
    -
     
    +
    +
    Default constructor.
    +
    SimulationStatus - Enum Class in com.scaleoutsoftware.digitaltwin.core
    The status of a simulation.
    @@ -793,7 +1001,9 @@

    T

    U

    Unconfigured - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
    -
     
    +
    +
    Enum for an unconfigured PersistenceProvider
    +
    UnexpectedChangeInConfiguration - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.SimulationStatus
    There was a runtime-change of simulation configuration.
    @@ -825,6 +1035,10 @@

    U

    V

    +
    valueOf(String) - Static method in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
    +
    +
    Returns the enum constant of this class with the specified name.
    +
    valueOf(String) - Static method in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
    Returns the enum constant of this class with the specified name.
    @@ -849,6 +1063,11 @@

    V

    Returns the enum constant of this class with the specified name.
    +
    values() - Static method in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
    +
    +
    Returns an array containing the constants of this enum class, in +the order they are declared.
    +
    values() - Static method in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
    Returns an array containing the constants of this enum class, in @@ -890,6 +1109,10 @@

    W

    Instantiate the workbench.
    +
    Workbench(int) - Constructor for class com.scaleoutsoftware.digitaltwin.development.Workbench
    +
    +
    Instantiate the workbench.
    +
    WorkbenchException - Exception in com.scaleoutsoftware.digitaltwin.development
    A Workbench exception indicates that a real-time or simulated twin caused an exception.
    diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/index.html b/docs/digitaltwin-core-docs/build/docs/javadoc/index.html index efbce74..c1028e2 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/index.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/index.html @@ -2,7 +2,7 @@ -Overview (digitaltwin-core-docs 3.0.4 API) +Overview (digitaltwin-core-docs 3.0.5 API) @@ -47,7 +47,7 @@
    -

    digitaltwin-core-docs 3.0.4 API

    +

    digitaltwin-core-docs 3.0.5 API

    Packages
    diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/member-search-index.js b/docs/digitaltwin-core-docs/build/docs/javadoc/member-search-index.js index 13931aa..a4c179e 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/member-search-index.js +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/member-search-index.js @@ -1 +1 @@ -memberSearchIndex = [{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addAlertProvider(String, AlertProviderConfiguration)","u":"addAlertProvider(java.lang.String,com.scaleoutsoftware.digitaltwin.core.AlertProviderConfiguration)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addInstance(String, String, DigitalTwinBase)","u":"addInstance(java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addRealTimeModel(String, MessageProcessor, Class, Class)","u":"addRealTimeModel(java.lang.String,com.scaleoutsoftware.digitaltwin.core.MessageProcessor,java.lang.Class,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addSimulationModel(String, MessageProcessor, SimulationProcessor, Class, Class)","u":"addSimulationModel(java.lang.String,com.scaleoutsoftware.digitaltwin.core.MessageProcessor,com.scaleoutsoftware.digitaltwin.core.SimulationProcessor,java.lang.Class,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"AlertMessage(String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"AlertMessage(String, String, String, HashMap)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.util.HashMap)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"AlertProviderConfiguration(String, String, String, String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"AzureDigitalTwinsService"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"close()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"createInstance(String, String, T)","u":"createInstance(java.lang.String,java.lang.String,T)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"createInstanceFromPersistenceStore(String, String)","u":"createInstanceFromPersistenceStore(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"createInstanceFromPersistenceStore(String, String, T)","u":"createInstanceFromPersistenceStore(java.lang.String,java.lang.String,T)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"delay(Duration)","u":"delay(java.time.Duration)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"deleteInstance(String, String)","u":"deleteInstance(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"deleteThisInstance()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"DigitalTwinBase()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"DigitalTwinTimerMessage(String, String, int, String, TimerType)","u":"%3Cinit%3E(java.lang.String,java.lang.String,int,java.lang.String,com.scaleoutsoftware.digitaltwin.core.TimerType)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"emitTelemetry(String, byte[])","u":"emitTelemetry(java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"emitTelemetry(String, Object)","u":"emitTelemetry(java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"EndTimeReached"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"Enqueued"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedInternalError"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedNoSuchTimer"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedTimerAlreadyExists"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedTooManyTimers"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"fromOrdinal(int)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"fromOrdinal(int)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"fromString(String)","u":"fromString(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"generateModelSchema(String)","u":"generateModelSchema(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"generateModelSchema(String, String)","u":"generateModelSchema(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getAlertMessages(String, String)","u":"getAlertMessages(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getAlertProviders()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getAlertProviderType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getAssemblyName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getAzureDigitalTwinModelName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getCurrentTime()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getDataSourceId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getDigitalTwinModel()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getEntityId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"getId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"getId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageFactory","l":"getIncomingMessages()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstance(String, String)","u":"getInstance(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstanceAsync(String, String)","u":"getInstanceAsync(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstanceIds(String)","u":"getInstanceIds(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstanceIdsAsync(String)","u":"getInstanceIdsAsync(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getInstances(String)","u":"getInstances(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getIntegrationKey()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getLoggedMessages(String, long)","u":"getLoggedMessages(java.lang.String,long)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getMessage()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"LogMessage","l":"getMessage()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"getMessage()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getMessageProcessorType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getMessageType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"getModel()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"getModel()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getModelName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getModelType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"getNextSimulationTimeMs()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getOptionalTwinInstanceProperties()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getPersistenceProvider()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getPersistenceProvider()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getProperty(String, String, String, Class)","u":"getProperty(java.lang.String,java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getPropertyAsync(String, String, String, Class)","u":"getPropertyAsync(java.lang.String,java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getPropertyMap(String)","u":"getPropertyMap(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getPropertyMapAsync(String)","u":"getPropertyMapAsync(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getProviderType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getRoutingKey()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getRtdtProperty(String, String, Class)","u":"getRtdtProperty(java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getRtdtPropertyAsync(String, String, Class)","u":"getRtdtPropertyAsync(java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getSeverity()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"LogMessage","l":"getSeverity()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getSimulationController()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getSimulationProcessorType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"getSimulationTimeIncrement()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"SimulationStep","l":"getStatus()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"SimulationStep","l":"getTime()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getTime()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerHandlerClass()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTimerId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerIntervalMs()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTimerName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTimerType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerType()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"LogMessage","l":"getTimestamp()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getTitle()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTwinId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getURL()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"Handled"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"Id"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"init(InitContext)","u":"init(com.scaleoutsoftware.digitaltwin.core.InitContext)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"InitContext()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"initializeSimulation(long, long, long)","u":"initializeSimulation(long,long,long)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"InstanceRequestedStop"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"isActive()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"logMessage(Level, String)","u":"logMessage(java.util.logging.Level,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessor","l":"MessageProcessor()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessorBase","l":"MessageProcessorBase()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"Model"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, PersistenceProviderType, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, String, PersistenceProviderType, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"NextSimulationTime"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"NoRemainingWork"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"NotHandled"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"NotSet"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"NoUpdate"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"OneTime"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerHandler","l":"onTimedMessage(String, T, ProcessingContext)","u":"onTimedMessage(java.lang.String,T,com.scaleoutsoftware.digitaltwin.core.ProcessingContext)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"peek()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"persistenceEnabled()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"ProcessingContext()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessor","l":"processMessages(ProcessingContext, T, Iterable)","u":"processMessages(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,java.lang.Iterable)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessor","l":"processMessages(ProcessingContext, T, MessageFactory)","u":"processMessages(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,com.scaleoutsoftware.digitaltwin.core.MessageFactory)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessorBase","l":"processMessages(ProcessingContext, T, MessageFactory)","u":"processMessages(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,com.scaleoutsoftware.digitaltwin.core.MessageFactory)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationProcessor","l":"processModel(ProcessingContext, T, Date)","u":"processModel(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,java.util.Date)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"Recurring"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"Running"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"runSimulation(long, long, double, long)","u":"runSimulation(long,long,double,long)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"send(String, String, List)","u":"send(java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendAlert(String, AlertMessage)","u":"sendAlert(java.lang.String,com.scaleoutsoftware.digitaltwin.core.AlertMessage)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDataSource(byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDataSource(List)","u":"sendToDataSource(java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDataSource(Object)","u":"sendToDataSource(java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, byte[])","u":"sendToDigitalTwin(java.lang.String,java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, List)","u":"sendToDigitalTwin(java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, Object)","u":"sendToDigitalTwin(java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, String)","u":"sendToDigitalTwin(java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"setNextSimulationTime(long)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"SimulationEventResult","l":"SimulationEventResult()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationProcessor","l":"SimulationProcessor()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"simulationSupportEnabled()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"SQLite"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"SQLServer"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"startTimer(String, Duration, TimerType, TimerHandler)","u":"startTimer(java.lang.String,java.time.Duration,com.scaleoutsoftware.digitaltwin.core.TimerType,com.scaleoutsoftware.digitaltwin.core.TimerHandler)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"startTimer(String, Duration, TimerType, TimerHandler)","u":"startTimer(java.lang.String,java.time.Duration,com.scaleoutsoftware.digitaltwin.core.TimerType,com.scaleoutsoftware.digitaltwin.core.TimerHandler)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"step()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"stopSimulation()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"stopTimer(String)","u":"stopTimer(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"Success"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"TimerHandlers"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"TimerMetadata(TimerHandler, TimerType, long, int)","u":"%3Cinit%3E(com.scaleoutsoftware.digitaltwin.core.TimerHandler,com.scaleoutsoftware.digitaltwin.core.TimerType,long,int)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"toString()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"toString()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"Unconfigured"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"UnexpectedChangeInConfiguration"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"UpdateDigitalTwin"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updateProperty(String, String, String, Object)","u":"updateProperty(java.lang.String,java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updatePropertyAsync(String, String, String, Object)","u":"updatePropertyAsync(java.lang.String,java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updateRtdtProperty(String, String, Object)","u":"updateRtdtProperty(java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updateRtdtPropertyAsync(String, String, Object)","u":"updateRtdtPropertyAsync(java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"UserRequested"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"Workbench()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"WorkbenchException(Exception)","u":"%3Cinit%3E(java.lang.Exception)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"WorkbenchException(String)","u":"%3Cinit%3E(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"WorkbenchException(String, Exception)","u":"%3Cinit%3E(java.lang.String,java.lang.Exception)"}];updateSearchResults(); \ No newline at end of file +memberSearchIndex = [{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addAlertProvider(String, AlertProviderConfiguration)","u":"addAlertProvider(java.lang.String,com.scaleoutsoftware.digitaltwin.core.AlertProviderConfiguration)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addGlobalModelData(String, byte[])","u":"addGlobalModelData(java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addInstance(String, String, DigitalTwinBase)","u":"addInstance(java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addRealTimeModel(String, MessageProcessor, Class, Class)","u":"addRealTimeModel(java.lang.String,com.scaleoutsoftware.digitaltwin.core.MessageProcessor,java.lang.Class,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addSharedModelData(String, String, byte[])","u":"addSharedModelData(java.lang.String,java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addSimulationModel(String, MessageProcessor, SimulationProcessor, Class, Class)","u":"addSimulationModel(java.lang.String,com.scaleoutsoftware.digitaltwin.core.MessageProcessor,com.scaleoutsoftware.digitaltwin.core.SimulationProcessor,java.lang.Class,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"AlertMessage(String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"AlertMessage(String, String, String, HashMap)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.util.HashMap)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"AlertProviderConfiguration(String, String, String, String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"AzureDigitalTwinsService"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"CacheCleared"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SharedData","l":"clear()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"close()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"CosmosDb"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"createInstance(String, String, T)","u":"createInstance(java.lang.String,java.lang.String,T)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"createInstanceFromPersistenceStore(String, String)","u":"createInstanceFromPersistenceStore(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"createInstanceFromPersistenceStore(String, String, T)","u":"createInstanceFromPersistenceStore(java.lang.String,java.lang.String,T)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"delay(Duration)","u":"delay(java.time.Duration)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"delayIndefinitely()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"deleteInstance(String, String)","u":"deleteInstance(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"deleteThisInstance()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"DigitalTwinBase()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"DigitalTwinTimerMessage(String, String, int, String, TimerType)","u":"%3Cinit%3E(java.lang.String,java.lang.String,int,java.lang.String,com.scaleoutsoftware.digitaltwin.core.TimerType)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"DynamoDb"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"emitTelemetry(String, byte[])","u":"emitTelemetry(java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"emitTelemetry(String, Object)","u":"emitTelemetry(java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"EndTimeReached"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"Enqueued"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedInternalError"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedNoSuchTimer"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedTimerAlreadyExists"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedTooManyTimers"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"fromOrdinal(int)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"fromOrdinal(int)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"fromString(String)","u":"fromString(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"generateModelSchema(String)","u":"generateModelSchema(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"generateModelSchema(String, String)","u":"generateModelSchema(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SharedData","l":"get(String)","u":"get(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getAlertMessages(String, String)","u":"getAlertMessages(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getAlertProviders()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getAlertProviderType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getAssemblyName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getAzureDigitalTwinModelName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getCurrentTime()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getDataSourceId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getDigitalTwinModel()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getEntityId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getEntryPoint()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"getId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"getId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageFactory","l":"getIncomingMessages()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstance(String, String)","u":"getInstance(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstanceAsync(String, String)","u":"getInstanceAsync(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstanceIds(String)","u":"getInstanceIds(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstanceIdsAsync(String)","u":"getInstanceIdsAsync(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getInstances(String)","u":"getInstances(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getIntegrationKey()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheResult","l":"getKey()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getLoggedMessages(String, long)","u":"getLoggedMessages(java.lang.String,long)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getMessage()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"LogMessage","l":"getMessage()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"getMessage()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getMessageProcessorType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getMessageType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"getModel()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"getModel()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getModelName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getModelType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"getName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"getNextSimulationTimeMs()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getOptionalTwinInstanceProperties()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getPersistenceProvider()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getPersistenceProvider()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getProperty(String, String, String, Class)","u":"getProperty(java.lang.String,java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getPropertyAsync(String, String, String, Class)","u":"getPropertyAsync(java.lang.String,java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getPropertyMap(String)","u":"getPropertyMap(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getPropertyMapAsync(String)","u":"getPropertyMapAsync(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getProviderType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getRoutingKey()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getRtdtProperty(String, String, Class)","u":"getRtdtProperty(java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getRtdtPropertyAsync(String, String, Class)","u":"getRtdtPropertyAsync(java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"getServiceOrdinalValue()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getSeverity()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"LogMessage","l":"getSeverity()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"getSharedGlobalData()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitSimulationContext","l":"getSharedGlobalData()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getSharedGlobalData()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getSharedGlobalData()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"getSharedModelData()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitSimulationContext","l":"getSharedModelData()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getSharedModelData()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getSharedModelData(String)","u":"getSharedModelData(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getSimulationController()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getSimulationProcessorType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"getSimulationStartTime()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"getSimulationTimeIncrement()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheResult","l":"getStatus()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"SimulationStep","l":"getStatus()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"SimulationStep","l":"getTime()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getTime()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerHandlerClass()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTimerId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerIntervalMs()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTimerName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTimerType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerType()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"LogMessage","l":"getTimestamp()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getTitle()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTwinId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getURL()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheResult","l":"getValue()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"Handled"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"Id"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"init(InitContext)","u":"init(com.scaleoutsoftware.digitaltwin.core.InitContext)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"InitContext()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"initializeSimulation(long, long, long)","u":"initializeSimulation(long,long,long)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"InstanceRequestedStop"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"isActive()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"logMessage(Level, String)","u":"logMessage(java.util.logging.Level,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessor","l":"MessageProcessor()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessorBase","l":"MessageProcessorBase()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"messageRecordingEnabled()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"Model"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, List, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.util.List,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, PersistenceProviderType, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, PersistenceProviderType, List, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, String, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, String, List, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.util.List,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, String, PersistenceProviderType, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, String, PersistenceProviderType, List, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, String, String, PersistenceProviderType, List, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"NextSimulationTime"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"NoRemainingWork"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"NotHandled"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"NotSet"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"NoUpdate"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"ObjectDoesNotExist"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"ObjectPut"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"ObjectRemoved"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"ObjectRetrieved"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"OneTime"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationProcessor","l":"onInitSimulation(InitSimulationContext, T, Date)","u":"onInitSimulation(com.scaleoutsoftware.digitaltwin.core.InitSimulationContext,T,java.util.Date)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerHandler","l":"onTimedMessage(String, T, ProcessingContext)","u":"onTimedMessage(java.lang.String,T,com.scaleoutsoftware.digitaltwin.core.ProcessingContext)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"peek()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"persistenceEnabled()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"ProcessingContext()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessor","l":"processMessages(ProcessingContext, T, Iterable)","u":"processMessages(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,java.lang.Iterable)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessor","l":"processMessages(ProcessingContext, T, MessageFactory)","u":"processMessages(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,com.scaleoutsoftware.digitaltwin.core.MessageFactory)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessorBase","l":"processMessages(ProcessingContext, T, MessageFactory)","u":"processMessages(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,com.scaleoutsoftware.digitaltwin.core.MessageFactory)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationProcessor","l":"processModel(ProcessingContext, T, Date)","u":"processModel(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,java.util.Date)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SharedData","l":"put(String, byte[])","u":"put(java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"Recurring"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SharedData","l":"remove(String)","u":"remove(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"Running"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"runSimulation(long, long, double, long)","u":"runSimulation(long,long,double,long)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"runThisInstance()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"send(String, String, List)","u":"send(java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendAlert(String, AlertMessage)","u":"sendAlert(java.lang.String,com.scaleoutsoftware.digitaltwin.core.AlertMessage)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDataSource(byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDataSource(List)","u":"sendToDataSource(java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDataSource(Object)","u":"sendToDataSource(java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, byte[])","u":"sendToDigitalTwin(java.lang.String,java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, List)","u":"sendToDigitalTwin(java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, Object)","u":"sendToDigitalTwin(java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, String)","u":"sendToDigitalTwin(java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"setNextSimulationTime(long)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"SimulationEventResult","l":"SimulationEventResult()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationProcessor","l":"SimulationProcessor()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"simulationSupportEnabled()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"SQLite"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"SQLServer"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"startTimer(String, Duration, TimerType, TimerHandler)","u":"startTimer(java.lang.String,java.time.Duration,com.scaleoutsoftware.digitaltwin.core.TimerType,com.scaleoutsoftware.digitaltwin.core.TimerHandler)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"startTimer(String, Duration, TimerType, TimerHandler)","u":"startTimer(java.lang.String,java.time.Duration,com.scaleoutsoftware.digitaltwin.core.TimerType,com.scaleoutsoftware.digitaltwin.core.TimerHandler)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"step()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"stopSimulation()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"stopTimer(String)","u":"stopTimer(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"Success"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"TimerHandlers"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"TimerMetadata(TimerHandler, TimerType, long, int)","u":"%3Cinit%3E(com.scaleoutsoftware.digitaltwin.core.TimerHandler,com.scaleoutsoftware.digitaltwin.core.TimerType,long,int)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"toString()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"toString()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"Unconfigured"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"UnexpectedChangeInConfiguration"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"UpdateDigitalTwin"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updateProperty(String, String, String, Object)","u":"updateProperty(java.lang.String,java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updatePropertyAsync(String, String, String, Object)","u":"updatePropertyAsync(java.lang.String,java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updateRtdtProperty(String, String, Object)","u":"updateRtdtProperty(java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updateRtdtPropertyAsync(String, String, Object)","u":"updateRtdtPropertyAsync(java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"UserRequested"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"Workbench()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"Workbench(int)","u":"%3Cinit%3E(int)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"WorkbenchException(Exception)","u":"%3Cinit%3E(java.lang.Exception)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"WorkbenchException(String)","u":"%3Cinit%3E(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"WorkbenchException(String, Exception)","u":"%3Cinit%3E(java.lang.String,java.lang.Exception)"}];updateSearchResults(); \ No newline at end of file diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/overview-summary.html b/docs/digitaltwin-core-docs/build/docs/javadoc/overview-summary.html index f782a93..0832a3f 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/overview-summary.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/overview-summary.html @@ -2,7 +2,7 @@ -digitaltwin-core-docs 3.0.4 API +digitaltwin-core-docs 3.0.5 API diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/overview-tree.html b/docs/digitaltwin-core-docs/build/docs/javadoc/overview-tree.html index 1d46006..e355db6 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/overview-tree.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/overview-tree.html @@ -2,7 +2,7 @@ -Class Hierarchy (digitaltwin-core-docs 3.0.4 API) +Class Hierarchy (digitaltwin-core-docs 3.0.5 API) @@ -93,8 +93,11 @@

    Class Hierarchy

    Interface Hierarchy

    @@ -106,6 +109,7 @@

    Enum Class Hierarchy

    • java.lang.Enum<E> (implements java.lang.Comparable<T>, java.lang.constant.Constable, java.io.Serializable)
        +
      • com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
      • com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType (implements java.io.Serializable)
      • com.scaleoutsoftware.digitaltwin.core.ProcessingResult
      • com.scaleoutsoftware.digitaltwin.core.SendingResult
      • diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/serialized-form.html b/docs/digitaltwin-core-docs/build/docs/javadoc/serialized-form.html index 6f04e5a..86e2438 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/serialized-form.html +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/serialized-form.html @@ -2,7 +2,7 @@ -Serialized Form (digitaltwin-core-docs 3.0.4 API) +Serialized Form (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/digitaltwin-core-docs/build/docs/javadoc/type-search-index.js b/docs/digitaltwin-core-docs/build/docs/javadoc/type-search-index.js index 1ff095a..3146686 100644 --- a/docs/digitaltwin-core-docs/build/docs/javadoc/type-search-index.js +++ b/docs/digitaltwin-core-docs/build/docs/javadoc/type-search-index.js @@ -1 +1 @@ -typeSearchIndex = [{"p":"com.scaleoutsoftware.digitaltwin.core","l":"AlertMessage"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"AlertProviderConfiguration"},{"l":"All Classes and Interfaces","u":"allclasses-index.html"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"DigitalTwinBase"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"DigitalTwinTimerMessage"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"InitContext"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"LogMessage"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"MessageFactory"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"MessageProcessor"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"MessageProcessorBase"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"ModelSchema"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"PersistenceProvider"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"PersistenceProviderType"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"ProcessingContext"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"ProcessingResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SendingResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SimulationController"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"SimulationEventResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SimulationProcessor"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SimulationStatus"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"SimulationStep"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerActionResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerHandler"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerMetadata"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerType"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"Workbench"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"WorkbenchException"}];updateSearchResults(); \ No newline at end of file +typeSearchIndex = [{"p":"com.scaleoutsoftware.digitaltwin.core","l":"AlertMessage"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"AlertProviderConfiguration"},{"l":"All Classes and Interfaces","u":"allclasses-index.html"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"CacheOperationStatus"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"CacheResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"DigitalTwinBase"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"DigitalTwinTimerMessage"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"InitContext"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"InitSimulationContext"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"LogMessage"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"MessageFactory"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"MessageProcessor"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"MessageProcessorBase"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"ModelSchema"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"PersistenceProvider"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"PersistenceProviderType"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"ProcessingContext"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"ProcessingResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SendingResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SharedData"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SimulationController"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"SimulationEventResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SimulationProcessor"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SimulationStatus"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"SimulationStep"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerActionResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerHandler"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerMetadata"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerType"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"Workbench"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"WorkbenchException"}];updateSearchResults(); \ No newline at end of file diff --git a/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/SimulationWorker.class.uniqueId0 b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/SimulationWorker.class.uniqueId0 new file mode 100644 index 0000000..7f627fc Binary files /dev/null and b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/SimulationWorker.class.uniqueId0 differ diff --git a/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/Workbench.class.uniqueId6 b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/Workbench.class.uniqueId6 new file mode 100644 index 0000000..850b9a0 Binary files /dev/null and b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/Workbench.class.uniqueId6 differ diff --git a/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchInitContext.class.uniqueId5 b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchInitContext.class.uniqueId5 new file mode 100644 index 0000000..7c681bb Binary files /dev/null and b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchInitContext.class.uniqueId5 differ diff --git a/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchProcessingContext.class.uniqueId3 b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchProcessingContext.class.uniqueId3 new file mode 100644 index 0000000..16c09a8 Binary files /dev/null and b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchProcessingContext.class.uniqueId3 differ diff --git a/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData$1.class.uniqueId8 b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData$1.class.uniqueId8 new file mode 100644 index 0000000..6b2266d Binary files /dev/null and b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData$1.class.uniqueId8 differ diff --git a/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData$2.class.uniqueId4 b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData$2.class.uniqueId4 new file mode 100644 index 0000000..21894d2 Binary files /dev/null and b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData$2.class.uniqueId4 differ diff --git a/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData$3.class.uniqueId7 b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData$3.class.uniqueId7 new file mode 100644 index 0000000..1899587 Binary files /dev/null and b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData$3.class.uniqueId7 differ diff --git a/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData$4.class.uniqueId1 b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData$4.class.uniqueId1 new file mode 100644 index 0000000..2036868 Binary files /dev/null and b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData$4.class.uniqueId1 differ diff --git a/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData.class.uniqueId2 b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData.class.uniqueId2 new file mode 100644 index 0000000..f75f9a4 Binary files /dev/null and b/docs/digitaltwin-core-docs/build/tmp/compileJava/compileTransaction/stash-dir/WorkbenchSharedData.class.uniqueId2 differ diff --git a/docs/digitaltwin-core-docs/build/tmp/compileJava/previous-compilation-data.bin b/docs/digitaltwin-core-docs/build/tmp/compileJava/previous-compilation-data.bin index 0225578..39ca4be 100644 Binary files a/docs/digitaltwin-core-docs/build/tmp/compileJava/previous-compilation-data.bin and b/docs/digitaltwin-core-docs/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/docs/digitaltwin-core-docs/build/tmp/createJavadocs/javadoc.options b/docs/digitaltwin-core-docs/build/tmp/createJavadocs/javadoc.options index 48abd5c..026c060 100644 --- a/docs/digitaltwin-core-docs/build/tmp/createJavadocs/javadoc.options +++ b/docs/digitaltwin-core-docs/build/tmp/createJavadocs/javadoc.options @@ -1,14 +1,17 @@ -classpath 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\build\\classes\\java\\main;C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\build\\resources\\main;C:\\Users\\brandonr\\.gradle\\caches\\modules-2\\files-2.1\\com.google.code.gson\\gson\\2.8.5\\f645ed69d595b24d4cf8b3fbb64cc505bede8829\\gson-2.8.5.jar;C:\\Users\\brandonr\\.gradle\\caches\\modules-2\\files-2.1\\org.apache.logging.log4j\\log4j-core\\2.20.0\\eb2a9a47b1396e00b5eee1264296729a70565cc0\\log4j-core-2.20.0.jar;C:\\Users\\brandonr\\.gradle\\caches\\modules-2\\files-2.1\\org.apache.logging.log4j\\log4j-api\\2.20.0\\1fe6082e660daf07c689a89c94dc0f49c26b44bb\\log4j-api-2.20.0.jar' -d 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\build\\docs\\javadoc' --doctitle 'digitaltwin-core-docs 3.0.3 API' +-doctitle 'digitaltwin-core-docs 3.0.5 API' -notimestamp -quiet --windowtitle 'digitaltwin-core-docs 3.0.3 API' +-windowtitle 'digitaltwin-core-docs 3.0.5 API' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\AlertMessage.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\AlertProviderConfiguration.java' +'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\CacheOperationStatus.java' +'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\CacheResult.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\DigitalTwinBase.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\DigitalTwinTimerMessage.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\InitContext.java' +'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\InitSimulationContext.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\MessageFactory.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\MessageProcessor.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\MessageProcessorBase.java' @@ -19,6 +22,7 @@ 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\ProcessingContext.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\ProcessingResult.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\SendingResult.java' +'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\SharedData.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\SimulationController.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\SimulationProcessor.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\core\\SimulationStatus.java' @@ -44,8 +48,10 @@ 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\development\\Workbench.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\development\\WorkbenchException.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\development\\WorkbenchInitContext.java' +'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\development\\WorkbenchInitSimulationContext.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\development\\WorkbenchMessageListFactory.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\development\\WorkbenchProcessingContext.java' +'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\development\\WorkbenchSharedData.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\development\\WorkbenchSimulationController.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\development\\WorkbenchSimulationFlags.java' 'C:\\src\\git\\JavaDigitalTwinCore\\docs\\digitaltwin-core-docs\\src\\main\\java\\com\\scaleoutsoftware\\digitaltwin\\development\\WorkbenchTimerService.java' diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertMessage.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertMessage.java new file mode 100644 index 0000000..7e0d3f4 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertMessage.java @@ -0,0 +1,99 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +import java.util.HashMap; + +/** + * A message that should be sent to a configured alert provider. + */ +public class AlertMessage { + private final String _title; + private final String _severity; + private final String _message; + private final HashMap _optionalTwinInstanceProperties; + + private AlertMessage() {_title = _severity = _message = null; _optionalTwinInstanceProperties = null;} + + /** + * Construct an alert message with a title, severity, and custom message. + * @param title the title for the alert message. + * @param severity the severity for this alert. + * @param message the custom message for this alert. + */ + public AlertMessage(String title, String severity, String message) { + _title = title; + _severity = severity; + _message = message; + _optionalTwinInstanceProperties = null; + } + + /** + * Construct an alert message with a title, severity, and custom message. + * @param title the title for the alert message. + * @param severity the severity for this alert. + * @param message the custom message for this alert. + * @param optProps the optional properties that should be sent to the alerting provider. + */ + public AlertMessage(String title, String severity, String message, HashMap optProps) { + _title = title; + _severity = severity; + _message = message; + _optionalTwinInstanceProperties = optProps; + } + + /** + * Retrieve the title for this alert message. + * @return the title of this alert message. + */ + public String getTitle() { + return _title; + } + + /** + * Retrieve the severity for this alert message. + * @return the severity for this alert message. + */ + public String getSeverity() { + return _severity; + } + + /** + * Retrieve the message for this alert message. + * @return the message for this alert message. + */ + public String getMessage() { + return _message; + } + + /** + * Retrieve the optional twin instance properties for this alert message. + * @return the optional twin instance properties for this alert message. + */ + public HashMap getOptionalTwinInstanceProperties() { + return _optionalTwinInstanceProperties; + } + + @Override + public String toString() { + return "AlertMessage{" + + "_title='" + _title + '\'' + + ", _severity='" + _severity + '\'' + + ", _message='" + _message + '\'' + + ", _optionalTwinInstanceProperties=" + _optionalTwinInstanceProperties + + '}'; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.java new file mode 100644 index 0000000..8f718aa --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/AlertProviderConfiguration.java @@ -0,0 +1,128 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +import java.io.Serializable; + +/** + * Configuration for an alert provider. + */ +public class AlertProviderConfiguration implements Serializable { + /** + * The alert provider type. + */ + final String alertProviderType; + /** + * The required url for the alert provider type. + */ + final String url; + /** + * The required integration key for the alert provider type. + */ + final String integrationKey; + /** + * The required routing key for the alert provider type. + */ + final String routingKey; + /** + * The name of this alert provider. + */ + final String name; + /** + * The entity ID of this alert provider type. + */ + final String entityId; + + private AlertProviderConfiguration() {alertProviderType = url = integrationKey = routingKey = name = entityId = null;} + + /** + * Construct an alert provider configuration. + * @param alertProviderType the alert provider type. + * @param url the alert provider URL where alerts should be posted. + * @param integrationKey the integration key. + * @param routingKey the routing key. + * @param name the name of the alert provider. + * @param entityId the entity Id. + */ + public AlertProviderConfiguration(String alertProviderType, String url, String integrationKey, String routingKey, String name, String entityId) { + this.alertProviderType = alertProviderType; + this.url = url; + this.integrationKey = integrationKey; + this.routingKey = routingKey; + this.name = name; + this.entityId = entityId; + } + + /** + * Retrieve the alert provider type for this configuration. + * @return the alert provider type. + */ + public String getAlertProviderType() { + return alertProviderType; + } + + /** + * Retrieve the URL for this alert provider configuration. + * @return the URL for this alert provider configuration. + */ + public String getURL() { + return url; + } + + /** + * Retrieve the integration key for this alert provider configuration. + * @return the integration key for this alert provider configuration. + */ + public String getIntegrationKey() { + return integrationKey; + } + + /** + * Retrieve the routing key for this alert provider configuration. + * @return the routing key for this alert provider configuration. + */ + public String getRoutingKey() { + return routingKey; + } + + /** + * Retrieve the name of this alert provider configuration. + * @return the name of this alert provider configuration. + */ + public String getName() { + return name; + } + + /** + * Retrieve the entity ID for this alert provider configuration. + * @return the entity ID for this alert provider configuration. + */ + public String getEntityId() { + return entityId; + } + + @Override + public String toString() { + return "AlertProviderConfiguration{" + + "alertProviderType=" + alertProviderType + '\'' + + ", URL='" + url + '\'' + + ", IntegrationKey='" + integrationKey + '\'' + + ", RoutingKey='" + routingKey + '\'' + + ", Name='" + name + '\'' + + ", EntityId='" + entityId + '\'' + + '}'; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/CacheOperationStatus.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/CacheOperationStatus.java new file mode 100644 index 0000000..119b0be --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/CacheOperationStatus.java @@ -0,0 +1,48 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * Status of a cache operation. + */ +public enum CacheOperationStatus { + + /** + * The object was successfully retrieved. + */ + + ObjectRetrieved, + + /** + * The object was successfully added/updated. + */ + ObjectPut, + + /** + * The object could not be retrieved because it was not found. + */ + ObjectDoesNotExist, + + /** + * The object was removed successfully. + */ + ObjectRemoved, + + /** + * The cache was cleared successfully. + */ + CacheCleared +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/CacheResult.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/CacheResult.java new file mode 100644 index 0000000..9dc13c7 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/CacheResult.java @@ -0,0 +1,39 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * Represents a response from a {@link SharedData} operation. + */ +public interface CacheResult { + /** + * Gets the key or null to the object associated with the result. + * @return the key or null. + */ + public String getKey(); + + /** + * Get the object returned from a Get operation. + * @return the object or null. + */ + public byte[] getValue(); + + /** + * Gets the status of the cache operation. + * @return the operation status. + */ + CacheOperationStatus getStatus(); +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.java new file mode 100644 index 0000000..4b4333d --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinBase.java @@ -0,0 +1,95 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +import java.util.Date; +import java.util.HashMap; + +/** + * A real-time digital twin of a data source. The implementation of the real-time DigitalTwin should have a parameterless constructor for + * basic initialization. + */ +public abstract class DigitalTwinBase { + + /* capitalized to match .NET serialization */ + /** + * The identifier for this twin instance + */ + public String Id = ""; + + /** + * The model this twin instance belongs to. + */ + public String Model = ""; + + /** + * The timer handlers for this twin instance. + */ + public HashMap TimerHandlers = new HashMap<>(); + + /** + * Note: Simulation only. The next time in milliseconds that this Digital Twin instance will be passed to {@link SimulationProcessor#processModel(ProcessingContext, DigitalTwinBase, Date)}. + */ + public long NextSimulationTime = 0L; + + /** + * Default constructor. + */ + public DigitalTwinBase() {} + + /** + * Retrieve the next simulation time in milliseconds. + * @return the next simulation time in milliseconds. + */ + public long getNextSimulationTimeMs() { + return NextSimulationTime; + } + + /** + * Set the next simulation time in milliseconds. + * @param nextSimulationTime set the next simulation time. + */ + public void setNextSimulationTime(long nextSimulationTime) { + NextSimulationTime = nextSimulationTime; + } + + /** + * The identifier of this DigitalTwin. + * @return the identifier of this digital twin + */ + public String getId() { + return Id; + } + + /** + * The model for this DigitalTwin. + * @return the model for this DigitalTwin + */ + public String getModel() { + return Model; + } + + /** + * Initialization method to set the identifier and model for a DigitalTwin instance. Optionally use the + * {@link InitContext} to start a timer. + * @param context the initialization context. + * @throws IllegalStateException if init is called after initialization. + */ + public void init(InitContext context) throws IllegalStateException { + this.Id = context.getId(); + this.Model = context.getModel(); + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.java new file mode 100644 index 0000000..6ea0ce0 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/DigitalTwinTimerMessage.java @@ -0,0 +1,84 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * A message sent to a digital twin instance's message processor. + */ +public class DigitalTwinTimerMessage { + + private String _modelName; + private String _twinId; + private int _timerId; + private String _timerName; + private TimerType _timerType; + + /** + * Construct a digital twin timer message. + * @param modelName the digital twin model name. + * @param twinId the digital twin instance ID + * @param timerId the timer ID + * @param timerName the timer name + * @param timerType the timer type + */ + public DigitalTwinTimerMessage(String modelName, String twinId, int timerId, String timerName, TimerType timerType) { + _modelName = modelName; + _twinId = twinId; + _timerId = timerId; + _timerName = timerName; + _timerType = timerType; + } + + /** + * Retrieve the digital twin model name. + * @return the digital twin model name. + */ + public String getModelName() { + return _modelName; + } + + /** + * Retrieve the digital twin ID. + * @return the digital twin ID. + */ + public String getTwinId() { + return _twinId; + } + + /** + * Retrieve the timer ID. + * @return the timer ID. + */ + public int getTimerId() { + return _timerId; + } + + /** + * Retrieve the timer name. + * @return the timer name. + */ + public String getTimerName() { + return _timerName; + } + + /** + * Retrieve the {@link TimerType}. + * @return the {@link TimerType} + */ + public TimerType getTimerType() { + return _timerType; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/InitContext.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/InitContext.java new file mode 100644 index 0000000..4cb7014 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/InitContext.java @@ -0,0 +1,67 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +import java.time.Duration; + +/** + * The InitContext is passed as a parameter to the {@link DigitalTwinBase#init(InitContext)} method of an initializing + * digital twin. + */ +public abstract class InitContext { + + /** + * Default constructor. + */ + public InitContext() {} + + /** + * Starts a new timer for the digital twin + * @param timerName the timer name + * @param interval the timer interval + * @param timerType the timer type + * @param timerHandler the time handler callback + * @param the type of the digital twin + * @return returns {@link TimerActionResult#Success} if the timer was started, {@link TimerActionResult#FailedTooManyTimers} + * if too many timers exist, or {@link TimerActionResult#FailedInternalError} if an unexpected error occurs. + */ + public abstract TimerActionResult startTimer(String timerName, Duration interval, TimerType timerType, TimerHandler timerHandler); + + /** + * Retrieve a {@link SharedData} accessor for this model's shared data. + * @return a {@link SharedData} instance. + */ + public abstract SharedData getSharedModelData(); + + /** + * Retrieve a {@link SharedData} accessor for globally shared data. + * @return a {@link SharedData} instance. + */ + public abstract SharedData getSharedGlobalData(); + + /** + * Get the model-unique Id identifier of the initializing digital twin instance. + * @return the id identifier. + */ + public abstract String getId(); + + /** + * Get the Model identifier of the initializing digital twin instance. + * @return the model identifier. + */ + public abstract String getModel(); + +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/InitSimulationContext.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/InitSimulationContext.java new file mode 100644 index 0000000..62ae315 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/InitSimulationContext.java @@ -0,0 +1,21 @@ +package com.scaleoutsoftware.digitaltwin.core; + +import java.util.Date; + +/** + * The InitSimulationContext is passed as a parameter to the {@link SimulationProcessor#onInitSimulation(InitSimulationContext, DigitalTwinBase, Date)} method of + * digital twin instance when a simulation is initializing. + */ +public interface InitSimulationContext { + /** + * Retrieve a {@link SharedData} accessor for this model's shared data. + * @return a {@link SharedData} instance. + */ + public abstract SharedData getSharedModelData(); + + /** + * Retrieve a {@link SharedData} accessor for globally shared data. + * @return a {@link SharedData} instance. + */ + public abstract SharedData getSharedGlobalData(); +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageFactory.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageFactory.java new file mode 100644 index 0000000..1e89eed --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageFactory.java @@ -0,0 +1,29 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * Message list factory retrieves message lists for a MessageProcessor + */ +public interface MessageFactory { + + /** + * Returns all incoming messages + * @param the type of incoming messages + * @return an iterable of incoming messages + */ + Iterable getIncomingMessages(); +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.java new file mode 100644 index 0000000..a608741 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessor.java @@ -0,0 +1,56 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +import java.io.Serializable; + +/** + * Processes messages for a real-time digital twin. + * @param the real type of the DigitalTwinBase + * @param the type of messages processed by the real-time digital twin + */ +public abstract class MessageProcessor extends MessageProcessorBase implements Serializable { + + /** + * Default constructor. + */ + public MessageProcessor() {} + + /** + * Processes a set of incoming messages and determines whether to update the real-time digital twin. + * @param context optional context for processing. + * @param stateObject the state object. + * @param incomingMessages the incoming messages. + * @return processing results for updating the state object. + * @throws Exception if an exception occurs during processing + */ + public abstract ProcessingResult processMessages(ProcessingContext context, T stateObject, Iterable incomingMessages) throws Exception; + + /** + * Helper method to ensure proper typing for user methods. + * @param context the processing context. + * @param twin the digital twin object. + * @param factory the message list factory. + * @return the implementing class's processing result. + * @throws Exception if an exception occurs during processing. + */ + @Override + public ProcessingResult processMessages(ProcessingContext context, T twin, MessageFactory factory) throws Exception { + Iterable incoming = factory.getIncomingMessages(); + return this.processMessages(context, twin, incoming); + } +} + diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.java new file mode 100644 index 0000000..befa76d --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/MessageProcessorBase.java @@ -0,0 +1,38 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * Base class for the MessageProcessor to help with typing. + * @param the type of the DigitalTwin + */ +public abstract class MessageProcessorBase { + + /** + * Default constructor. + */ + public MessageProcessorBase() {} + + /** + * Helper method to ensure proper typing for the user methods. + * @param context the processing context + * @param twin the real-time digital twin instance + * @param messageListFactory the message list factory + * @return the implementing class's processing result + * @throws Exception if an exception occurs during processing + */ + public abstract ProcessingResult processMessages(ProcessingContext context, T twin, MessageFactory messageListFactory) throws Exception; +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/ModelSchema.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/ModelSchema.java new file mode 100644 index 0000000..970ab1a --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/ModelSchema.java @@ -0,0 +1,785 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +import java.util.List; + +/** + * The ModelSchema class is used as a Java object representation of the model.json schema file used for deploying a + * digital twin model to the real-time digital twin cloud service. + */ +public class ModelSchema { + private final String modelType; + private final String messageProcessorType; + private final String simulationProcessorType; + private final String messageType; + private final String assemblyName; + private final String entryPoint; + private final String azureDigitalTwinModelName; + private final String persistenceProvider; + private final boolean enablePersistence; + private final boolean enableSimulationSupport; + private final boolean enableMessageRecording; + private final List alertProviders; + + private ModelSchema() { + modelType = messageProcessorType = simulationProcessorType = messageType = assemblyName = entryPoint = azureDigitalTwinModelName = persistenceProvider = null; + enablePersistence = false; + enableSimulationSupport = false; + enableMessageRecording = false; + alertProviders = null; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, and a message class. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = null; + enableSimulationSupport = false; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; + alertProviders = null; + azureDigitalTwinModelName = null; + enablePersistence = false; + enableMessageRecording = false; + persistenceProvider = null; + } + + /** + * Model schema with a defined entry point. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param ep the invocation grid entry point. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String ep) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = null; + enableSimulationSupport = false; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = ep; + alertProviders = null; + azureDigitalTwinModelName = null; + enablePersistence = false; + enableMessageRecording = false; + persistenceProvider = null; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, and a message class. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = null; + enableSimulationSupport = false; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; + alertProviders = null; + azureDigitalTwinModelName = null; + enablePersistence = false; + enableMessageRecording = emr; + persistenceProvider = null; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, and a message class. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param ep the invocation grid entry point. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String ep, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = null; + enableSimulationSupport = false; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = ep; + alertProviders = null; + azureDigitalTwinModelName = null; + enablePersistence = false; + enableMessageRecording = emr; + persistenceProvider = null; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, and + * alert provider configurations. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param alertingProviders the alerting provider configurations. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + List alertingProviders) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = null; + enableSimulationSupport = false; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; + azureDigitalTwinModelName = null; + enablePersistence = false; + enableMessageRecording = false; + persistenceProvider = null; + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, and + * alert provider configurations. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param spClass the simulation processor class implementation. + * @param alertingProviders the alerting provider configurations. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String spClass, + List alertingProviders) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) || + (spClass == null || spClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass), + (spClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = spClass; + enableSimulationSupport = true; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; + azureDigitalTwinModelName = null; + enablePersistence = false; + persistenceProvider = null; + enableMessageRecording = false; + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, and + * alert provider configurations. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param spClass the simulation processor class implementation. + * @param ep the invocation grid entry point. + * @param alertingProviders the alerting provider configurations. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String spClass, + String ep, + List alertingProviders) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) || + (spClass == null || spClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass), + (spClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = spClass; + enableSimulationSupport = true; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = ep; + azureDigitalTwinModelName = null; + enablePersistence = false; + persistenceProvider = null; + enableMessageRecording = false; + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, and + * alert provider configurations. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param spClass the simulation processor class implementation. + * @param alertingProviders the alerting provider configurations. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String spClass, + List alertingProviders, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) || + (spClass == null || spClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass), + (spClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = spClass; + enableSimulationSupport = true; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; + azureDigitalTwinModelName = null; + enablePersistence = false; + persistenceProvider = null; + enableMessageRecording = emr; + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, and + * alert provider configurations. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param spClass the simulation processor class implementation. + * @param alertingProviders the alerting provider configurations. + * @param ep the invocation grid entry point. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String spClass, + String ep, + List alertingProviders, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) || + (spClass == null || spClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass), + (spClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = spClass; + enableSimulationSupport = true; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = ep; + azureDigitalTwinModelName = null; + enablePersistence = false; + persistenceProvider = null; + enableMessageRecording = emr; + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, and + * alert provider configurations. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param adtName the Azure Digital Twin model name. + * @param persistenceType the persistence provider type. + * @param alertingProviders the alerting provider configurations. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String adtName, + PersistenceProviderType persistenceType, + List alertingProviders) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = null; + enableSimulationSupport = false; + messageType = msgClass; + enableMessageRecording = false; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; + persistenceProvider = persistenceType.name(); + switch (persistenceType) { + case AzureDigitalTwinsService: + azureDigitalTwinModelName = adtName; + enablePersistence = true; + break; + case SQLite: + case SQLServer: + case DynamoDb: + case CosmosDb: + enablePersistence = true; + azureDigitalTwinModelName = null; + break; + default: + azureDigitalTwinModelName = null; + enablePersistence = false; + break; + } + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, and + * alert provider configurations. + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param adtName the Azure Digital Twin model name. + * @param persistenceType the persistence provider type. + * @param alertingProviders the alerting provider configurations. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String adtName, + PersistenceProviderType persistenceType, + List alertingProviders, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = null; + enableSimulationSupport = false; + messageType = msgClass; + enableMessageRecording = emr; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; + persistenceProvider = persistenceType.name(); + switch (persistenceType) { + case AzureDigitalTwinsService: + azureDigitalTwinModelName = adtName; + enablePersistence = true; + break; + case SQLite: + case SQLServer: + case DynamoDb: + enablePersistence = true; + azureDigitalTwinModelName = null; + break; + default: + azureDigitalTwinModelName = null; + enablePersistence = false; + break; + } + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, + * a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + * and an alert provider configuration. + * + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param simulationProcessorClass the simulation processor class implementation. + * @param adtName the Azure Digital Twin model name. + * @param persistenceType the persistence provider type. + * @param alertingProviders the alerting provider configurations. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String simulationProcessorClass, + String adtName, + PersistenceProviderType persistenceType, + List alertingProviders) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = simulationProcessorClass; + enableSimulationSupport = true; + enableMessageRecording = false; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; + persistenceProvider = persistenceType.name(); + switch (persistenceType) { + case AzureDigitalTwinsService: + azureDigitalTwinModelName = adtName; + enablePersistence = true; + break; + case SQLite: + case SQLServer: + case DynamoDb: + enablePersistence = true; + azureDigitalTwinModelName = null; + break; + default: + azureDigitalTwinModelName = null; + enablePersistence = false; + break; + } + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, + * a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + * and an alert provider configuration. + * + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param simulationProcessorClass the simulation processor class implementation. + * @param adtName the Azure Digital Twin model name. + * @param persistenceType the persistence provider type. + * @param alertingProviders the alerting provider configurations. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String simulationProcessorClass, + String adtName, + PersistenceProviderType persistenceType, + List alertingProviders, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = simulationProcessorClass; + enableSimulationSupport = true; + enableMessageRecording = emr; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = null; + persistenceProvider = persistenceType.name(); + switch (persistenceType) { + case AzureDigitalTwinsService: + azureDigitalTwinModelName = adtName; + enablePersistence = true; + break; + case SQLite: + case SQLServer: + case DynamoDb: + case CosmosDb: + enablePersistence = true; + azureDigitalTwinModelName = null; + break; + default: + azureDigitalTwinModelName = null; + enablePersistence = false; + break; + } + alertProviders = alertingProviders; + } + + /** + * Creates a model schema from a digital twin class, a message processor class, a message class, + * a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + * and an alert provider configuration. + * + * @param dtClass the digital twin class implementation. + * @param mpClass the message processor class implementation. + * @param msgClass a JSON serializable message class. + * @param simulationProcessorClass the simulation processor class implementation. + * @param adtName the Azure Digital Twin model name. + * @param persistenceType the persistence provider type. + * @param alertingProviders the alerting provider configurations. + * @param ep the invocation grid entry point. + * @param emr enable message recording for this model. + */ + public ModelSchema( + String dtClass, + String mpClass, + String msgClass, + String simulationProcessorClass, + String adtName, + String ep, + PersistenceProviderType persistenceType, + List alertingProviders, + boolean emr) { + if( (dtClass == null || dtClass.isEmpty()) || + (mpClass == null || mpClass.isEmpty()) || + (msgClass == null || msgClass.isEmpty()) + ) { + throw new IllegalArgumentException(String.format("Expected value for dtClass, mpClass, and msgClass; actual values: %s, %s, %s", + (dtClass == null ? "null dtClass" : dtClass), + (mpClass == null ? "null mpClass" : mpClass), + (msgClass == null ? "null mpClass" : msgClass) + )); + } + modelType = dtClass; + messageProcessorType = mpClass; + simulationProcessorType = simulationProcessorClass; + enableSimulationSupport = true; + enableMessageRecording = emr; + messageType = msgClass; + assemblyName = "NOT_USED_BY_JAVA_MODELS"; + entryPoint = ep; + persistenceProvider = persistenceType.name(); + switch (persistenceType) { + case AzureDigitalTwinsService: + azureDigitalTwinModelName = adtName; + enablePersistence = true; + break; + case SQLite: + case SQLServer: + case DynamoDb: + case CosmosDb: + enablePersistence = true; + azureDigitalTwinModelName = null; + break; + default: + azureDigitalTwinModelName = null; + enablePersistence = false; + break; + } + alertProviders = alertingProviders; + } + + /** + * Retrieve the digital twin model type (a {@link DigitalTwinBase} implementation). + * @return the model type. + */ + public String getModelType() { + return modelType; + } + + /** + * Retrieve the message type (JSON serializable message implementation). + * @return the message type. + */ + public String getMessageType() { + return messageType; + } + + /** + * Retrieve the message processor type (a {@link MessageProcessor} implementation). + * @return the message processor type. + */ + public String getMessageProcessorType() { + return messageProcessorType; + } + + /** + * Retrieve the simulation processor type (a {@link SimulationProcessor} implementation). + * @return the simulation processor type. + */ + public String getSimulationProcessorType() { + return simulationProcessorType; + } + + /** + * NOT USED BY JAVA MODEL SCHEMA + * @return NOT USED BY JAVA MODEL SCHEMA + */ + public String getAssemblyName() { + return assemblyName; + } + + /** + * Retrieve the alert provider configurations. + * @return the alert provider configurations. + */ + public List getAlertProviders() {return alertProviders; } + + /** + * Retrieve the Azure Digital Twin model name. + * @return the Azure Digital Twin model name. + */ + public String getAzureDigitalTwinModelName() { + return azureDigitalTwinModelName; + } + + /** + * Retrieve persistence status. True if persistence is enabled, false otherwise. + * @return True if persistence is enabled, false otherwise. + */ + public boolean persistenceEnabled() { return enablePersistence; } + + /** + * Retrieve simulation support enabled status. True if simulation support is enabled, false otherwise. + * @return True if simulation support is enabled, false otherwise. + */ + public boolean simulationSupportEnabled() {return enableSimulationSupport;} + + /** + * Retrieve the persistence provider type. + * @return the persistence provider type. + */ + public PersistenceProviderType getPersistenceProvider() { return PersistenceProviderType.fromString(persistenceProvider); } + + /** + * Retrieves the message recording enabled status. True if this model should persist messages when message recording is active, + * false otherwise. + * @return True if message recording is enabled, false otherwise. + */ + public boolean messageRecordingEnabled() { + return enableMessageRecording; + } + + /** + * Retrieves the packaged model's entry point (fully-qualified class name -- FQCN -- of a Java main) for launching. + * @return the entry point for launching. + */ + public String getEntryPoint() { + return entryPoint; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.java new file mode 100644 index 0000000..434bf75 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProvider.java @@ -0,0 +1,162 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +/** + * An interface that can be used for persisting/retrieving the state of real-time digital twins. + */ +public interface PersistenceProvider { + + /** + * Returns true if this PersistenceProvider is active, false otherwise. + * @return true if this PersistenceProvider is active, false otherwise. + */ + public abstract boolean isActive(); + + /** + * Retrieves this persistence providers type. Currently supported provider types: AzureDigitalTwins. + * @return the persistence provider type. + */ + public PersistenceProviderType getProviderType(); + + /** + * Retrieves a future that when complete will return the instance IDs stored in a container, or an empty list if no instances exist. + * @param containerName the container name. + * @return a future that will return a list of instances. + */ + public CompletableFuture> getInstanceIdsAsync(String containerName); + + /** + * Retrieves the instance IDs stored in a container, or an empty list if no instances exist. + * @param containerName the container name. + * @return a list of instances. + */ + public List getInstanceIds(String containerName); + + /** + * Retrieves a future that when complete will return an instance or null if it doesn't exist. + * @param containerName the container name. + * @param instanceId the instance identifier. + * @return a future that will return an instance or null. + */ + public CompletableFuture getInstanceAsync(String containerName, String instanceId); + + /** + * Retrieves an instance or null if it doesn't exist. + * @param containerName the container name + * @param instanceId the instance identifier + * @return the instance or null. + */ + public String getInstance(String containerName, String instanceId); + + /** + * Retrieves a future that will return a map of property names to property, or an empty map. + * @param containerName the container name. + * @return a future that will return a map of property names to property types. + */ + public CompletableFuture> getPropertyMapAsync(String containerName); + + /** + * Retrieves a map of property names to property types, or an empty map. + * @param containerName the container name. + * @return a map of property names to property types. + */ + public Map getPropertyMap(String containerName); + + /** + * Retrieves a future that will complete exceptionally or return void if the instance's property was successfully updated. + * Updates a property for the provided instance id in the provided container specified by the property name and property value. + * @param containerName the container name. + * @param instanceId the instance id. + * @param propertyName the property name. + * @param propertyValue the property value. + * @return a future that will complete exceptionally or return void. + */ + public CompletableFuture updatePropertyAsync(String containerName, String instanceId, String propertyName, Object propertyValue); + + /** + * Updates a property for the provided instance id in the provided container specified by the property name and property value. + * @param containerName the container name. + * @param instanceId the instance id. + * @param propertyName the property name. + * @param propertyValue the property value. + */ + public void updateProperty(String containerName, String instanceId, String propertyName, Object propertyValue); + + /** + * Retrieves a future that will return a property or null if the property does not exist. + * @param containerName the container name. + * @param instanceId the instance id. + * @param propertyName the property name. + * @param clazz the class representing the property. + * @param the type of the property to return + * @return the property or null if the property does not exist. + */ + public CompletableFuture getPropertyAsync(String containerName, String instanceId, String propertyName, Class clazz); + + /** + * Retrieves a property or null if the property does not exist. + * @param containerName the container name. + * @param instanceId the instance id. + * @param propertyName the property name + * @param clazz the class representing the property. + * @param the type of the property to return. + * @return the property or null if the property does not exist. + */ + public T getProperty(String containerName, String instanceId, String propertyName, Class clazz); + + /** + * Retrieves a future that will complete exceptionally or return void if the RTDT's property was successfully updated. + * Updates a RTDT property for the provided instance id specified by the property name and property value. + * @param instanceId the instance id. + * @param propertyName the property name. + * @param propertyValue the property value. + * @return a future that will complete exceptionally or return void. + */ + public CompletableFuture updateRtdtPropertyAsync(String instanceId, String propertyName, Object propertyValue); + + /** + * Updates a RTDT property for the provided instance id specified by the property name and property value. + * @param instanceId the instance id. + * @param propertyName the property name. + * @param propertyValue the property value. + */ + public void updateRtdtProperty(String instanceId, String propertyName, Object propertyValue); + + /** + * Retrieves a future that will return a property value for a RTDT instance or null if the property doesn't exist. + * @param instanceId the instance id. + * @param propertyName the property name. + * @param clazz the class of the property type + * @param the type of the property to return. + * @return a future that will return a property value for a RTDT instance. + */ + public CompletableFuture getRtdtPropertyAsync(String instanceId, String propertyName, Class clazz); + + /** + * Retrieves a property for a RTDT instance or null if the property does not exist. + * @param instanceId the instance id. + * @param propertyName the property name. + * @param clazz the class of the property type. + * @param the type of the property to return. + * @return the property value. + */ + public T getRtdtProperty(String instanceId, String propertyName, Class clazz); +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.java new file mode 100644 index 0000000..ce9eb88 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/PersistenceProviderType.java @@ -0,0 +1,125 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +import java.io.Serializable; + +/** + * Available {@link PersistenceProvider} types. + */ +public enum PersistenceProviderType implements Serializable { + + /** + * Enum for the Azure Digital Twin service. + */ + AzureDigitalTwinsService("AzureDigitalTwinsService", 1), + /** + * Enum for CosmosDB + */ + CosmosDb("Azure Cosmos DB", 6), + + /** + * Enum for DynamoDB + */ + DynamoDb("DynamoDB", 5), + /** + * Enum for SQLite + */ + SQLite("SQLite", 4), + /** + * Enum for SQLServer + */ + SQLServer("SQLServer", 3), + + /** + * Enum for an unconfigured PersistenceProvider + */ + Unconfigured("", 0); + + private final String _name; + private final int _value; + PersistenceProviderType(String name, int ordinal) { + _name = name; + _value = ordinal; + } + + + /** + * Retrieve the name of the persistence provider type. + * @return the name of the persistence provider type. + */ + public String getName() { + return _name; + } + + /** + * Retrieve the ordinal value (used by the DTBuidler service). + * @return the ordinal value. + */ + public int getServiceOrdinalValue() { + return _value; + } + + /** + * Return the PersistenceProviderType from a string value. We do not rely on Java's naming + * because the string values need to be cross-platform and the names may be different in each language. + * @param name the enums name. + * @return the associated PersistenceProviderType, or null if no association exists. + */ + public static PersistenceProviderType fromString(String name) { + if(name != null && !name.isEmpty() && !name.isBlank()) { + switch(name) { + case "AzureDigitalTwinsService": + return AzureDigitalTwinsService; + case "SQLite": + return SQLite; + case "SQLServer": + return SQLServer; + case "DynamoDB": + return DynamoDb; + case "Azure Cosmos DB": + return CosmosDb; + default: + return null; + } + } else { + return null; + } + } + + /** + * Return the PersistenceProviderType from an ordinal value. We do not rely on Java's ordering + * because the ordinal values need to be cross-platform, and the values may be ordered differently. + * @param ordinal the enums ordinal value. + * @return the associated PersistenceProviderType, or null if no association exists. + */ + public static PersistenceProviderType fromOrdinal(int ordinal) { + switch(ordinal) { + case 1: + return AzureDigitalTwinsService; + case 3: + return SQLServer; + case 4: + return SQLite; + case 5: + return DynamoDb; + case 6: + return CosmosDb; + default: + return null; + } + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.java new file mode 100644 index 0000000..2af1dc8 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingContext.java @@ -0,0 +1,243 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +import java.io.Serializable; +import java.time.Duration; +import java.util.Date; +import java.util.List; +import java.util.logging.Level; + +/** + * Context object that allows the user to send a message to a DataSource. + */ +public abstract class ProcessingContext implements Serializable { + + /** + * Default constructor. + */ + public ProcessingContext() {} + + /** + *

        + * Sends a message to a data source. This will route messages through the connector back to the data source. + *

        + * + *

        + * if the datasource is simulation instance, then the message will be sent to the simulation model's implementation + * of the {@link MessageProcessor}. + *

        + * + * @param payload the message (as a serialized JSON string) + * @return the sending result + */ + public abstract SendingResult sendToDataSource(byte[] payload); + + /** + *

        + * Sends a message to a data source. This will route messages through the connector back to the data source. + *

        + * + *

        + * if the datasource is simulation instance, then the message will be sent to the simulation model's implementation + * of the {@link MessageProcessor}. + *

        + * + * @param jsonSerializableMessage a JSON serializable message. + * @return the sending result + */ + public abstract SendingResult sendToDataSource(Object jsonSerializableMessage); + + /** + *

        + * Sends a list of messages to a data source. This will route messages through the connector back to the data source. + *

        + * + *

        + * if the datasource is simulation instance, then the message will be sent to the simulation model's implementation + * of the {@link MessageProcessor#processMessages(ProcessingContext, DigitalTwinBase, Iterable)}. + *

        + * + * @param jsonSerializableMessages a list of JSON serializable messages. + * @return the sending result + */ + public abstract SendingResult sendToDataSource(List jsonSerializableMessages); + + /** + *

        + * This method sends a serialized JSON message to a real-time digital twin + *

        + * + *

        + * Note, the message contents must be serialized so that the registered message type + * of the digital twin model will be sufficient to deserialize the message. + *

        + * @param model the model of the digital twin + * @param id the id of the digital twin + * @param payload the serialized JSON message + * @return the sending result + */ + public abstract SendingResult sendToDigitalTwin(String model, String id, byte[] payload); + + /** + *

        + * This method sends a serialized JSON message to a real-time digital twin + *

        + * + *

        + * Note, the message contents must be serialized so that the registered message type + * of the digital twin model will be sufficient to deserialize the message. + *

        + * @param model the model of the digital twin + * @param id the id of the digital twin + * @param jsonSerializableMessage a JSON serializable message object + * @return the sending result + */ + public abstract SendingResult sendToDigitalTwin(String model, String id, Object jsonSerializableMessage); + + /** + *

        + * This method sends a JSON message to a real-time digital twin + *

        + * + *

        + * Note, the message contents must be serialized so that the registered message type + * of the digital twin model will be sufficient to deserialize the message. + *

        + * + * @param model the model of the digital twin + * @param id the id of the digital twin + * @param payload the JSON message + * @return the sending result + */ + public abstract SendingResult sendToDigitalTwin(String model, String id, String payload); + + /** + *

        + * This method sends a list of serialized JSON message to a real-time digital twin + *

        + * + *

        + * Note, the message contents must be serialized so that the registered message type + * of the digital twin model will be sufficient to deserialize the message. + *

        + * + * @param model the model of the digital twin + * @param id the id of the digital twin + * @param payload the JSON message + * @return the sending result + */ + public abstract SendingResult sendToDigitalTwin(String model, String id, List payload); + + + /** + *

        + * This method sends an alert message to supported systems. + *

        + * + *

        + * When a model is deployed, an optional alerting provider configuration can be supplied. The provider name corresponds + * to the name of the configured alerting provider. For example, if an alerting provider configuration is called + * "SREPod1", then the processing context will send an alert message to the alerting provider configured with the name + * "SREPod1". + *

        + * + *

        + * If the message cannot be sent then {@link SendingResult#NotHandled} will be returned. If the message is sent + * and in process of sending then {@link SendingResult#Enqueued} will be returned. Once the message is successfully sent + * then the returned enum will be changed to {@link SendingResult#Handled}. + *

        + * @param alertingProviderName the alerting provider name. Note, must match a valid configuration. + * @param alert the alert message. + * @return the sending result. + */ + public abstract SendingResult sendAlert(String alertingProviderName, AlertMessage alert); + + /** + * Returns the configured persistence provider or null if no persistence provider configuration can be found. + * @return a PersistenceProvider . + */ + public abstract PersistenceProvider getPersistenceProvider(); + + /** + * Retrieve the unique Identifier for a DataSource (matches the Device/Datasource/Real-time twin ID) + * @return the digital twin id + */ + public abstract String getDataSourceId(); + + /** + * Retrieve the model for a DigitalTwin (matches the model of a Device/Datasource/real-time twin) + * @return the digital twin model + */ + public abstract String getDigitalTwinModel(); + + /** + * Logs a message to the real-time digital twin cloud service. + * + * Note: the only supported severity levels are: INFO, WARN, and SEVERE + * + * @param severity the severity of the log message + * @param message the message to log + */ + public abstract void logMessage(Level severity, String message); + + /** + * Starts a new timer for the digital twin + * @param timerName the timer name + * @param interval the timer interval + * @param timerType the timer type + * @param timerHandler the time handler callback + * @param the type of the digital twin + * @return returns {@link TimerActionResult#Success} if the timer was started, {@link TimerActionResult#FailedTooManyTimers} + * if too many timers exist, or {@link TimerActionResult#FailedInternalError} if an unexpected error occurs. + */ + public abstract TimerActionResult startTimer(String timerName, Duration interval, TimerType timerType, TimerHandler timerHandler); + + /** + * Stops the specified timer. + * @param timerName the timer name. + * @return returns {@link TimerActionResult#Success} if the timer was stopped, {@link TimerActionResult#FailedNoSuchTimer} + * if no timer exists with that name, or {@link TimerActionResult#FailedInternalError} if an unexpected error occurs. + */ + public abstract TimerActionResult stopTimer(String timerName); + + /** + * Retrieves the current time. If the model (simulation or real-time) is running inside of a simulation then the + * simulation time will be returned. + * + * @return The current time (real time, or simulation if running under simulation). + */ + public abstract Date getCurrentTime(); + + /** + * Retrieve the running {@link SimulationController} or null if no simulation is running. + * @return the {@link SimulationController} or null if no simulation is running. + */ + public abstract SimulationController getSimulationController(); + + /** + * Retrieve a {@link SharedData} accessor for this model's shared data. + * @return a {@link SharedData} instance. + */ + public abstract SharedData getSharedModelData(); + + /** + * Retrieve a {@link SharedData} accessor for globally shared data. + * @return a {@link SharedData} instance. + */ + public abstract SharedData getSharedGlobalData(); + +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.java new file mode 100644 index 0000000..279f0fa --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/ProcessingResult.java @@ -0,0 +1,30 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * The result from a message processor which indicates to update the state object or to ignore + */ +public enum ProcessingResult { + /** + * Update the digital twin. + */ + UpdateDigitalTwin, + /** + * Do not update the digital twin. + */ + NoUpdate +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SendingResult.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SendingResult.java new file mode 100644 index 0000000..9b3731b --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SendingResult.java @@ -0,0 +1,35 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * Marks a message as Delivered or not Delivered + */ +public enum SendingResult { + /** + * Handled indicates that a message was successfully sent and processed + */ + Handled, + /** + * Enqueued indicates that a message was successfully formed and then sent to an internal messaging service + */ + Enqueued, + /** + * NotHandled indicates that the message was not handled. This can occur if an exception occurs + * in the message processor or if internal messaging service reached capacity. + */ + NotHandled +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SharedData.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SharedData.java new file mode 100644 index 0000000..5c1392d --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SharedData.java @@ -0,0 +1,49 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * SharedData is used to access a model's, or globally, shared cache. + */ +public interface SharedData { + /** + * Retrieves an existing object from the cache. + * @param key the key mapping to a value. + * @return A cache result. + */ + public CacheResult get(String key); + + /** + * Put a new key/value mapping into the cache. + * @param key the key mapping to a value. + * @param value the value. + * @return a cache result. + */ + public CacheResult put(String key, byte[] value); + + /** + * Remove a key/value mapping from the cache. + * @param key the key mapping to a value. + * @return a cache result. + */ + public CacheResult remove(String key); + + /** + * Clear the shared data cache. + * @return a cache result. + */ + public CacheResult clear(); +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationController.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationController.java new file mode 100644 index 0000000..314f6eb --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationController.java @@ -0,0 +1,190 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +import java.time.Duration; +import java.util.Date; + +/** + * The SimulationController interface is used to interact with the running DigitalTwin simulation. + */ +public interface SimulationController { + + /** + *

        + * Retrieves the current simulation time increment. + *

        + * @return the simulation time increment. + */ + Duration getSimulationTimeIncrement(); + + /** + * + */ + + /** + *

        + * Retrieves the simulation start time. + *

        + * @return the simulation start time. + */ + Date getSimulationStartTime(); + + /** + *

        + * Delay simulation processing for this DigitalTwin instance for a duration of time. + *

        + * + *

        + * Simulation processing will be delayed for the duration specified relative to the current simulation time. + *

        + * + *

        + * Examples: + *

        + * + *

        + * at a current simulation time of 10, an interval of 20, and a delay of 40 -- the instance would + * skip one cycle of processing and be processed at simulation time 50. + *

        + * + *

        + * at a current simulation time of 10, an interval of 20, and a delay of 30 -- the instance would + * skip one cycle of processing and be processed at simulation time 50. + *

        + * + *

        + * at a current simulation time of 10, an interval of 20, and a delay of 50 -- the instance would + * skip two cycles of processing and be processed at simulation time 70. + *

        + * + * @param duration the duration to delay. + * @return {@link SendingResult#Handled} if the delay was processed or {@link SendingResult#NotHandled} + * if the delay was not processed. + */ + SendingResult delay(Duration duration); + + /** + *

        + * Delay simulation processing for this DigitalTwin instance, indefinitely. + *

        + * + *

        + * Simulation processing will be delayed until this instance is run with {@link SimulationController#runThisInstance()}. + *

        + * + * @return {@link SendingResult#Handled} if the delay was processed or {@link SendingResult#NotHandled} + * if the delay was not processed. + */ + SendingResult delayIndefinitely(); + + /** + *

        + * Asynchronously send a JSON serialized message to a DigitalTwin instance that will be processed by the DigitalTwin + * models {@link MessageProcessor#processMessages(ProcessingContext, DigitalTwinBase, Iterable)} method. + *

        + * @param modelName the model to send the messages too. + * @param telemetryMessage a blob representing a JSON serialized messages. + * @return {@link SendingResult#Handled} if the messages were processed, {@link SendingResult#Enqueued} if + * the messages are in process of being handled, or {@link SendingResult#NotHandled} if the delay was not processed. + */ + SendingResult emitTelemetry(String modelName, byte[] telemetryMessage); + + /** + *

        + * Asynchronously send a JSON serializable message to a DigitalTwin instance that will be processed by the DigitalTwin + * models {@link MessageProcessor#processMessages(ProcessingContext, DigitalTwinBase, Iterable)} method. + *

        + * @param modelName the model to send the messages too. + * @param jsonSerializableMessage an object message that is JSON serializable. + * @return {@link SendingResult#Handled} if the messages were processed, {@link SendingResult#Enqueued} if + * the messages are in process of being handled, or {@link SendingResult#NotHandled} if the delay was not processed. + */ + SendingResult emitTelemetry(String modelName, Object jsonSerializableMessage); + + /** + * Create a new digital twin instance for simulation processing. + * @param modelName the model name. + * @param instanceId the instance id. + * @param base the instance to create. + * @return {@link SendingResult#Handled} if the instance was created, {@link SendingResult#Enqueued} if the instance + * is in process of being created, or {@link SendingResult#NotHandled} if the instance could not be created. + * @param the type of the digital twin to create. + */ + SendingResult createInstance(String modelName, String instanceId, T base); + + /** + * Create a new digital twin instance for simulation processing from a persistence store. + * + * The twin instance will be loaded via model name and id from a persistence store. + * + * If no instance can be found, then an exception will be thrown and no instance will be created. + * + * @param model The model name. + * @param id the instance id. + * @return {@link SendingResult#Handled} if the instance was created, {@link SendingResult#Enqueued} if the instance + * is in process of being created, or {@link SendingResult#NotHandled} if the instance could not be created. + */ + SendingResult createInstanceFromPersistenceStore(String model, String id); + + /** + * The twin instance will be loaded via model name and id from a persistence store. + * + * The twin instance will be loaded via model name and id from a persistence store. + * + * If no instance can be found, then the default parameter instance will be used. + * + * @param model the model name. + * @param id the instance id. + * @param def the default instance to create. + * @return {@link SendingResult#Handled} if the instance was created, {@link SendingResult#Enqueued} if the instance + * * is in process of being created, or {@link SendingResult#NotHandled} if the instance could not be created. + * @param the type of the digital twin to create. + */ + SendingResult createInstanceFromPersistenceStore(String model, String id, T def); + + /** + * Delete and remove a digital twin instance from simulation processing. + * @param modelName the model name. + * @param instanceId the instance id. + * @return {@link SendingResult#Handled} if the instance was deleted, {@link SendingResult#Enqueued} if the instance + * is in process of being deleted, or {@link SendingResult#NotHandled} if the instance could not be deleted. + */ + SendingResult deleteInstance(String modelName, String instanceId); + + /** + * Delete and remove this digital twin instance from simulation processing. + * @return this local request will always return {@link SendingResult#Handled}. + */ + SendingResult deleteThisInstance(); + + /** + * Run this instance during this simulation step. The instance will be run using the models {@link SimulationProcessor#processModel(ProcessingContext, DigitalTwinBase, Date)} + * implementation. + * + * This will cause the simulation sub-system to run this instance regardless of the instances current + * {@link DigitalTwinBase#NextSimulationTime}. + */ + void runThisInstance(); + + /** + * Stop the simulation. + * @return a {@link SimulationStatus#InstanceRequestedStop}. + */ + SimulationStatus stopSimulation(); + + +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.java new file mode 100644 index 0000000..a98d396 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationProcessor.java @@ -0,0 +1,66 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +import java.io.Serializable; +import java.util.Date; + +/** + * Processes simulation events for a digital twin. + * @param the type of the digital twin. + */ +public abstract class SimulationProcessor implements Serializable { + + /** + * Default constructor. + */ + public SimulationProcessor() {} + + /** + * Processes simulation events for a real-time digital twin. + * @param context the processing context. + * @param instance the digital twin instance. + * @param epoch the current time of the simulation. + * @return {@link ProcessingResult#UpdateDigitalTwin} to update the digital twin, or + * {@link ProcessingResult#NoUpdate} to ignore the changes. + */ + public abstract ProcessingResult processModel(ProcessingContext context, T instance, Date epoch); + + /** + *

        + * Optional method that is called per-instance when a simulation is started. Default behavior is a no-op. + *

        + * + *

        + * onInitSimulation can be used when internal digital twin starting state is set outside the context of a digital twins init method and may be changed + * between simulation runs. + *

        + *
          + *
        • Set variables in global or shared data.
        • + *
        • Run a simulation.
        • + *
        • onInitSimulation is called (per-instance) and digital twin instances set internal state based on the values in shared data.
        • + *
        • Complete simulation and evaluate the result.
        • + *
        + * + * @param context The simulation init context. + * @param instance The digital twin instance. + * @param epoch the simulation start time. + * @return {@link ProcessingResult#UpdateDigitalTwin} or {@link ProcessingResult#NoUpdate}. Default behavior: {@link ProcessingResult#NoUpdate}. + */ + public ProcessingResult onInitSimulation(InitSimulationContext context, T instance, Date epoch) { + return ProcessingResult.NoUpdate; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.java new file mode 100644 index 0000000..93f8ee4 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/SimulationStatus.java @@ -0,0 +1,50 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * The status of a simulation. + */ +public enum SimulationStatus { + /** + * The simulation is running. + */ + Running, + /** + * The simulation status is not set. + */ + NotSet, + /** + * The user requested a stop. + */ + UserRequested, + /** + * The simulation end time has been reached. + */ + EndTimeReached, + /** + * There is no remaining work for the simulation. + */ + NoRemainingWork, + /** + * A digital twin instance has requested the simulation to stop by calling {@link SimulationController#stopSimulation()} + */ + InstanceRequestedStop, + /** + * There was a runtime-change of simulation configuration. + */ + UnexpectedChangeInConfiguration; +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.java new file mode 100644 index 0000000..852174e --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerActionResult.java @@ -0,0 +1,79 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * The result of a timer action. + */ +public enum TimerActionResult { + /** + * The operation completed successfully. + */ + Success(0), + + /** + * Failed to start a new timer due to reaching the limit for a number of active timers. + */ + FailedTooManyTimers(1), + + /** + * Failed to stop the existing timer, the timer is no longer active. + */ + FailedNoSuchTimer(2), + + /** + * Failed to start the timer, the timer with the specified name already exists. + */ + FailedTimerAlreadyExists(3), + + /** + * Failed to start/stop timer due to an internal error. + */ + FailedInternalError(4); + + private final int _value; + private TimerActionResult(int val) { + _value = val; + } + + /** + * Convert an ordinal into a {@link TimerActionResult}. + * + * 0 = {@link TimerActionResult#Success}, 1 = {@link TimerActionResult#FailedTooManyTimers}, + * 2 = {@link TimerActionResult#FailedNoSuchTimer}, 3 = {@link TimerActionResult#FailedTimerAlreadyExists}, + * 4 = {@link TimerActionResult#FailedInternalError} + * @param val the ordinal value. + * @return the associated {@link TimerActionResult} or throws an IllegalArgumentException for an unexpected + * ordinal value. + */ + public static TimerActionResult fromOrdinal(int val) { + switch (val) { + case 0: + return Success; + case 1: + return FailedTooManyTimers; + case 2: + return FailedNoSuchTimer; + case 3: + return FailedTimerAlreadyExists; + case 4: + return FailedInternalError; + default: + throw new IllegalArgumentException("No known TimerActionResult from value: " + val); + + } + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerHandler.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerHandler.java new file mode 100644 index 0000000..6380324 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerHandler.java @@ -0,0 +1,33 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * Callback to a handle a timer message for a {@link DigitalTwinBase}. + * @param the type of the {@link DigitalTwinBase}. + */ +public interface TimerHandler { + + /** + * Callback to handle a timer message. + * @param timerName the timer's unique identifier. + * @param instance the digital twin instance. + * @param ctx the processing context. + * @return {@link ProcessingResult#UpdateDigitalTwin} to update the digital twin instance or + * {@link ProcessingResult#NoUpdate} to leave the instance state as is. + */ + public ProcessingResult onTimedMessage(String timerName, T instance, ProcessingContext ctx); +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.java new file mode 100644 index 0000000..e9c151d --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerMetadata.java @@ -0,0 +1,76 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +import java.lang.reflect.InvocationTargetException; +import java.time.Duration; + +/** + * Metadata class for a timer. + * @param the type of the {@link DigitalTwinBase} implementation. + */ +public class TimerMetadata { + final String timerHandler; + final TimerType timerType; + final long timerIntervalMs; + final int timerId; + + /** + * Constructs a timer metadata. + * @param handler the timer handler. + * @param timerType the timer type. + * @param timerIntervalMs the timer interval. + * @param timerIdx the timer index. + */ + public TimerMetadata(TimerHandler handler, TimerType timerType, long timerIntervalMs, int timerIdx) { + this.timerHandler = handler.getClass().getName(); + this.timerType = timerType; + this.timerIntervalMs = timerIntervalMs; + this.timerId = timerIdx; + } + + /** + * Retrieves the timer handler class name. + * @return the timer handler class name. + */ + public String getTimerHandlerClass() { + return timerHandler; + } + + /** + * Retrieves the timer type. + * @return the timer type. + */ + public TimerType getTimerType() { + return timerType; + } + + /** + * Retrieves the timer interval. + * @return the timer interval. + */ + public long getTimerIntervalMs() { + return timerIntervalMs; + } + + /** + * Retrieves the timer ID. + * @return the timer ID. + */ + public int getTimerId() { + return timerId; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerType.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerType.java new file mode 100644 index 0000000..66626e1 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/TimerType.java @@ -0,0 +1,30 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.core; + +/** + * Enum representation of the available timer types + */ +public enum TimerType { + /** + * This timer should reoccur on a schedule. + */ + Recurring, + /** + * This timer should trigger one time. + */ + OneTime +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/package-info.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/package-info.java new file mode 100644 index 0000000..4ccf77f --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/core/package-info.java @@ -0,0 +1,21 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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. +*/ + +/** + * Digital twin model API - Create a digital twin model. + */ +package com.scaleoutsoftware.digitaltwin.core; + diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/Constants.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/Constants.java new file mode 100644 index 0000000..5948de6 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/Constants.java @@ -0,0 +1,99 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +class Constants { + public static final int MAX_TIMER_COUNT = 5; + /** + * + * Returns a hash that is suitable for inserting an object into a hash-based collection. + *

        + * ----------------------------------------------------------------------------- + * MurmurHash3 was written by Austin Appleby, and is placed in the public + * domain. The author hereby disclaims copyright to this source code. + * + * Note - The x86 and x64 versions do _not_ produce the same results, as the + * algorithms are optimized for their respective platforms. You can still + * compile and run any of them on any platform, but your performance with the + * non-native version will be less than optimal. + * Original code from: + * https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp + * ----------------------------------------------------------------------------- + * + * This implementation is tweaked to initialize with a hard-coded seed and to return a long instead of a + * 32-bit unsigned integer (since Java doesn't easily support unsigned integers). + * @param data The byte array to be hashed. + * @return Hash code for the array, with values ranging from 0 to 4,294,967,295. + */ + static long getHash(byte[] data) { + if(data == null) { + throw new IllegalArgumentException("Hash data was null."); + } + + final int seed = 947203; // Scaleout's implementation-specific seed. + final int c1 = 0xcc9e2d51; + final int c2 = 0x1b873593; + + int len = data.length; + int h1 = seed; + int roundedEnd = len & 0xfffffffc; // round down to 4 byte block + + for (int i = 0; i < roundedEnd; i += 4) { + // little endian load order + int k1 = (data[i] & 0xff) | ((data[i + 1] & 0xff) << 8) | ((data[i + 2] & 0xff) << 16) | (data[i + 3] << 24); + k1 *= c1; + k1 = (k1 << 15) | (k1 >>> 17); // ROTL32(k1,15); + k1 *= c2; + + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> 19); // ROTL32(h1,13); + h1 = h1 * 5 + 0xe6546b64; + } + + // tail (leftover bytes that didn't fit into a 4-byte block) + int k1 = 0; + + switch (len & 0x03) { + case 3: + k1 = (data[roundedEnd + 2] & 0xff) << 16; + // fallthrough + case 2: + k1 |= (data[roundedEnd + 1] & 0xff) << 8; + // fallthrough + case 1: + k1 |= (data[roundedEnd] & 0xff); + k1 *= c1; + k1 = (k1 << 15) | (k1 >>> 17); // ROTL32(k1,15); + k1 *= c2; + h1 ^= k1; + } + + // finalization + h1 ^= len; + + // fmix(h1); + h1 ^= h1 >>> 16; + h1 *= 0x85ebca6b; + h1 ^= h1 >>> 13; + h1 *= 0xc2b2ae35; + h1 ^= h1 >>> 16; + + // Other languages want to represent the hash as an unsigned int, but java doesn't easily have + // unsigned types. So we move the signed integer's bits into an "unsigned" long, which + // is big enough to hold all the positive values of an unsigned int. + return h1 & 0x00000000ffffffffL; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/LogMessage.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/LogMessage.java new file mode 100644 index 0000000..4708e20 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/LogMessage.java @@ -0,0 +1,56 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import java.util.logging.Level; + +/** + * A messaged that was logged by a digital twin. + */ +public class LogMessage { + private String _message; + private Level _severity; + private long _timestamp; + LogMessage(Level severity, String message) { + _message = message; + _severity = severity; + _timestamp = System.currentTimeMillis(); + } + + /** + * Retrieve the string message associated with this log message. + * @return the message. + */ + public String getMessage() { + return _message; + } + + /** + * Retrieve the severity of this log message. + * @return the severity. + */ + public Level getSeverity() { + return _severity; + } + + /** + * Retrieve the timestamp from when this message was generated. + * @return the timestamp. + */ + public long getTimestamp() { + return _timestamp; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/ProxyState.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/ProxyState.java new file mode 100644 index 0000000..0dd7e68 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/ProxyState.java @@ -0,0 +1,25 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +enum ProxyState { + // The proxy has an unspecified state. + Unspecified, + // The proxy is active. + Active, + // the proxy is removed + Removed +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEvent.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEvent.java new file mode 100644 index 0000000..686936e --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEvent.java @@ -0,0 +1,69 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.ProcessingContext; + +import java.util.Date; + +abstract class SimulationEvent implements Comparable { + protected String _model; + protected String _id; + protected long _priority; + protected long _nextSimulationTime; + + SimulationEvent(String model, String id, long priority) { + _model = model; + _id = id; + _priority = priority; + } + + abstract SimulationEventResult processSimulationEvent(ProcessingContext context, Date currentTime) throws WorkbenchException; + + abstract ProxyState getProxyState(); + + abstract void setProxyState(ProxyState newState); + + abstract void handleResetNextSimulationTime(); + + abstract void simulationInit(Date simulationStartTime); + + long getPriority() { + return _priority; + } + + void setPriority(long priority) { + _priority = priority; + } + + String getId() { + return _id; + } + + String getModel() {return _model;} + + void setNextSimulationTime(long nextSimulationTime) { + _nextSimulationTime = nextSimulationTime; + handleResetNextSimulationTime(); + } + + + + @Override + public int compareTo(SimulationEvent other) { + return Long.compare(this._priority, other._priority); + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.java new file mode 100644 index 0000000..f917da6 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventResult.java @@ -0,0 +1,22 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +/** + * A simulation event result. + */ +public abstract class SimulationEventResult { +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTimerImpl.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTimerImpl.java new file mode 100644 index 0000000..49f9b5d --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTimerImpl.java @@ -0,0 +1,63 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase; +import com.scaleoutsoftware.digitaltwin.core.ProcessingContext; +import com.scaleoutsoftware.digitaltwin.core.TimerHandler; + +import java.util.Date; + +class SimulationEventTimerImpl extends SimulationEvent { + TwinProxy _proxy; + TimerHandler _handler; + String _timerName; + + SimulationEventTimerImpl(String model, String id, long priority, String name, TwinProxy proxy, TimerHandler handler) { + super(model, id,priority); + _timerName = name; + _proxy = proxy; + _handler = handler; + + } + + @Override + SimulationEventResult processSimulationEvent(ProcessingContext context, Date currentTime) { + DigitalTwinBase base = _proxy.getInstance(); + _handler.onTimedMessage(_timerName, base, context); + _proxy.setInstance(base); + return new SimulationEventResult(){}; + } + + @Override + ProxyState getProxyState() { + return _proxy.getProxyState(); + } + + @Override + void setProxyState(ProxyState newState) { + _proxy.setProxyState(newState); + } + + @Override + void handleResetNextSimulationTime() { + } + + @Override + void simulationInit(Date simulationStartTime) { + + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTwinImpl.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTwinImpl.java new file mode 100644 index 0000000..27e4147 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationEventTwinImpl.java @@ -0,0 +1,93 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.*; + +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.Objects; + +class SimulationEventTwinImpl extends SimulationEvent { + SimulationProcessor _processor; + TwinProxy _proxy; + SharedData _modelSharedData; + SharedData _globalSharedData; + + SimulationEventTwinImpl(long priority, TwinProxy proxy, SimulationProcessor processor, SharedData modelSharedData, SharedData globalSharedData) { + super(proxy.getInstance().Model, proxy.getInstance().Id, priority); + _proxy = proxy; + _processor = processor; + _modelSharedData = modelSharedData; + _globalSharedData = globalSharedData; + } + + @Override + SimulationEventResult processSimulationEvent(ProcessingContext context, Date currentTime) throws WorkbenchException { + try { + DigitalTwinBase base = _proxy.getInstance(); + synchronized (_proxy) { + WorkbenchProcessingContext wpc = (WorkbenchProcessingContext)context; + wpc.resetInstance(base); + _processor.processModel(wpc, base, currentTime); + _proxy.setInstance(base); + } + } catch (Exception e) { + throw new WorkbenchException(e); + } + return new SimulationEventResult(){}; + } + + @Override + ProxyState getProxyState() { + return _proxy.getProxyState(); + } + + @Override + void setProxyState(ProxyState newState) { + _proxy.setProxyState(newState); + } + + @Override + void handleResetNextSimulationTime() { + DigitalTwinBase base = _proxy.getInstance(); + base.NextSimulationTime = _nextSimulationTime; + _proxy.setInstance(base); + } + + @Override + void simulationInit(Date simulationStartTime) { + InitSimulationContext context = new WorkbenchInitSimulationContext(_globalSharedData, _modelSharedData); + synchronized (_proxy) { + DigitalTwinBase base = _proxy.getInstance(); + _processor.onInitSimulation(context, base, simulationStartTime); + _proxy.setInstance(base); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SimulationEventTwinImpl that = (SimulationEventTwinImpl) o; + return this._proxy.getInstance().getId().compareTo(that._id) == 0 && this._proxy.getInstance().getModel().compareTo(that._model) == 0; + } + + @Override + public int hashCode() { + return (int)Constants.getHash(_id.getBytes(StandardCharsets.UTF_8)); + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationScheduler.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationScheduler.java new file mode 100644 index 0000000..fa46b98 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationScheduler.java @@ -0,0 +1,177 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.*; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +class SimulationScheduler { + static AtomicInteger PROCESSED = new AtomicInteger(0); + static AtomicInteger QUEUED = new AtomicInteger(0); + static AtomicInteger SENT = new AtomicInteger(0); + private final List _workers; + private final ExecutorService _simulationService; + private final String _modelName; + private final SimulationProcessor _simulationProcessor; + private final Logger _logger = LogManager.getLogger(SimulationScheduler.class); + private long _curSimulationTime; + private Date _simulationStartTime; + private boolean _isActive; + + + public SimulationScheduler(String modelName, + Class digitalTwinClass, + SimulationProcessor modelProcessor, + TwinExecutionEngine executor, + int numWorkers) { + _modelName = modelName; + _simulationProcessor = modelProcessor; + _workers = new ArrayList<>(numWorkers); + _simulationService = Executors.newFixedThreadPool(numWorkers, new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r, "SimulationWorker"); + t.setName(t.getName()+"-"+t.getId()); + t.setDaemon(true); + return t; + } + }); + for(int i = 0; i < numWorkers; i++) { + _workers.add(new SimulationWorker(i, _modelName, _simulationProcessor, digitalTwinClass, executor, this)); + } + } + + // -------------- package private methods ---------------- + SimulationStep runSimulation(SimulationStepArgs runSimulationEventArgs) { + _logger.info("Received run simulation event with args: " + runSimulationEventArgs.getCurSimulationTime() + " iterationSize: " + runSimulationEventArgs.getIterationSize() + " flags: " + runSimulationEventArgs.getSimulationFlags() ); + long current = System.currentTimeMillis(); + SimulationStep ret; + _curSimulationTime = runSimulationEventArgs.getCurSimulationTime(); + + if (runSimulationEventArgs.getSimulationFlags() == WorkbenchSimulationFlags.Stop) { + _logger.info("Stopping simulation; shutting down workers."); + for(SimulationWorker worker : _workers) { + worker.shutdown(); + } + return new SimulationStep(SimulationStatus.UserRequested,_curSimulationTime); + } if(runSimulationEventArgs.getSimulationFlags() == WorkbenchSimulationFlags.Start) { + _logger.info("Starting simulation; initializing instances."); + for(SimulationWorker worker : _workers) { + worker.initSimulation(new Date(runSimulationEventArgs.getCurSimulationTime())); + } + return new SimulationStep(SimulationStatus.Running,_curSimulationTime); + } else { + ret = runSimulationStep(runSimulationEventArgs); + } + + _logger.info(String.format("runSim complete in %s ms... returning next: %s", (System.currentTimeMillis()-current), ret)); + return ret; + } + + long getCurrentTime() { + if(_isActive) { + return _curSimulationTime; + } + return System.currentTimeMillis(); + } + + void setStatus(boolean active) { + _isActive = active; + } + + Date getSimulationStartTime() { + return _simulationStartTime; + } + + void setSimulationStartTime(Date simulationStartTime) { + _simulationStartTime = simulationStartTime; + } + + + + // -------------- private methods ---------------- + private SimulationStep runSimulationStep(SimulationStepArgs args) { + long currentTimeMs = System.currentTimeMillis(); + List> futures = new LinkedList<>(); + for(SimulationWorker worker : _workers) { + worker.reset(args); + futures.add(_simulationService.submit(worker)); + } + + SimulationStatus status = SimulationStatus.Running; + boolean workFound = false; + long next = -1; + long cur = Long.MAX_VALUE; + for(Future f : futures) { + try { + SimulationStep result = f.get(); + if(result.getStatus() == SimulationStatus.Running) { + workFound = true; + } + if(result.getStatus() != SimulationStatus.Running) { + status = result.getStatus(); + } + cur = result.getTime(); + if (cur != -1 && cur < next) { + _logger.info(String.format("future return is lower than next... cur: %s next: %s", cur, next)); + next = cur; + } else if (next == -1 && cur > -1) { + next = cur; + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + } + _logger.info(String.format("Simulation step complete in %s ms... returning next: %s", (System.currentTimeMillis()-currentTimeMs), next)); + + if(workFound && status == SimulationStatus.NoRemainingWork) status = SimulationStatus.Running; + return new SimulationStep(status, next); + } + + void addInstance(TwinProxy proxy) { + SimulationWorker worker = _workers.get(findSlotId(proxy.getInstance().getId())); + worker.addTwinToQueue(proxy); + } + + void addTimer(TwinProxy proxy, String modelName, String id, String timerName, TimerType type, Duration interval, TimerHandler handler) { + SimulationWorker worker = _workers.get(findSlotId(proxy.getInstance().getId())); + worker.addTimerToQueue(proxy, modelName, id, timerName, type, interval, handler); + } + void stopTimer(String modelName, String id, String timerName) { + SimulationWorker worker = _workers.get(findSlotId(id)); + worker.stopTimer(modelName, id, timerName); + } + + void runThisInstance(String model, String id) throws WorkbenchException { + SimulationWorker worker = _workers.get(findSlotId(id)); + worker.runThisInstance(model, id); + } + + private int findSlotId(String id) { + return (int)((Constants.getHash(id.getBytes(StandardCharsets.UTF_8))) % (long)_workers.size()); + } + + +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStep.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStep.java new file mode 100644 index 0000000..c2a6dba --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStep.java @@ -0,0 +1,57 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.SimulationStatus; + +/** + * The simulation step class encases the metadata for a completed interval of a simulation. + */ +public class SimulationStep { + private SimulationStatus _status; + private long _intervalTime; + + SimulationStep(SimulationStatus status, long intervalTime) { + _status = status; + _intervalTime = intervalTime; + } + + /** + * Retrieve the {@link SimulationStatus} of the simulation interval. + * @return the current simulation status. + */ + public SimulationStatus getStatus() { + return _status; + } + + /** + * Retrieve the time of the simulation interval. + * @return the simulation interval time. + */ + public long getTime() { + return _intervalTime; + } + + // merge two simulation steps + void merge(SimulationStep result) { + if(this._status == SimulationStatus.Running && result._status != SimulationStatus.Running) { + this._status = result._status; + } + if(this._intervalTime > result._intervalTime) { + this._intervalTime = result.getTime(); + } + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStepArgs.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStepArgs.java new file mode 100644 index 0000000..c65ad79 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationStepArgs.java @@ -0,0 +1,40 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +class SimulationStepArgs { + private long _curSimulationTime; + private long _interval; + private WorkbenchSimulationFlags _simulationFlags; + + SimulationStepArgs(long currentSimulationTime, long interval, WorkbenchSimulationFlags flags) { + _curSimulationTime = currentSimulationTime; + _interval = interval; + _simulationFlags = flags; + } + + long getCurSimulationTime() { + return _curSimulationTime; + } + + long getIterationSize() { + return _interval; + } + + WorkbenchSimulationFlags getSimulationFlags() { + return this._simulationFlags; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationTime.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationTime.java new file mode 100644 index 0000000..e09c0e7 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationTime.java @@ -0,0 +1,36 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import java.util.Date; + +class SimulationTime { + private long _currentSimulationEpochMs; + private long _simulationIntervalMs; + + public SimulationTime(long currentSimulationEpochMs, long intervalMs) { + _currentSimulationEpochMs = currentSimulationEpochMs; + _simulationIntervalMs = intervalMs; + } + + long getCurrentSimulationTime() { + return _currentSimulationEpochMs; + } + + long getNextSimulationTime() { + return _currentSimulationEpochMs + _simulationIntervalMs; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationWorker.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationWorker.java new file mode 100644 index 0000000..ebaa891 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/SimulationWorker.java @@ -0,0 +1,229 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.*; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.time.Duration; +import java.util.*; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Predicate; + +class SimulationWorker implements Callable { + private final Logger _logger = LogManager.getLogger(SimulationWorker.class); + private final PriorityQueue _timeOrderedQueue = new PriorityQueue<>(); + private final ConcurrentHashMap _timers = new ConcurrentHashMap<>(); + private final ConcurrentHashMap _events = new ConcurrentHashMap<>(); + private final int _slotId; + private final String _modelName; + private final SimulationProcessor _simulationProcessor; + private final TwinExecutionEngine _twinExecutionEngine; + private final SimulationScheduler _simulationScheduler; + private long _curSimulationTime; + private long _simulationInterval; + private long _nextSimulationTime; + private boolean _running; + + public SimulationWorker(int slotId, + String model, + SimulationProcessor modelProcessor, + Class digitalTwinClass, + TwinExecutionEngine engine, + SimulationScheduler scheduler) { + _slotId = slotId; + _modelName = model; + _simulationProcessor = modelProcessor; + _twinExecutionEngine = engine; + _simulationScheduler = scheduler; + } + + public void reset(SimulationStepArgs runSimulationEventArgs) { + _curSimulationTime = runSimulationEventArgs.getCurSimulationTime(); + _simulationInterval = runSimulationEventArgs.getIterationSize(); + _logger.info(String.format("Worker reset... cur: %s interval: %s", _curSimulationTime, _simulationInterval)); + } + + public void shutdown() { + _timeOrderedQueue.clear(); + _events.clear(); + _timers.clear(); + } + + public void addTwinToQueue(TwinProxy proxy) { + SimulationEvent event = new SimulationEventTwinImpl(_curSimulationTime, proxy, _simulationProcessor, new WorkbenchSharedData(_twinExecutionEngine.getGlobalSharedData()), new WorkbenchSharedData(_twinExecutionEngine.getModelData(_modelName))); + _timeOrderedQueue.add(event); + _events.put(String.format("%s%s",event.getModel(),event.getId()), event); + } + + public void addTwinToQueue(SimulationEvent event) { + _timeOrderedQueue.add(event); + _events.put(String.format("%s%s",event.getModel(),event.getId()), event); + } + + public void addTimerToQueue(TwinProxy proxy, String modelName, String id, String timerName, TimerType type, Duration interval, TimerHandler handler) { + SimulationEvent event = new SimulationEventTimerImpl(modelName, id, interval.toMillis(), timerName, proxy, handler); + _timers.put(timerName, event); + _timeOrderedQueue.add(event); + _events.put(String.format("%s%s",event.getModel(),event.getId()), event); + } + + public void stopTimer(String model, String id, String timerName) { + SimulationEvent event = _timers.remove(String.format("%s%s%s",model, id,timerName)); + event.setProxyState(ProxyState.Removed); + _events.remove(String.format("%s%s",event.getModel(),event.getId())); + } + + void initSimulation(Date startTime) { + for(SimulationEvent event : _events.values()) { + event.simulationInit(startTime); + } + } + + public void runThisInstance(String model, String id) throws WorkbenchException { + SimulationEvent event = _events.remove(String.format("%s%s",model,id)); + if(event == null) { + TwinProxy proxy = _twinExecutionEngine.getTwinProxy(model, id); + event = new SimulationEventTwinImpl(_curSimulationTime, proxy, _simulationProcessor, new WorkbenchSharedData(_twinExecutionEngine.getGlobalSharedData()), new WorkbenchSharedData(_twinExecutionEngine.getModelData(_modelName))); + } else { + _timeOrderedQueue.remove(event); + } + WorkbenchSimulationController simulationController = new WorkbenchSimulationController(_twinExecutionEngine, _simulationScheduler); + WorkbenchProcessingContext processingContext = new WorkbenchProcessingContext(_twinExecutionEngine, simulationController); + processingContext.reset(model, id, null); + Date date = new Date(); + date.setTime(_curSimulationTime); + event.processSimulationEvent(processingContext, date); + if(simulationController.delayRequested()) { + long delay = simulationController.getRequestedDelay(); + if(delay == 0x0000e677d21fdbffL) { + event.setPriority(simulationController.getRequestedDelay()); + event.setNextSimulationTime(simulationController.getRequestedDelay()); + } else if (delay == 0L) { + event.setPriority(_curSimulationTime); + event.setNextSimulationTime(_curSimulationTime); + } else { + event.setPriority(_curSimulationTime + simulationController.getRequestedDelay()); + event.setNextSimulationTime(_curSimulationTime + simulationController.getRequestedDelay()); + } + } else { + event.setPriority(_curSimulationTime + _simulationInterval); + event.setNextSimulationTime(_curSimulationTime + _simulationInterval); + } + _events.put(String.format("%s%s",model,id), event); + _timeOrderedQueue.add(event); + } + + @Override + public SimulationStep call() throws Exception { + synchronized (this) { + _running = true; + } + SimulationTime simulationTime = new SimulationTime(_curSimulationTime, _simulationInterval); + long lowestNextSimulationTime = Long.MAX_VALUE; + long nextQueueTm = Long.MAX_VALUE; + boolean keepProcessing = true; + boolean delayed = false; + boolean addToBuffer = true; + List buffer = new LinkedList<>(); + WorkbenchSimulationController simulationController = new WorkbenchSimulationController(_twinExecutionEngine, _simulationScheduler); + WorkbenchProcessingContext processingContext = new WorkbenchProcessingContext(_twinExecutionEngine, simulationController); + Date currentTime = new Date(); + currentTime.setTime(_curSimulationTime); + int processed = 0; + do { + addToBuffer = true; + SimulationEvent next = _timeOrderedQueue.poll(); + if(next != null) { + if(next.getProxyState() == ProxyState.Active) { + processed++; + nextQueueTm = next.getPriority(); + if(next.getPriority() <= simulationTime.getCurrentSimulationTime()) { + simulationController.reset(_modelName, next.getId()); + processingContext.reset(_modelName, next.getId(), null); + ProcessingResult result = ProcessingResult.NoUpdate; + try { + next.processSimulationEvent(processingContext, currentTime); + } catch (Exception e) { + _logger.error("simulation processor threw an exception.", e); + result = ProcessingResult.NoUpdate; + } + if(simulationController.delayRequested()) { + delayed = true; + long delay = simulationController.getRequestedDelay(); + if(delay == 0x0000e677d21fdbffL) { + next.setPriority(simulationController.getRequestedDelay()); + next.setNextSimulationTime(simulationController.getRequestedDelay()); + } else if (delay == 0L) { + next.setPriority(_curSimulationTime); + next.setNextSimulationTime(_curSimulationTime); + addToBuffer = false; + } else { + next.setPriority(simulationTime.getCurrentSimulationTime() + simulationController.getRequestedDelay()); + next.setNextSimulationTime(simulationTime.getCurrentSimulationTime() + simulationController.getRequestedDelay()); + } + } else { + next.setPriority(simulationTime.getNextSimulationTime()); + next.setNextSimulationTime(simulationTime.getNextSimulationTime()); + } + if(lowestNextSimulationTime > next.getPriority()) { + lowestNextSimulationTime = next.getPriority(); + } + if(simulationController.deleted()) { + result = ProcessingResult.NoUpdate; + } + if(!simulationController.enqueue()) { + // the user called "runThisInstance" -- the work item has already been re-enqueued for the + // current time slice. + addToBuffer = false; + } + } else { + synchronized (this) { + _running = false; + } + keepProcessing = false; + } + if(!simulationController.deleted() && addToBuffer) { + buffer.add(next); + } + } + } else { + synchronized (this) { + _running = false; + } + keepProcessing = false; + nextQueueTm = Long.MAX_VALUE; + } + } while (keepProcessing); + + _timeOrderedQueue.addAll(buffer); + _nextSimulationTime = Math.min(lowestNextSimulationTime, nextQueueTm); + + if(_nextSimulationTime == Long.MAX_VALUE && !delayed) { // check to make sure the user didn't set delay to Long.MAX_VALUE + _nextSimulationTime = simulationTime.getNextSimulationTime(); + } + + SimulationScheduler.PROCESSED.addAndGet(processed); + SimulationScheduler.QUEUED.addAndGet(_timeOrderedQueue.size()); + if(processed > 0) { + return new SimulationStep(simulationController.getSimulationStatus(), _nextSimulationTime); + } else { + return new SimulationStep(SimulationStatus.NoRemainingWork, _nextSimulationTime); + } + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinExecutionEngine.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinExecutionEngine.java new file mode 100644 index 0000000..bd34eca --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinExecutionEngine.java @@ -0,0 +1,439 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.google.gson.Gson; +import com.scaleoutsoftware.digitaltwin.core.*; + +import java.io.Closeable; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.time.Duration; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; + +class TwinExecutionEngine implements Closeable { + private List _modelNames; + private ConcurrentHashMap> _digitalTwins; + private ConcurrentHashMap _messageProcessors; + private ConcurrentHashMap _simulationProcessors; + private ConcurrentHashMap> _messageProcessorValueTypes; + private ConcurrentHashMap> _modelInstances; + private ConcurrentHashMap> _alertProviders; + private ConcurrentHashMap> _modelsSharedData; + private HashMap _globalSharedData; + private Workbench _workbench; + private ConcurrentHashMap _simulationSchedulers; + private ConcurrentHashMap _realTimeTimers; + private Gson _gson; + + + TwinExecutionEngine(Workbench workbench) { + _workbench = workbench; + init(); + } + + void init( ) { + _modelNames = new LinkedList<>(); + _digitalTwins = new ConcurrentHashMap<>(); + _messageProcessors = new ConcurrentHashMap<>(); + _simulationProcessors = new ConcurrentHashMap<>(); + _messageProcessorValueTypes = new ConcurrentHashMap<>(); + _modelInstances = new ConcurrentHashMap<>(); + _modelsSharedData = new ConcurrentHashMap<>(); + _globalSharedData = new HashMap<>(); + _alertProviders = new ConcurrentHashMap<>(); + _simulationSchedulers = new ConcurrentHashMap<>(); + _realTimeTimers = new ConcurrentHashMap<>(); + _gson = new Gson(); + } + + void addDigitalTwin(String digitalTwinModelName, MessageProcessor digitalTwinMessageProcessor, Class dtType, Class messageClass) { + _modelNames.add(digitalTwinModelName); + _digitalTwins.put(digitalTwinModelName, dtType); + _messageProcessors.put(digitalTwinModelName, digitalTwinMessageProcessor); + _messageProcessorValueTypes.put(digitalTwinModelName, messageClass); + } + + void addDigitalTwin(String digitalTwinModelName, MessageProcessor digitalTwinMessageProcessor, SimulationProcessor simulationProcessor, Class dtType, Class messageClass, int numWorkers) { + _modelNames.add(digitalTwinModelName); + _digitalTwins.put(digitalTwinModelName, dtType); + _messageProcessors.put(digitalTwinModelName, digitalTwinMessageProcessor); + _simulationProcessors.put(digitalTwinModelName, simulationProcessor); + _messageProcessorValueTypes.put(digitalTwinModelName, messageClass); + _simulationSchedulers.put(digitalTwinModelName, new SimulationScheduler(digitalTwinModelName, dtType, simulationProcessor, this, numWorkers)); + } + + void addTimer(String modelName, String id, String timerName, TimerType type, Duration interval, TimerHandler handler) { + ConcurrentHashMap modelInstances = _modelInstances.get(modelName); + TwinProxy proxy = modelInstances.get(id); + SimulationScheduler scheduler = _simulationSchedulers.get(modelName); + if (scheduler != null) { + scheduler.addTimer(proxy, modelName, id, timerName, type, interval, handler); + } else { + Timer timer = new Timer(); + WorkbenchTimerTask task = new WorkbenchTimerTask(this, modelName, id, timerName, proxy, type, interval, handler); + _realTimeTimers.put(String.format("%s%s%s", modelName, id, timerName), task); + switch(type) { + case OneTime: + timer.schedule(task, interval.toMillis()); + break; + case Recurring: + timer.scheduleAtFixedRate(task, interval.toMillis(), interval.toMillis()); + break; + } + } + + } + + void stopTimer(String modelName, String id, String timerName) { + SimulationScheduler scheduler = _simulationSchedulers.get(modelName); + if (scheduler != null) { + scheduler.stopTimer(modelName, id, timerName); + } else { + WorkbenchTimerTask task = _realTimeTimers.get(String.format("%s%s%s",modelName, id,timerName)); + task.cancel(); + } + } + + void addAlertProvider(String modelName, AlertProviderConfiguration configuration) { + ConcurrentHashMap configMap = new ConcurrentHashMap<>(); + configMap.put(configuration.getName(), configuration); + _alertProviders.put(modelName, configMap); + } + + void updateTwin(String model, String id, TwinProxy proxy) { + ConcurrentHashMap modelInstances = _modelInstances.get(model); + modelInstances.put(id, proxy); + _modelInstances.put(model, modelInstances); + } + + Date getTime(String model) { + if(_simulationSchedulers.containsKey(model)) { + SimulationScheduler scheduler = _simulationSchedulers.get(model); + return new Date(scheduler.getCurrentTime()); + } + return new Date(System.currentTimeMillis()); + } + + void setSimulationStatus(boolean status) { + for(SimulationScheduler scheduler : _simulationSchedulers.values()) { + scheduler.setStatus(status); + } + } + + List runningModels() { + return _modelNames; + } + + HashMap getTwinInstances(String model) { + HashMap ret = new HashMap<>(); + ConcurrentHashMap instances = _modelInstances.get(model); + if(instances!= null) { + for(Map.Entry entry : instances.entrySet()) { + ret.put(entry.getKey(), entry.getValue().getInstance()); + } + } + return ret; + } + + DigitalTwinBase getTwinInstance(String model, String id) { + DigitalTwinBase ret = null; + ConcurrentHashMap instances = _modelInstances.get(model); + if(instances != null) { + TwinProxy proxy = instances.get(id); + if(proxy != null) { + ret = proxy.getInstance(); + } + } + return ret; + } + + TwinProxy getTwinProxy(String model, String id) { + TwinProxy proxy = null; + ConcurrentHashMap instances = _modelInstances.get(model); + if(instances != null) { + proxy = instances.get(id); + return proxy; + } + return proxy; + } + + String generateModelSchema(String model) throws WorkbenchException { + if(_digitalTwins.get(model) != null) { + ModelSchema schema; + if(_simulationProcessors.get(model) != null) { + schema = new ModelSchema( + _digitalTwins.get(model).getName(), + _messageProcessors.get(model).getClass().getName(), + _messageProcessorValueTypes.get(model).getName(), + _simulationProcessors.get(model).getClass().getName(), + List.copyOf(_alertProviders.get(model) == null ? Collections.emptyList() : _alertProviders.get(model).values())); + } else { + schema = new ModelSchema( + _digitalTwins.get(model).getName(), + _messageProcessors.get(model).getClass().getName(), + _messageProcessorValueTypes.get(model).getName(), + List.copyOf(_alertProviders.get(model) == null ? Collections.emptyList() : _alertProviders.get(model).values())); + } + + Gson gson = new Gson(); + String modelSchemaJson = gson.toJson(schema, ModelSchema.class); + return modelSchemaJson; + } else { + throw new WorkbenchException("Model has not been added to this workbench."); + } + } + + boolean hasAlertProviderConfiguration(String model, String alertProviderName) { + if(hasModel(model)) { + return _alertProviders.containsKey(model) && _alertProviders.getOrDefault(model, new ConcurrentHashMap<>()).containsKey(alertProviderName); + } else { + return false; + } + + } + + boolean hasModel(String modelName) { + return _modelNames.contains(modelName); + } + + SendingResult sendToSource(String source, String model, String id, String msg) throws WorkbenchException { + if(_modelNames.contains(source)) { + String toSend = String.format("[%s]", msg); + run(source, id, null, toSend); + return SendingResult.Handled; + } else { + ConcurrentHashMap> messagesByModel = _workbench.SOURCE_MESSAGES.getOrDefault(model, new ConcurrentHashMap<>()); + List messages = messagesByModel.getOrDefault(id, new LinkedList<>()); + messages.add(msg); + messagesByModel.put(id, messages); + _workbench.SOURCE_MESSAGES.put(model, messagesByModel); + return SendingResult.Handled; + } + } + + SendingResult sendToSource(String source, String model, String id, List jsonSerializableMessage) throws WorkbenchException { + if (_modelNames.contains(source)) { + run(source, id, null, jsonSerializableMessage); + return SendingResult.Handled; + } else { + String msg = _gson.toJson(jsonSerializableMessage); + ConcurrentHashMap> messagesByModel = _workbench.SOURCE_MESSAGES.getOrDefault(model, new ConcurrentHashMap>()); + List messages = messagesByModel.getOrDefault(id, new LinkedList<>()); + messages.add(msg); + messagesByModel.put(id, messages); + _workbench.SOURCE_MESSAGES.put(model, messagesByModel); + return SendingResult.Handled; + } + } + + SimulationStep runSimulationStep(SimulationStepArgs args) { + SimulationStep status = null; + for(Map.Entry entry : _simulationSchedulers.entrySet()) { + SimulationStep next = entry.getValue().runSimulation(args); + if(status == null) { + status = next; + } else { + status.merge(next); + } + } + return status; + } + + HashMap getModelData(String model) { + HashMap sharedData = _modelsSharedData.get(model); + if(sharedData == null) sharedData = new HashMap<>(); + _modelsSharedData.put(model, sharedData); + return sharedData; + } + + HashMap getGlobalSharedData() { + return _globalSharedData; + } + + + public void logMessage(String model, LogMessage message) { + ConcurrentLinkedQueue prev = _workbench.LOGGED_MESSAGES.get(model); + if(prev == null) { + synchronized (_workbench.LOGGED_MESSAGES) { + prev = _workbench.LOGGED_MESSAGES.get(model); + if(prev == null) { + prev = new ConcurrentLinkedQueue<>(); + _workbench.LOGGED_MESSAGES.put(model, prev); + } + } + } + prev.add(message); + _workbench.LOGGED_MESSAGES.put(model, prev); + } + + public void recordAlertMessage(String model, String alertProvider, AlertMessage message) { + ConcurrentHashMap> perModelMessages = _workbench.ALERT_MESSAGES.getOrDefault(model, new ConcurrentHashMap<>()); + ConcurrentLinkedQueue perApMessages = perModelMessages.getOrDefault(alertProvider, new ConcurrentLinkedQueue<>()); + perApMessages.add(message); + perModelMessages.put(alertProvider, perApMessages); + _workbench.ALERT_MESSAGES.put(model, perModelMessages); + } + + public void createInstance(String modelName, String id, DigitalTwinBase instance) { + TwinProxy proxy = new TwinProxy(instance); + ConcurrentHashMap modelInstances = _modelInstances.get(modelName); + if(modelInstances == null) { + modelInstances = new ConcurrentHashMap<>(); + } + modelInstances.put(id, proxy); + InitContext initContext = new WorkbenchInitContext(this, instance, modelName, id); + instance.init(initContext); + SimulationScheduler scheduler = _simulationSchedulers.get(modelName); + if(scheduler != null) { + proxy.setProxyState(ProxyState.Active); + scheduler.addInstance(proxy); + } + modelInstances.put(id, proxy); + _modelInstances.put(modelName, modelInstances); + } + + public void deleteSimulationInstance(String modelName, String id) { + ConcurrentHashMap modelInstances = _modelInstances.get(modelName); + TwinProxy proxy = modelInstances.remove(id); + proxy.setProxyState(ProxyState.Removed); + _modelInstances.put(modelName, modelInstances); + } + + ProcessingResult run(String model, String id, String source, String serializedList) throws WorkbenchException { + try { + ConcurrentHashMap twinInstances = _modelInstances.get(model); + if(twinInstances == null) { + twinInstances = new ConcurrentHashMap<>(); + } + TwinProxy proxy = twinInstances.get(id); + DigitalTwinBase instance = null; + if(proxy == null) { + Class dtClazz = _digitalTwins.get(model); + if(dtClazz == null) { + throw new WorkbenchException(String.format("DigitalTwin model \"%s\" does not exist on this workbench.", model)); + } + instance = dtClazz.getConstructor().newInstance(); + InitContext initContext = new WorkbenchInitContext(this, instance, model, id); + instance.init(initContext); + proxy = new TwinProxy(instance); + SimulationScheduler scheduler = _simulationSchedulers.get(model); + if(scheduler != null) { + proxy.setProxyState(ProxyState.Active); + scheduler.addInstance(proxy); + } + } else { + instance = proxy.getInstance(); + } + MessageProcessor mp = _messageProcessors.get(model); + HashMap sharedData = _modelsSharedData.get(model); + if(sharedData == null) sharedData = new HashMap<>(); + _modelsSharedData.put(model, sharedData); + SimulationController simulationController = null; + SimulationScheduler scheduler = _simulationSchedulers.get(model); + if(scheduler != null) { + simulationController = new WorkbenchSimulationController(this, scheduler); + } + WorkbenchProcessingContext context = new WorkbenchProcessingContext(_workbench._twinExecutionEngine, sharedData, _globalSharedData, simulationController); + context.reset(model, id, source, instance); + ProcessingResult res = mp.processMessages(context, instance, new WorkbenchMessageListFactory(serializedList, _messageProcessorValueTypes.get(model))); + if(context.forceSave()) res = ProcessingResult.UpdateDigitalTwin; + switch(res) { + case UpdateDigitalTwin: + proxy.setInstance(instance); + twinInstances.put(id, proxy); + _modelInstances.put(model, twinInstances); + break; + case NoUpdate: + break; + default: + break; + } + return res; + } catch (Exception e) { + throw new WorkbenchException("Exception thrown while running message processor.", e); + } + } + + ProcessingResult run(String model, String id, String source, List messages) throws WorkbenchException { + try { + ConcurrentHashMap twinInstances = _modelInstances.get(model); + if(twinInstances == null) { + twinInstances = new ConcurrentHashMap<>(); + } + TwinProxy proxy = twinInstances.get(id); + DigitalTwinBase instance = null; + if(proxy == null) { + Class dtClazz = _digitalTwins.get(model); + if(dtClazz == null) return ProcessingResult.NoUpdate; + instance = dtClazz.getConstructor().newInstance(); + InitContext initContext = new WorkbenchInitContext(this, instance, model, id); + instance.init(initContext); + proxy = new TwinProxy(instance); + SimulationScheduler scheduler = _simulationSchedulers.get(model); + if(scheduler != null) { + proxy.setProxyState(ProxyState.Active); + scheduler.addInstance(proxy); + } + } else { + instance = proxy.getInstance(); + } + MessageProcessor mp = _messageProcessors.get(model); + HashMap sharedData = _modelsSharedData.get(model); + if(sharedData == null) sharedData = new HashMap<>(); + _modelsSharedData.put(model, sharedData); + WorkbenchSimulationController simulationController = null; + SimulationScheduler scheduler = _simulationSchedulers.get(model); + if(scheduler != null) { + simulationController = new WorkbenchSimulationController(this, scheduler); + } + WorkbenchProcessingContext context = new WorkbenchProcessingContext(_workbench._twinExecutionEngine, sharedData, _globalSharedData, simulationController); + context.reset(model, id, source, instance); + if(simulationController != null) { + simulationController.reset(model, id); + } + ProcessingResult res = mp.processMessages(context, instance, new WorkbenchMessageListFactory(messages, _messageProcessorValueTypes.get(model))); + if(context.forceSave()) res = ProcessingResult.UpdateDigitalTwin; + switch(res) { + case UpdateDigitalTwin: + proxy.setInstance(instance); + twinInstances.put(id, proxy); + _modelInstances.put(model, twinInstances); + break; + case NoUpdate: + break; + default: + break; + } + return res; + } catch (Exception e) { + throw new WorkbenchException(e.getMessage(), e); + } + } + + @Override + public void close() throws IOException { + if(_realTimeTimers != null && _realTimeTimers.size() > 0) { + for(Map.Entry entry : _realTimeTimers.entrySet()) { + WorkbenchTimerTask task = _realTimeTimers.remove(entry.getKey()); + task.cancel(); + } + _realTimeTimers = null; + } + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinProxy.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinProxy.java new file mode 100644 index 0000000..4811ab7 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/TwinProxy.java @@ -0,0 +1,52 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase; + +class TwinProxy { + private DigitalTwinBase _instance; + private ProxyState _state; + public TwinProxy(DigitalTwinBase instance) { + _instance = instance; + _state = ProxyState.Unspecified; + } + + void setProxyState(ProxyState state) { + _state = state; + } + + ProxyState getProxyState() { + return _state; + } + + DigitalTwinBase getInstance() { + return _instance; + } + + public void setInstance(DigitalTwinBase instance) { + _instance = instance; + } + + @Override + public String toString() { + return "TwinProxy{" + + "_instance=" + _instance + + ", _state=" + _state + + '}'; + } +} + diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/Workbench.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/Workbench.java new file mode 100644 index 0000000..0cc6a07 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/Workbench.java @@ -0,0 +1,769 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.*; + +import java.io.*; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; + +/** + * The Workbench is used to represent an environment where developers can test real-time and simulated digital twins. + *

        + * Quick start: + *

        + *

        + * Build a real-time digital twin model for testing real-time message processing with messages generated by a simulated + * digital twin. + *

        + *

        + * The real-time model will represent a car and the simulated digital twin will + * represent a pump increasing the real-time car's tire pressure. The real-time car will process messages from the + * simulated pump and send information back to the simulated pump when the tire is full. + *

        + * + *

        The quickstart will demonstrate the following:

        + *
          + *
        • Define a real-time car digital twin
        • + *
        • Define a tire pressure change message
        • + *
        • Define a real-time car message processor
        • + *
        • Define a simulated pump digital twin
        • + *
        • Define a simulated pump message processor
        • + *
        • Define a simulated pump simulation processor
        • + *
        + * + *

        + * Defining the real-time car model: + *

        + * + *

        + * Create a class that extends the {@link DigitalTwinBase} class and add an integer property for tire pressure. + * When constructed by the {@link Workbench} this will be our real-time car instance. + *

        + *
        + *     public class RealTimeCar extends DigitalTwinBase {
        + *         private int _tirePressure;
        + *         public RealTimeCar() { _tirePressure=0; }
        + *         public RealTimeCar(int startingTirePressure) {
        + *             _tirePressure = startingTirePressure;
        + *         }
        + *
        + *         public void incrementTirePressure(int increment) {
        + *             _tirePressure += increment;
        + *         }
        + *
        + *         public int getTirePressure() {
        + *             return _tirePressure;
        + *         }
        + *     }
        + * 
        + *

        + * Defining the tire pressure change message: + *

        + *

        + * Implement a message to send from the simulated pump, to the real-time model. The message will tell the real-time + * car to increase the tire pressure by some value. + *

        + * + *
        + *     public class TirePressureMessage {
        + *         final int _pressureChange;
        + *         public TirePressureMessage(int pressureChange) {
        + *             _pressureChange = pressureChange;
        + *         }
        + *
        + *         public int getPressureChange() {
        + *             return _pressureChange;
        + *         }
        + *     }
        + * 
        + * + *

        + * Defining the real-time car message processor: + *

        + * + *

        + * Create the real-time car {@link MessageProcessor}. The message processor will apply the tire pressure change from the tire + * pressure message to the real-time car digital twin instance. When the tire is full, the message processor will + * send a message back to the simulated pump. + *

        + *
        + *     public class RealTimeCarMessageProcessor extends MessageProcessor{@literal <}RealTimeCar, TirePressureMessage{@literal >} implements Serializable {
        + *         final int TIRE_PRESSURE_FULL = 100;
        + *         public ProcessingResult processMessages(ProcessingContext processingContext, RealTimeCar car, Iterable{@literal <}TirePressureMessage{@literal >} messages) throws Exception {
        + *             // apply the updates from the messages
        + *             for(TirePressureMessage message : messages) {
        + *                 car.incrementTirePressure(message.getPressureChange());
        + *             }
        + *             if(car.getTirePressure() {@literal >} TIRE_PRESSURE_FULL) {
        + *                 processingContext.sendToDataSource(new TirePressureMessage(car.getTirePressure()));
        + *             }
        + *             return ProcessingResult.UpdateDigitalTwin;
        + *         }
        + *     }
        + * 
        + * + *

        + * Defining the simulated pump model: + *

        + * + *

        + * Create a class that extends the {@link DigitalTwinBase} class and add a double property for tire pressure change. + * When constructed by the {@link Workbench} this will be our simulated pump instance. + *

        + *
        + *     public class SimulatedPump extends DigitalTwinBase {
        + *     private double _tirePressureChange;
        + *     private boolean _tirePressureReached = false;
        + *     public SimulatedPump() {}
        + *     public SimulatedPump(double pressureChange) {
        + *         _tirePressureChange = pressureChange;
        + *     }
        + *
        + *     public double getTirePressureChange() {
        + *         return _tirePressureChange;
        + *     }
        + *
        + *     public void setTirePressureReached() {
        + *         _tirePressureReached = true;
        + *     }
        + *
        + *     public boolean isTireFull() {
        + *         return _tirePressureReached;
        + *     }
        + * }
        + * 
        + * + *

        + * Defining the simulated pump message processor: + *

        + * + *

        + * The simulated pump should stop when the simulated pump message processor receives a message. The simulated pump message + * processor will update the state of the simulated pump indicating that the tire is full. + *

        + *
        + *     public class PumpMessageProcessor extends MessageProcessor{@literal <}SimulatedPump, TirePressureMessage{@literal >} implements Serializable {
        + *         public ProcessingResult processMessages(ProcessingContext processingContext, SimulatedPump pump, Iterable{@literal <}TirePressureMessage{@literal >} messages) throws Exception {
        + *             // apply the updates from the messages
        + *             pump.setTirePressureReached();
        + *             return ProcessingResult.UpdateDigitalTwin;
        + *         }
        + *     }
        + * 
        + * + *

        + * Defining the pump simulation processor: + *

        + * + *

        + * Define the simulated pump {@link SimulationProcessor}. This piece of code will be called at each simulation interval so + * long as the simulation has instances to run. This pump simulation processor will send a message to the + * real-time car with a tire pressure change derived from the state of the simulated pump. While the simulated pump has not been + * told to stop, it will continue sending tire pressure changes to the real-time car. + *

        + *
        + *     public class PumpSimulationProcessor extends SimulationProcessor{@literal <}SimulatedPump{@literal >} implements Serializable {
        + *         public ProcessingResult processModel(ProcessingContext processingContext, SimulatedPump simPump, Date date) {
        + *             SimulationController controller = processingContext.getSimulationController();
        + *             if(simPump.isTireFull()) {
        + *                 controller.deleteThisInstance();
        + *             } else {
        + *                 int change = (int) (100 * simPump.getTirePressureChange());
        + *                 controller.emitTelemetry("RealTimeCar", new TirePressureMessage(change));
        + *             }
        + *             return ProcessingResult.UpdateDigitalTwin;
        + *         }
        + *     }
        + * 
        + * + *

        + * Using the workbench: + *

        + * + *

        + * The real-time and simulation models are complete. The workbench can now load up the models and then run a simulation. + * When beginning testing, the "step loop" is used to track the state of the twins and the simulation. Instantiate the + * workbench and add the models. + *

        + * + *
        + *     Workbench workbench = new Workbench();
        + *     workbench.addRealTimeModel("RealTimeCar", new RealTimeCarMessageProcessor(), RealTimeCar.class, TirePressureMessage.class);
        + *     workbench.addSimulationModel("SimPump", new SimulatedPumpMessageProcessor(), new PumpSimulationProcessor(), SimulationPump.class, TirePressureMessage.class);
        + * 
        + * + *

        + * The workbench is loaded up with the models. Add a single simulated pump instance. + * Note that no real-time car digital twin is created and added to the workbench. The first message from the + * simulated pump digital twin will cause the workbench to create a new real-time instance. + *

        + *
        + *     workbench.addInstance("SimPump", "23", new SimulationPump(0.29d));
        + * 
        + * + *

        Initialize the simulation and then step through the simulation intervals. Start the simulation now and end the + * simulation in 60 seconds.

        + * + *
        + *     SimulationStep step = workbench.initializeSimulation(System.currentTimeMillis(), System.currentTimeMillis()+60000, 1000);
        + * 
        + * + *

        + * At each interval, view the state of the real-time car to ensure the tire pressure is changing as expected. + *

        + * + *
        + *     while(step.getStatus() == SimulationStatus.Running) {
        + *         step = workbench.step();
        + *         HashMap{@literal <}String, DigitalTwinBase{@literal >} realTimeCars = workbench.getInstances("RealTimeCar");
        + *         RealTimeCar rtCar = (RealTimeCar) realTimeCars.get("23");
        + *         System.out.println("rtCar: " + rtCar.getTirePressure());
        + *     }
        + * 
        + * + *

        + * Summary: + *

        + *

        + * The simulated pump at each simulation step emits telemetry to the real-time car digital twin. With each tire pressure + * change message, the real-time car twin accrues state about the pressure of the tire. When the real-time car twins tire + * is full, it sends a message back to the simulated pump. When the simulated pump receives a message from the real-time car, + * it updates some internal state indicating to stop pumping. During the next simulation interval, the simulated pump + * deletes itself to stop pumping. This completes the simulation as there are no more remaining simulated pumps. + *

        + * + */ +public class Workbench implements AutoCloseable { + final ConcurrentHashMap> LOGGED_MESSAGES = new ConcurrentHashMap<>(); + final ConcurrentHashMap>> ALERT_MESSAGES = new ConcurrentHashMap<>(); + final ConcurrentHashMap>> SOURCE_MESSAGES = new ConcurrentHashMap<>(); + + TwinExecutionEngine _twinExecutionEngine; + private long _curTime, _endTime, _interval; + private long _now, _next; + private SimulationStep _result = null; + private boolean _simulationStarted = false; + private int _numWorkers = Runtime.getRuntime().availableProcessors(); + + + /** + * Instantiate the workbench. + */ + public Workbench() { + _twinExecutionEngine = new TwinExecutionEngine(this); + } + + /** + * Instantiate the workbench. + * @param numSimulationWorkers the number of simulation workers to use. Default is {@link Runtime#availableProcessors()}. + */ + public Workbench(int numSimulationWorkers) { + _twinExecutionEngine = new TwinExecutionEngine(this); + if(_numWorkers <= 0) throw new IllegalArgumentException("numSimulationWorkers must be greater-than 0."); + _numWorkers = numSimulationWorkers; + } + + + /** + * Adds a real-time digital twin model to the workbench. + * + * @param modelName the name of the model. + * @param digitalTwinMessageProcessor the model's {@link MessageProcessor} implementation. Must be marked as {@link Serializable}. + * @param dtType the model's {@link DigitalTwinBase} implementation. + * @param messageClass the model's message type. + * @param the type of the digital twin. + * @param the type of the message. + * @throws WorkbenchException if any of the parameters are null or the model does not pass validation (the message + * processor must be serializable, and the digital twin implementation must have a parameterless constructor). + */ + public void addRealTimeModel(String modelName, MessageProcessor digitalTwinMessageProcessor, Class dtType, Class messageClass) throws WorkbenchException { + if(modelName == null || modelName.isBlank() || modelName.isEmpty() || digitalTwinMessageProcessor == null || dtType == null || messageClass == null) { + String errorMessage = String.format("modelName null: %b messageProcessor null: %b dtType null: %b messageType null: %b",modelName == null, digitalTwinMessageProcessor == null, dtType == null, messageClass == null); + throw new WorkbenchException(new IllegalArgumentException("All parameters required. Found null parameter.\n" + errorMessage)); + } + + validate(digitalTwinMessageProcessor, dtType); + _twinExecutionEngine.addDigitalTwin(modelName, digitalTwinMessageProcessor, dtType, messageClass); + } + + /** + * Adds a simulation digital twin model to the workbench. + * + * @param modelName the name of the model. + * @param digitalTwinMessageProcessor the model's {@link MessageProcessor} implementation. Must be marked as {@link Serializable}. + * @param simulationProcessor the model's {@link SimulationProcessor} implementation. Must be marked as {@link Serializable}. + * @param dtType the model's {@link DigitalTwinBase} implementation. + * @param messageClass the model's message type. + * @param the type of the digital twin. + * @param the type of the message. + * @throws WorkbenchException if any of the parameters are null or the model does not pass validation (the message + * processor must be serializable, and the digital twin implementation must have a parameterless constructor). + */ + public void addSimulationModel(String modelName, MessageProcessor digitalTwinMessageProcessor, SimulationProcessor simulationProcessor, Class dtType, Class messageClass) throws WorkbenchException { + if(modelName == null || modelName.isBlank() || modelName.isEmpty() || digitalTwinMessageProcessor == null || simulationProcessor == null || dtType == null || messageClass == null) { + String errorMessage = String.format("modelName null: %b messageProcessor null: %b simulationProcessor null: %b dtType null: %b messageType null: %b",modelName == null, digitalTwinMessageProcessor == null, simulationProcessor == null, dtType == null, messageClass == null); + throw new WorkbenchException(new IllegalArgumentException("All parameters required. Found null parameter.\n" + errorMessage)); + } + + validate(digitalTwinMessageProcessor, dtType); + _twinExecutionEngine.addDigitalTwin(modelName, digitalTwinMessageProcessor, simulationProcessor, dtType, messageClass, _numWorkers); + } + + /** + * Adds a digital twin instance to the workbench. + * Instances cannot be added to the workbench after {@link Workbench#runSimulation(long, long, double, long)} or + * {@link Workbench#initializeSimulation(long, long, long)} has been called. + * + * @param modelName the instances model. + * @param id the instance identifier. + * @param instance the real-time or simulation instance. + * @throws WorkbenchException If the model does not exist or if a simulation is already running. + */ + public void addInstance(String modelName, String id, DigitalTwinBase instance) throws WorkbenchException { + if(_simulationStarted) throw new WorkbenchException("Cannot add new instance while simulation is active."); + if(!_twinExecutionEngine.hasModel(modelName)) throw new WorkbenchException("The model does not exist on this workbench."); + _twinExecutionEngine.createInstance(modelName, id, instance); + } + + /** + * Adds an alert provider configuration to the specified model on this workbench. + * Alert provider configurations cannot be added to the workbench after {@link Workbench#runSimulation(long, long, double, long)} or + * {@link Workbench#initializeSimulation(long, long, long)} has been called. + * + * @param modelName the instances model. + * @param configuration the alert provider configuration. + * @throws WorkbenchException If the model does not exist or if a simulation is already running. + */ + public void addAlertProvider(String modelName, AlertProviderConfiguration configuration) throws WorkbenchException { + if(_simulationStarted) throw new WorkbenchException("Cannot add new alert provider while simulation is active."); + if(!_twinExecutionEngine.hasModel(modelName)) throw new WorkbenchException("The model does not exist on this workbench."); + _twinExecutionEngine.addAlertProvider(modelName, configuration); + } + + /** + * Runs a simulation from the given startTime until the given endTime OR there is no more work to do. + * A simulation has reached the end time when the time to run the next interval is greater than the end time or + * there are no more simulated twins to run. + * + * @param startTime the start time of the simulation. + * @param endTime the end time of the simulation. + * @param speedup the speedup of the interval (in real-time). + * @param interval the interval between simulation steps. + * @return a {@link SimulationStep} that details the final runtime and the {@link SimulationStatus}. + * @throws WorkbenchException if an exception is thrown by the simulated model or real-time model. + */ + public SimulationStep runSimulation(long startTime, long endTime, double speedup, long interval) throws WorkbenchException { + _twinExecutionEngine.setSimulationStatus(true); + _simulationStarted = true; + SimulationStep ret, result = null; + SimulationStepArgs args; + long now, curTime, start, end, deltaTm, delta, wait, numItv; + args = new SimulationStepArgs(startTime, interval, WorkbenchSimulationFlags.Start); + _twinExecutionEngine.runSimulationStep(args); + SimulationStatus status = SimulationStatus.Running; + now = curTime = startTime; + while(status == SimulationStatus.Running && + curTime < endTime) { + args = new SimulationStepArgs(curTime, interval, WorkbenchSimulationFlags.Run); + now = curTime; + start = System.currentTimeMillis(); + result = _twinExecutionEngine.runSimulationStep(args); + end = System.currentTimeMillis(); + delta = result.getTime() - curTime; + numItv = delta/interval; + numItv = numItv > 0 ? delta%numItv != 0 ? numItv+1 : numItv : numItv; + deltaTm = end-start; + wait = deltaTm >= interval ? 0L : (long)((interval-deltaTm)/speedup); + status = result.getStatus(); + curTime = curTime+(numItv*interval); + try { + Thread.sleep(wait); + } catch (Exception e) { + throw new WorkbenchException(e); + } + } + if(curTime >= endTime) { + ret = new SimulationStep(SimulationStatus.EndTimeReached, curTime); + _twinExecutionEngine.setSimulationStatus(false); + _simulationStarted = false; + } else { + ret = new SimulationStep(result.getStatus(), now); + _twinExecutionEngine.setSimulationStatus(false); + _simulationStarted = false; + } + return ret; + } + + /** + * Initializes the simulation so that each interval can be run separately by calling the {@link Workbench#step()} + * function. + * + * @param startTime the start time of the simulation. + * @param endTime the end time of the simulation. + * @param interval the interval between simulation steps. + * @return a {@link SimulationStep} that details the startTime and the {@link SimulationStatus} -- which will always be {@link SimulationStatus#Running}. + */ + public SimulationStep initializeSimulation(long startTime, long endTime, long interval) { + _simulationStarted = true; + _twinExecutionEngine.setSimulationStatus(true); + _curTime = startTime; + _endTime = endTime; + _interval = interval; + _result = new SimulationStep(SimulationStatus.Running, startTime); + _twinExecutionEngine.setSimulationStatus(true); + return _result; + } + + /** + * Run the next simulation interval. + * + * @return a {@link SimulationStep} that shows the time interval that was run and the corresponding {@link SimulationStatus} + * @throws WorkbenchException if an exception is thrown by the simulated model or real-time model. + */ + public SimulationStep step() throws WorkbenchException { + long delta, numItv; + SimulationStatus status = _result.getStatus(); + if(status == SimulationStatus.Running ) { + if(_curTime >= _endTime) { + _simulationStarted = false; + _twinExecutionEngine.setSimulationStatus(false); + return new SimulationStep(SimulationStatus.EndTimeReached, _curTime); + } + SimulationStepArgs args = new SimulationStepArgs(_curTime, _interval, WorkbenchSimulationFlags.Run); + _now = _curTime; + _result = _twinExecutionEngine.runSimulationStep(args); + delta = _result.getTime() - _curTime; + numItv = delta/_interval; + numItv = numItv > 0 ? delta%numItv != 0 ? numItv+1 : numItv : numItv+1; + _curTime = _curTime+(numItv*_interval); + _next = _curTime; + return new SimulationStep(_result.getStatus(), _now); + } else { + _simulationStarted = false; + _twinExecutionEngine.setSimulationStatus(false); + throw new WorkbenchException("Simulation is inactive. Simulation status: " + _result.getStatus()); + } + } + + /** + * Retrieves the current time interval of the simulation. + * @return a {@link Date} representation for the current interval time for the simulation. + * @throws WorkbenchException if the simulation is not started or initialized. + */ + public Date getTime() throws WorkbenchException { + if(_simulationStarted) { + return new Date(_now); + } + throw new WorkbenchException("Simulation is not started"); + + } + + /** + * Retrieves the next interval time of the simulation. + * @return a {@link Date} representation for the next interval time for the simulation. + * @throws WorkbenchException if the simulation is not started or initialized. + */ + public Date peek() throws WorkbenchException { + if(_simulationStarted) { + return new Date(_next); + } + throw new WorkbenchException("Simulation is not started"); + } + + /** + * Retrieves DigitalTwin instances for a given model. + * + * @param modelName the digital twin model name + * @return the instances associated with the parameter model + * @throws WorkbenchException if an exception occurs while retrieving digital twin instances for the parameter modelName + */ + public HashMap getInstances(String modelName) throws WorkbenchException { + if(_twinExecutionEngine.getTwinInstances(modelName) == null) + throw new WorkbenchException(String.format("No instances for model %s.", modelName)); + return _twinExecutionEngine.getTwinInstances(modelName); + } + + /** + * Retrieves messages logged by digital twin instances for a specified mdoel. If the provided timestamp is 0, all messages will be returned. + * Timestamps greater than 0 will return a sublist of logged messages where the first message in the returned list + * will be greater than the provided timestamp. If no messages exist after the timestamp, the returned list will be + * empty. + * + * @param model the model name for the logged messages. + * @param timestamp the timestamp used to filter the retrieved list. + * @return the list of messages defined by the timestamp + */ + public List getLoggedMessages(String model, long timestamp) { + if(timestamp == 0L) { + return Arrays.asList(LOGGED_MESSAGES.getOrDefault(model, new ConcurrentLinkedQueue<>()).toArray(new LogMessage[0])); + } else { + ConcurrentLinkedQueue modelMessages = LOGGED_MESSAGES.getOrDefault(model, new ConcurrentLinkedQueue<>()); + int endIdx = modelMessages.size()-1; + int bgnIdx = -1; + for(LogMessage msg : modelMessages) { + if(msg.getTimestamp() <= timestamp) { + bgnIdx++; + } else { + break; + } + } + + if(endIdx == bgnIdx) { + return Collections.emptyList(); + } else if(bgnIdx == -1){ + return Arrays.asList(LOGGED_MESSAGES.getOrDefault(model, new ConcurrentLinkedQueue<>()).toArray(new LogMessage[0])); + } + + return Arrays.asList(modelMessages.toArray(new LogMessage[0])).subList(bgnIdx, endIdx); + } + } + + /** + * Retrieves alert messages from digital twin instances. + * + * @param model the model to retrieve alert messages from. + * @param alertProvider the alert provider that generated the alerts. + * @return the list of alert messages generated by digital twin instances. + * @throws WorkbenchException if an exception occurs while retrieving logged messages. + */ + public List getAlertMessages(String model, String alertProvider) throws WorkbenchException { + if(!_twinExecutionEngine.hasModel(model)) throw new WorkbenchException(String.format("No registered model with name %s found.", model)); + if(!_twinExecutionEngine.hasAlertProviderConfiguration(model, alertProvider)) throw new WorkbenchException(String.format("No alert provider configuration, registered for model %s, for %s found.", model, alertProvider)); + + ConcurrentHashMap> perModelMessages = ALERT_MESSAGES.getOrDefault(model, new ConcurrentHashMap<>()); + return Arrays.asList(perModelMessages.get(alertProvider).toArray(new AlertMessage[0])); + } + + /** + * Retrieve the {@link SharedData} for a model. + * @param model the model name. + * @return the {@link SharedData} for a model. + * @throws WorkbenchException if an exception occurs while creating the working shared data. + */ + public SharedData getSharedModelData(String model) throws WorkbenchException { + if(_twinExecutionEngine.hasModel(model)) { + return new WorkbenchSharedData(_twinExecutionEngine.getModelData(model)); + } else { + throw new WorkbenchException("Workbench does not contain model " + model); + } + } + + /** + * Retrieve the global {@link SharedData}. + * @return the global {@link SharedData} of this workbench. + * @throws WorkbenchException if an exception occurs while creating the working shared data. + */ + public SharedData getSharedGlobalData() throws WorkbenchException { + return new WorkbenchSharedData(_twinExecutionEngine.getGlobalSharedData()); + } + + /** + * Generates a ModelSchema for the defined model + * + * @param modelName the digital twin model's name to generate a schema. + * @return a JSON string of the model's schema + * @throws WorkbenchException if an exception occurs while generating a model schema. + */ + public String generateModelSchema(String modelName) throws WorkbenchException { + if(_twinExecutionEngine.runningModels().contains(modelName)) { + return _twinExecutionEngine.generateModelSchema(modelName); + } + throw new WorkbenchException("Model is not loaded; cannot generate model schema."); + } + + /** + * Generates a ModelSchema for the parameter modelName and writes the schema to a file on the file system. If the + * parameter outputDirectory is null the file will be written to the working directory of the JVM. + * + * @param modelName the name of the digital twin model + * @param outputDirectory the directory to write the file to, or null to write the file to the current working directory. + * @return the full file path of the model.json schema file + * @throws WorkbenchException if an exception occurs while generating a model schema. + */ + public String generateModelSchema(String modelName, String outputDirectory) throws WorkbenchException { + if(modelName == null || modelName.isEmpty()) { + throw new WorkbenchException("Required parameters: modelName.", new IllegalArgumentException()); + } + + outputDirectory = outputDirectory == null ? System.getProperty("user.dir") : outputDirectory; + + if(_twinExecutionEngine.runningModels().contains(modelName)) { + try { + String filePath = String.format("%s\\model.json", outputDirectory); + FileWriter fileWriter = new FileWriter(filePath); + fileWriter.write(_twinExecutionEngine.generateModelSchema(modelName)); + fileWriter.flush(); + fileWriter.close(); + return filePath; + } catch (IOException e) { + throw new WorkbenchException("Could not write file to file system.", e); + } + + } + throw new WorkbenchException("Model is not loaded; cannot generate model schema."); + } + + /** + * Send a list of messages to a real-time or simulation model. + * @param modelName The model name. + * @param id the instance id. + * @param messages the messages to send. + * @return {@link SendingResult#Handled} unless an exception is thrown. + * @throws WorkbenchException if model name, id, or messages are null. Also thrown if the model's {@link MessageProcessor#processMessages(ProcessingContext, DigitalTwinBase, Iterable)} + * throws an exception. + */ + public SendingResult send(String modelName, String id, List messages) throws WorkbenchException { + if(modelName == null || id == null || messages == null) { + throw new WorkbenchException("ModelName, Id, and messages are required."); + } + if(_twinExecutionEngine.hasModel(modelName) && !_simulationStarted) { + _twinExecutionEngine.run(modelName, id, null, messages); + } else { + String msg = _twinExecutionEngine.hasModel(modelName) ? String.format("Cannot send message to %s. Simulation is active.", modelName) : String.format("Cannot send message to %s. Model does not exist.", modelName); + throw new WorkbenchException(msg); + } + return SendingResult.Handled; + } + +// /** +// * Sends a single JSON serialized UTF-8 string message to a digital twin. +// * +// * @param modelName the name of the digital twin model +// * @param id the ID of the digital twin model +// * @param jsonSerializedMessage the serialized JSON UTF-8 string message +// * @return the sending result +// * @throws WorkbenchException if an exception is thrown by the twin or an error occurs while processing. +// */ +// public SendingResult send(String modelName, String id, String jsonSerializedMessage) throws WorkbenchException { +// List msgs = new ArrayList<>(); +// msgs.add(jsonSerializedMessage); +// return send(modelName, id, msgs); +// } +// +// /** +// * +// * @param modelName the name of the digital twin model +// * @param id the ID of the digital twin model +// * @param jsonSerializedMessages a serialized list of JSON UTF-8 string messages +// * @return the sending result +// * @throws WorkbenchException if an exception occurs while sending a message +// */ +// public SendingResult send(String modelName, String id, List jsonSerializedMessages) throws WorkbenchException { +// return sendMessage(modelName, id, jsonSerializedMessages) != null ? SendingResult.Handled : SendingResult.NotHandled; +// } + + ProcessingResult sendMessage(String model, String id, List jsonMessages) throws WorkbenchException { + if(_simulationStarted) throw new WorkbenchException("Cannot send message; simulation is active."); + StringBuilder serializedListBuilder = new StringBuilder(String.format("[%s", jsonMessages.remove(0))); + for(String msg : jsonMessages) { + serializedListBuilder.append(","); + serializedListBuilder.append(msg); + + } + serializedListBuilder.append("]"); + return _twinExecutionEngine.run(model, id, null, serializedListBuilder.toString()); + } + + + static void validate(MessageProcessor digitalTwinMessageProcessor, Class dtType) throws WorkbenchException { + WorkbenchException mee = null; + + ByteArrayOutputStream baos = null; + ObjectOutputStream oos = null; + + ByteArrayInputStream bais = null; + ObjectInputStream ois = null; + boolean serialized = false; + try { + // serialize MessageProcessor + baos = new ByteArrayOutputStream(); + oos = new ObjectOutputStream(baos); + oos.writeObject(digitalTwinMessageProcessor); + + byte[] serializedMP = baos.toByteArray(); + serialized = true; + + bais = new ByteArrayInputStream(serializedMP); + ois = new ObjectInputStream(bais); + MessageProcessor incoming = (MessageProcessor) ois.readObject(); + } catch (Exception all) { + if(serialized) + throw new WorkbenchException("Could not deserialize MessageProcessor instance.", all); + else + throw new WorkbenchException("Could not serialize MessageProcessor instance", all); + } finally { + try { + if(baos != null) { + baos.flush(); + baos.close(); + } + if(oos != null) { + oos.flush(); + oos.close(); + } + + if(bais != null) { + bais.close(); + } + if(ois != null) { + ois.close(); + } + } catch(Exception any) {} // best effort to cleanup + } + + try { + Class mpType = digitalTwinMessageProcessor.getClass(); + // instantiate TwinInstance + MessageProcessor instance = mpType.getConstructor().newInstance(); + } catch (Exception e) { + throw new WorkbenchException("Could not instantiate MessageProcessor instance. Default constructor required.", e); + } + + try { + // instantiate TwinInstance + DigitalTwinBase instance = dtType.getConstructor().newInstance(); + } catch (Exception e) { + throw new WorkbenchException("Could not instantiate DigitalTwin instance. Default constructor required.", e); + } + } + + /** + * Add a key/value pair to {@link SharedData} for a model. + * @param modelName the model name. + * @param key the key. + * @param value the value. + */ + public void addSharedModelData(String modelName, String key, byte[] value) { + _twinExecutionEngine.getModelData(modelName).put(key, value); + } + + /** + * Add a key/value pair to the global {@link SharedData}. + * @param key the key. + * @param value the value. + */ + public void addGlobalModelData(String key, byte[] value) { + _twinExecutionEngine.getGlobalSharedData().put(key, value); + } + + @Override + public void close() throws Exception { + _twinExecutionEngine.close(); + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.java new file mode 100644 index 0000000..b983f6c --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchException.java @@ -0,0 +1,66 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +/** + * A Workbench exception indicates that a real-time or simulated twin caused an exception. + */ +public class WorkbenchException extends Exception { + + /** + * The string message for this workbench exception. + */ + String _message; + /** + * The inner cause of the workbench exception. + */ + Exception _innerException; + + /** + * Instantiates a WorkbenchException with the parameter message and inner exception + * + * @param message the message of this exception + * @param e the inner exception + */ + public WorkbenchException(String message, Exception e) { + _message = message; + _innerException = e; + } + + /** + * Instantiates a WorkbenchException with the parameter inner exception + * + * @param e the inner exception + */ + public WorkbenchException(Exception e) { + _innerException = e; + _message = e.getMessage(); + } + + /** + * Instantiates a WorkbenchException with the parameter message + * + * @param message the message of this exception + */ + public WorkbenchException(String message) { + _message = message; + } + + @Override + public String getMessage() { + return _message; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchInitContext.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchInitContext.java new file mode 100644 index 0000000..8cc55b0 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchInitContext.java @@ -0,0 +1,59 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.*; + +import java.time.Duration; + +class WorkbenchInitContext extends InitContext { + TwinExecutionEngine _twinExecutionEngine; + DigitalTwinBase _instance; + String _model; + String _id; + + WorkbenchInitContext(TwinExecutionEngine twinExecutionEngine, DigitalTwinBase instance, String model, String id) { + _twinExecutionEngine = twinExecutionEngine; + _instance = instance; + _model = model; + _id = id; + } + + @Override + public TimerActionResult startTimer(String timerName, Duration duration, TimerType timerType, TimerHandler timerHandler) { + return WorkbenchTimerService.startTimer(_twinExecutionEngine, (T)_instance, _model, _id, timerName, duration, timerType, timerHandler); + } + + @Override + public SharedData getSharedModelData() { + return new WorkbenchSharedData(_twinExecutionEngine.getModelData(_model)); + } + + @Override + public SharedData getSharedGlobalData() { + return new WorkbenchSharedData(_twinExecutionEngine.getGlobalSharedData()); + } + + @Override + public String getId() { + return _id; + } + + @Override + public String getModel() { + return _model; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchInitSimulationContext.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchInitSimulationContext.java new file mode 100644 index 0000000..3128ad8 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchInitSimulationContext.java @@ -0,0 +1,39 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.InitSimulationContext; +import com.scaleoutsoftware.digitaltwin.core.SharedData; + +class WorkbenchInitSimulationContext implements InitSimulationContext { + SharedData _globalData; + SharedData _modelData; + + WorkbenchInitSimulationContext(SharedData globalData, SharedData modelData) { + _globalData = globalData; + _modelData = modelData; + } + + @Override + public SharedData getSharedModelData() { + return _modelData; + } + + @Override + public SharedData getSharedGlobalData() { + return _globalData; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchMessageListFactory.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchMessageListFactory.java new file mode 100644 index 0000000..43b0a06 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchMessageListFactory.java @@ -0,0 +1,67 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.google.gson.Gson; +import com.scaleoutsoftware.digitaltwin.core.MessageFactory; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.List; + +class WorkbenchMessageListFactory implements MessageFactory { + private String _serializedJsonList; + private List _messages; + private Class _type; + + WorkbenchMessageListFactory(String serializedJson, Class type) { + _serializedJsonList = serializedJson; + _messages = null; + _type = type; + } + + WorkbenchMessageListFactory(List messages, Class type) { + _serializedJsonList = null; + _messages = messages; + _type = type; + } + + @Override + public Iterable getIncomingMessages() { + if (_messages != null) { + return (Iterable) _messages; + } else { + Gson gson = new Gson(); + return gson.fromJson(_serializedJsonList, getTypedList(_type)); + } + } + + private Type getTypedList(final Class paramClass) { + return new ParameterizedType() { + public Type[] getActualTypeArguments() { + return new Type[]{paramClass}; + } + + public Type getRawType() { + return List.class; + } + + public Type getOwnerType() { + return null; + } + }; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchProcessingContext.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchProcessingContext.java new file mode 100644 index 0000000..2846a09 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchProcessingContext.java @@ -0,0 +1,237 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.google.gson.Gson; + +import com.scaleoutsoftware.digitaltwin.core.*; + +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.*; +import java.util.logging.Level; + +class WorkbenchProcessingContext extends ProcessingContext { + final TwinExecutionEngine _twinExecutionEngine; + String _model; + String _id; + String _source; + DigitalTwinBase _twinInstance; + SimulationController _controller; + HashMap _modelData; + HashMap _globalData; + boolean _forceSave; + + WorkbenchProcessingContext(TwinExecutionEngine twinExecutionEngine, HashMap modelSharedData, HashMap globalSharedData, SimulationController simulationController) { + _twinExecutionEngine = twinExecutionEngine; + _controller = simulationController; + _modelData = modelSharedData; + _globalData = globalSharedData; + } + + WorkbenchProcessingContext(TwinExecutionEngine twinExecutionEngine, SimulationController controller) { + _twinExecutionEngine = twinExecutionEngine; + _controller = controller; + } + + void reset(String model, String id, String source, DigitalTwinBase instance) { + _model = model; + _id = id; + _twinInstance = instance; + _forceSave = false; + _source = source; + _modelData = _twinExecutionEngine.getModelData(model); + _globalData = _twinExecutionEngine.getGlobalSharedData(); + } + + void reset(String model, String id, String source) { + _model = model; + _id = id; + _forceSave = false; + _source = source; + _modelData = _twinExecutionEngine.getModelData(model); + _globalData = _twinExecutionEngine.getGlobalSharedData(); + } + + void resetInstance(DigitalTwinBase instance) { + _twinInstance = instance; + } + + boolean forceSave() { + return _forceSave; + } + + @Override + public SendingResult sendToDataSource(byte[] bytes) { + try { + return _twinExecutionEngine.sendToSource(_source, _model, _id, new String(bytes, StandardCharsets.UTF_8)); + } catch (WorkbenchException e) { + return SendingResult.NotHandled; + } + } + + @Override + public SendingResult sendToDataSource(Object jsonSerializableMessage) { + try { + List jsonSerializableMessages = new LinkedList<>(); + jsonSerializableMessages.add(jsonSerializableMessage); + return _twinExecutionEngine.sendToSource(_source, _model, _id, jsonSerializableMessages); + } catch (WorkbenchException e) { + return SendingResult.NotHandled; + } + } + + @Override + public SendingResult sendToDataSource(List list) { + try { + return _twinExecutionEngine.sendToSource(_source, _model, _id, list); + } catch (WorkbenchException e) { + return SendingResult.NotHandled; + } + } + + @Override + public SendingResult sendToDigitalTwin(String model, String id, byte[] bytes) { + List msgs = new LinkedList<>(); + msgs.add(bytes); + return sendToDigitalTwin(model, id, msgs); + } + + @Override + public SendingResult sendToDigitalTwin(String model, String id, Object jsonSerializableMessage) { + try { + if(_twinExecutionEngine.getTwinInstance(model, id) != null) { + List jsonSerializableMessages; + if(jsonSerializableMessage instanceof List) { + jsonSerializableMessages = (List)jsonSerializableMessage; + } else { + jsonSerializableMessages = new LinkedList<>(); + jsonSerializableMessages.add(jsonSerializableMessage); + } + + return _twinExecutionEngine.run(model, id, null, jsonSerializableMessages) != null ? SendingResult.Handled : SendingResult.NotHandled; + } else { + return SendingResult.NotHandled; + } + } catch (WorkbenchException e) { + return SendingResult.NotHandled; + } + } + + @Override + public SendingResult sendToDigitalTwin(String model, String id, String msg) { + return sendToDigitalTwin(model, id, msg.getBytes(StandardCharsets.UTF_8)); + } + + @Override + public SendingResult sendToDigitalTwin(String model, String id, List list) { + if( (model == null || model.isEmpty()) || + (id == null || id.isEmpty()) || + (list == null || list.isEmpty())) { + return SendingResult.NotHandled; + } + Gson gson = new Gson(); + List msgs = new LinkedList<>(); + for(byte[] serialMsg : list) { + msgs.add(new String(serialMsg, StandardCharsets.UTF_8)); + } + String json = gson.toJson(msgs); + try { + if(_twinExecutionEngine.getTwinInstance(model, id) != null) { + return _twinExecutionEngine.run(model, id, null, json) != null ? SendingResult.Handled : SendingResult.NotHandled; + } else { + return SendingResult.NotHandled; + } + + } catch (WorkbenchException e) { + return SendingResult.NotHandled; + } + } + + @Override + public SendingResult sendAlert(String alertProviderName, AlertMessage alertMessage) { + if(alertProviderName.isBlank() || alertProviderName.isEmpty() || alertMessage == null) return SendingResult.NotHandled; + else if (!_twinExecutionEngine.hasAlertProviderConfiguration(_model, alertProviderName)) return SendingResult.NotHandled; + else { + if(_twinExecutionEngine.hasAlertProviderConfiguration(_model, alertProviderName)) { + _twinExecutionEngine.recordAlertMessage(_model, alertProviderName, alertMessage); + } + return SendingResult.Handled; + } + } + + @Override + public PersistenceProvider getPersistenceProvider() { + return null; + } + + @Override + public String getDataSourceId() { + return _id; + } + + @Override + public String getDigitalTwinModel() { + return _model; + } + + @Override + public void logMessage(Level level, String msg) { + _twinExecutionEngine.logMessage(_model, new LogMessage(level, msg)); + } + + @Override + public TimerActionResult startTimer(String timerName, Duration interval, TimerType timerType, TimerHandler timerHandler) { + TimerActionResult ret = WorkbenchTimerService.startTimer(_twinExecutionEngine, (T)_twinInstance, _model, _id, timerName, interval, timerType, timerHandler); + if(ret != TimerActionResult.Success) { + _forceSave = false; + } else { + _forceSave = true; + } + return ret; + } + + @Override + public TimerActionResult stopTimer(String timerName) { + TimerActionResult ret = WorkbenchTimerService.stopTimer(_twinExecutionEngine, _twinInstance, _model, _id, timerName); + if(ret != TimerActionResult.Success) { + _forceSave = false; + } else { + _forceSave = true; + } + return ret; + } + + @Override + public Date getCurrentTime() { + return _twinExecutionEngine.getTime(_model); + } + + @Override + public SimulationController getSimulationController() { + return _controller; + } + + @Override + public SharedData getSharedModelData() { + return new WorkbenchSharedData(_modelData); + } + + @Override + public SharedData getSharedGlobalData() { + return new WorkbenchSharedData(_globalData); + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSharedData.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSharedData.java new file mode 100644 index 0000000..0712e9a --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSharedData.java @@ -0,0 +1,112 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus; +import com.scaleoutsoftware.digitaltwin.core.CacheResult; +import com.scaleoutsoftware.digitaltwin.core.SharedData; + +import java.util.HashMap; + +class WorkbenchSharedData implements SharedData { + private final HashMap data; + + public WorkbenchSharedData(HashMap shared) { + data = shared; + } + @Override + public CacheResult get(String s) { + return new CacheResult() { + @Override + public String getKey() { + return s; + } + + @Override + public byte[] getValue() { + return data.getOrDefault(s, null); + } + + @Override + public CacheOperationStatus getStatus() { + return data.containsKey(s) ? CacheOperationStatus.ObjectRetrieved : CacheOperationStatus.ObjectDoesNotExist; + } + }; + } + + @Override + public CacheResult put(String s, byte[] bytes) { + data.put(s, bytes); + return new CacheResult() { + @Override + public String getKey() { + return s; + } + + @Override + public byte[] getValue() { + return bytes; + } + + @Override + public CacheOperationStatus getStatus() { + return CacheOperationStatus.ObjectPut; + } + }; + } + + @Override + public CacheResult remove(String s) { + byte[] v = data.remove(s); + return new CacheResult() { + @Override + public String getKey() { + return s; + } + + @Override + public byte[] getValue() { + return v; + } + + @Override + public CacheOperationStatus getStatus() { + return v == null ? CacheOperationStatus.ObjectDoesNotExist : CacheOperationStatus.ObjectRemoved; + } + }; + } + + @Override + public CacheResult clear() { + data.clear(); + return new CacheResult() { + @Override + public String getKey() { + return null; + } + + @Override + public byte[] getValue() { + return null; + } + + @Override + public CacheOperationStatus getStatus() { + return CacheOperationStatus.CacheCleared; + } + }; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationController.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationController.java new file mode 100644 index 0000000..611d7af --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationController.java @@ -0,0 +1,182 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.*; + +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +class WorkbenchSimulationController implements SimulationController { + TwinExecutionEngine _engine; + SimulationScheduler _scheduler; + private long _requestedDelay; + private boolean _delayRequested; + private boolean _deleted; + private boolean _enqueue; + private String _modelName; + private String _id; + private SimulationStatus _simulationStatus = SimulationStatus.Running; + + public WorkbenchSimulationController(TwinExecutionEngine engine, SimulationScheduler scheduler) { + _engine = engine; + _scheduler = scheduler; + } + + @Override + public Duration getSimulationTimeIncrement() { + return null; + } + + @Override + public Date getSimulationStartTime() { + return _scheduler.getSimulationStartTime(); + } + + @Override + public SendingResult delay(Duration duration) { + _requestedDelay = duration.toMillis(); + _delayRequested = true; + return SendingResult.Handled; + } + + @Override + public SendingResult delayIndefinitely() { + _requestedDelay = 0x0000e677d21fdbffL; + _delayRequested = true; + return SendingResult.Handled; + } + + @Override + public SendingResult emitTelemetry(String modelName, byte[] bytes) { + try { + _engine.run(modelName, _id, _modelName, String.format("[%s]", new String(bytes, StandardCharsets.UTF_8))); + return SendingResult.Handled; + } catch (WorkbenchException e) { + e.printStackTrace(); + return SendingResult.NotHandled; + } + } + + @Override + public SendingResult emitTelemetry(String modelName, Object jsonSerializableMessage) { + try { + if(_engine.hasModel(modelName)) { + List jsonSerializableMessages = new LinkedList<>(); + jsonSerializableMessages.add(jsonSerializableMessage); + _engine.run(modelName, _id, _modelName, jsonSerializableMessages); + return SendingResult.Handled; + } else { + return SendingResult.NotHandled; + } + + } catch (WorkbenchException e) { + e.printStackTrace(); + return SendingResult.NotHandled; + } + } + + @Override + public SendingResult createInstance(String modelName, String id, T instance) { + try { + _engine.createInstance(modelName, id, instance); + return SendingResult.Handled; + } catch (Exception e) { + e.printStackTrace(); + return SendingResult.NotHandled; + } + } + + @Override + public SendingResult createInstanceFromPersistenceStore(String modelName, String id) { + try { + throw new NoSuchMethodException("Not available on the workbench."); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + @Override + public SendingResult createInstanceFromPersistenceStore(String modelName, String id, T defaultInstance) { + try { + throw new NoSuchMethodException("Not available on the workbench."); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + @Override + public SendingResult deleteInstance(String modelName, String id) { + _engine.deleteSimulationInstance(modelName, id); + return SendingResult.Handled; + } + + @Override + public SendingResult deleteThisInstance() { + _engine.deleteSimulationInstance(_modelName, _id); + _deleted = true; + return SendingResult.Handled; + } + + @Override + public void runThisInstance() { + try { + _scheduler.runThisInstance(_modelName, _id); + _enqueue = false; + } catch (WorkbenchException e) { + throw new RuntimeException(e); + } + + } + + @Override + public SimulationStatus stopSimulation() { + _simulationStatus = SimulationStatus.InstanceRequestedStop; + return _simulationStatus; + } + + public boolean delayRequested() { + return _delayRequested; + } + + public void reset(String modelName, String id) { + _modelName = modelName; + _id = id; + _requestedDelay = Long.MIN_VALUE; + _delayRequested = false; + _deleted = false; + _enqueue = true; + } + + public long getRequestedDelay() { + return _requestedDelay; + } + + public boolean deleted() { + return _deleted; + } + + public boolean enqueue() { + return _enqueue; + } + + public SimulationStatus getSimulationStatus() { + return _simulationStatus; + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationFlags.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationFlags.java new file mode 100644 index 0000000..4e7acff --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchSimulationFlags.java @@ -0,0 +1,25 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +enum WorkbenchSimulationFlags { + // Start the simulation + Start, + // Run the simulation + Run, + // Stop the simulation + Stop +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerService.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerService.java new file mode 100644 index 0000000..c5911a7 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerService.java @@ -0,0 +1,65 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.*; + +import java.time.Duration; + +class WorkbenchTimerService { + + static TimerActionResult startTimer(TwinExecutionEngine twinExecutionEngine, T instance, String model, String id, String timerName, Duration interval, TimerType timerType, TimerHandler timerHandler) { + if(timerName == null || timerName.isBlank() || timerName.isEmpty() || interval == null || + interval.isZero() || interval.isNegative() || timerType == null || timerHandler == null) { + String msg = String.format("Empty, blank, zero, or null parameter provided: timerName %s interval %s timerType %s timerHandler %s", + timerName, interval, timerType, timerHandler); + throw new IllegalArgumentException(msg); + + } + if (instance.TimerHandlers.size() >= Constants.MAX_TIMER_COUNT) // all timer slots are occupied + return TimerActionResult.FailedTooManyTimers; + + if(instance.TimerHandlers.containsKey(timerName)) return TimerActionResult.FailedTimerAlreadyExists; + + int timerId = -1; + + boolean[] taken = new boolean[Constants.MAX_TIMER_COUNT]; + // List of all timer Ids + for (TimerMetadata md : instance.TimerHandlers.values()) { + taken[md.getTimerId()] = true; + } + + for(int i = 0; i < taken.length; i++) { + if(!taken[i]) { + timerId = i; + break; + } + } + + twinExecutionEngine.addTimer(model, id, timerName, timerType, interval, timerHandler); + + TimerMetadata metadata = new TimerMetadata<>(timerHandler, timerType, interval.toMillis(), timerId); + instance.TimerHandlers.put(timerName, metadata); + return TimerActionResult.Success; + } + + static TimerActionResult stopTimer(TwinExecutionEngine twinExecutionEngine, T instance, String model, String id, String timerName) { + twinExecutionEngine.stopTimer(model, id, timerName); + instance.TimerHandlers.remove(timerName); + return TimerActionResult.Success; + } + +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerTask.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerTask.java new file mode 100644 index 0000000..6118b9e --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/WorkbenchTimerTask.java @@ -0,0 +1,63 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.scaleoutsoftware.digitaltwin.core.*; + +import java.time.Duration; +import java.util.TimerTask; + +class WorkbenchTimerTask extends TimerTask { + TwinExecutionEngine _engine; + String _modelName; + String _id; + String _timerName; + TwinProxy _proxy; + TimerType _type; + Duration _interval; + TimerHandler _handler; + + WorkbenchTimerTask(TwinExecutionEngine engine, String modelName, String id, String timerName, TwinProxy proxy, TimerType type, Duration interval, TimerHandler handler) { + _engine = engine; + _modelName = modelName; + _id = id; + _timerName = timerName; + _proxy = proxy; + _type = type; + _interval = interval; + _handler = handler; + } + + @Override + public void run() { + DigitalTwinBase instance = _proxy.getInstance(); + WorkbenchProcessingContext context = new WorkbenchProcessingContext(_engine, null); + context.reset(_modelName, _id, null, instance); + ProcessingResult result; + synchronized (instance) { + result = _handler.onTimedMessage(_timerName, instance, context); + } + switch (result) { + case UpdateDigitalTwin: + _engine.updateTwin(_modelName, _id, _proxy); + break; + case NoUpdate: + break; + default: + throw new RuntimeException(new WorkbenchException("Unknown return type from timer handler.")); + } + } +} diff --git a/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/package-info.java b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/package-info.java new file mode 100644 index 0000000..c8df4a2 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/main/java/com/scaleoutsoftware/digitaltwin/development/package-info.java @@ -0,0 +1,21 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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. +*/ + +/** + * Digital twin development API - Develop and test simulation/real-time digital twins. + */ +package com.scaleoutsoftware.digitaltwin.development; + diff --git a/docs/digitaltwin-core-docs/src/test/java/com/scaleoutsoftware/digitaltwin/development/TestWorkbench.java b/docs/digitaltwin-core-docs/src/test/java/com/scaleoutsoftware/digitaltwin/development/TestWorkbench.java new file mode 100644 index 0000000..4864388 --- /dev/null +++ b/docs/digitaltwin-core-docs/src/test/java/com/scaleoutsoftware/digitaltwin/development/TestWorkbench.java @@ -0,0 +1,873 @@ +/* + Copyright (c) 2025 by ScaleOut Software, Inc. + + 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 com.scaleoutsoftware.digitaltwin.development; + +import com.google.gson.Gson; +import com.scaleoutsoftware.digitaltwin.core.*; +import org.junit.Assert; +import org.junit.Test; + +import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; + +public class TestWorkbench { + public static class SimpleDigitalTwin extends DigitalTwinBase { + private String _stringProp; + public SimpleDigitalTwin() {} + public SimpleDigitalTwin(String stringProp) { + _stringProp = stringProp; + } + } + + public static class SimpleMessage { + String stringChange; + int intChange; + String payload; + public SimpleMessage(String s, int i) { + stringChange = s; + intChange = i; + } + } + + public static class SimpleMessageProcessor extends MessageProcessor implements Serializable { + + public SimpleMessageProcessor() {} + + @Override + public ProcessingResult processMessages(ProcessingContext processingContext, SimpleDigitalTwin instance, Iterable messages) { + Gson gson = new Gson(); + Date currentTime = processingContext.getCurrentTime(); + PersistenceProvider provider = processingContext.getPersistenceProvider(); + if(processingContext.getDigitalTwinModel().compareTo(instance.getModel()) != 0) { + throw new IllegalStateException(String.format("context.getModel and instance.getModel difer. %s:%s", processingContext.getDigitalTwinModel(), instance.getModel())); + } + if(processingContext.getDataSourceId().compareTo(instance.getId()) != 0) { + throw new IllegalStateException(String.format("context.getModel and instance.getModel difer. %s:%s", processingContext.getDigitalTwinModel(), instance.getModel())); + } + + if(instance.getModel().compareTo("SimSimple") == 0) {// if this is a simulation model... + for(SimpleMessage msg : messages) { + System.out.println(msg.stringChange); + } + } else { + for(SimpleMessage msg : messages) { + switch (msg.stringChange) { + case "SendToSource": + processingContext.sendToDataSource(new SimpleMessage("Hello from data source!", 10)); + break; + case "SendToTwin": + String jsonMsg = gson.toJson(msg); + byte[] bytes = jsonMsg.getBytes(StandardCharsets.UTF_8); + processingContext.sendToDigitalTwin(msg.payload == null ? msg.payload : "model", msg.intChange+"",bytes); + break; + case "LogMessage": + processingContext.logMessage(Level.INFO, msg.payload); + break; + case "StartTimer": + processingContext.startTimer("timer", Duration.ofMillis(1000), TimerType.Recurring, + new TimerHandler() { + @Override + public ProcessingResult onTimedMessage(String s, DigitalTwinBase digitalTwinBase, ProcessingContext processingContext) { + System.out.println("Hello from real-time timer."); + return ProcessingResult.UpdateDigitalTwin; + } + }); + break; + case "StopTimer": + processingContext.stopTimer("timer"); + break; + case "SharedData": + SharedData sharedData = processingContext.getSharedModelData(); + CacheResult result = sharedData.put("Hello", "Some string...".getBytes(StandardCharsets.UTF_8)); + if(result.getStatus() == CacheOperationStatus.ObjectPut) { + System.out.println("Successfully stored object in model storage."); + } + result = sharedData.get("Hello"); + if(result.getStatus() == CacheOperationStatus.ObjectRetrieved) { + System.out.println("Successfully retrieved " + new String(result.getValue(), StandardCharsets.UTF_8) + " from model storage."); + } + result = sharedData.remove("Hello"); + if(result.getStatus() == CacheOperationStatus.ObjectRemoved) { + System.out.println("Successfully removed " + new String(result.getValue(), StandardCharsets.UTF_8) + " from model storage."); + } + result = sharedData.put("modelTest", "assert".getBytes(StandardCharsets.UTF_8)); + sharedData = processingContext.getSharedGlobalData(); + result = sharedData.put("Hello", "Some string...".getBytes(StandardCharsets.UTF_8)); + if(result.getStatus() == CacheOperationStatus.ObjectPut) { + System.out.println("Successfully stored object in global storage."); + } + result = sharedData.get("Hello"); + if(result.getStatus() == CacheOperationStatus.ObjectRetrieved) { + System.out.println("Successfully retrieved " + new String(result.getValue(), StandardCharsets.UTF_8) + " from global storage."); + } + result = sharedData.remove("Hello"); + if(result.getStatus() == CacheOperationStatus.ObjectRemoved) { + System.out.println("Successfully removed " + new String(result.getValue(), StandardCharsets.UTF_8) + " from global storage."); + } + result = sharedData.put("globalTest", "assert".getBytes(StandardCharsets.UTF_8)); + break; + case "WakeUp": + SimulationController controller = processingContext.getSimulationController(); + instance._stringProp = "WakeUp"; + System.out.println("Calling run this twin..."); + controller.runThisInstance(); + break; + default: + break; + } + } + } + return ProcessingResult.UpdateDigitalTwin; + } + } + + public static class RealTimeCar extends DigitalTwinBase { + private int _tirePressure; + public RealTimeCar() { _tirePressure=0; } + public RealTimeCar(int startingTirePressure) { + _tirePressure = startingTirePressure; + } + + public void incrementTirePressure(int increment) { + _tirePressure += increment; + } + + public int getTirePressure() { + return _tirePressure; + } + } + + public static class TirePressureMessage { + final int _pressureChange; + public TirePressureMessage(int pressureChange) { + _pressureChange = pressureChange; + } + + public int getPressureChange() { + return _pressureChange; + } + } + + public static class RealTimeCarMessageProcessor extends MessageProcessor implements Serializable { + final int TIRE_PRESSURE_FULL = 100; + @Override + public ProcessingResult processMessages(ProcessingContext processingContext, RealTimeCar car, Iterable messages) throws Exception { + // apply the updates from the messages + for(TirePressureMessage message : messages) { + car.incrementTirePressure(message.getPressureChange()); + } + if(car.getTirePressure() > TIRE_PRESSURE_FULL) { + processingContext.sendToDataSource(new TirePressureMessage(car.getTirePressure())); + } + return ProcessingResult.UpdateDigitalTwin; + } + } + + public static class SimulationPump extends DigitalTwinBase { + private double _tirePressureChange; + private boolean _tirePressureReached = false; + public SimulationPump() {} + public SimulationPump(double pressureChange) { + _tirePressureChange = pressureChange; + } + + public double getTirePressureChange() { + return _tirePressureChange; + } + + public void setTirePressureReached() { + _tirePressureReached = true; + } + + public boolean isTireFull() { + return _tirePressureReached; + } + } + + public static class SimulatedPumpMessageProcessor extends MessageProcessor implements Serializable { + @Override + public ProcessingResult processMessages(ProcessingContext processingContext, SimulationPump simCar, Iterable messages) throws Exception { + // apply the updates from the messages + simCar.setTirePressureReached(); + return ProcessingResult.UpdateDigitalTwin; + } + } + + public static class PumpSimulationProcessor extends SimulationProcessor implements Serializable { + @Override + public ProcessingResult processModel(ProcessingContext processingContext, SimulationPump simPump, Date date) { + SimulationController controller = processingContext.getSimulationController(); + if(simPump.isTireFull()) { + controller.deleteThisInstance(); + } else { + int change = (int) (100 * simPump.getTirePressureChange()); + controller.emitTelemetry("RealTimeCar", new TirePressureMessage(change)); + } + return ProcessingResult.UpdateDigitalTwin; + } + } + + public static class SimpleSimProcessor extends SimulationProcessor implements Serializable { + private Gson _gson = new Gson(); + private AtomicInteger timesInvoked = new AtomicInteger(0); + private boolean _useJson; + private String _modelIdToMessage; + private String _instanceIdToMessage; + + public SimpleSimProcessor(boolean json) { + _useJson = json; + } + + public SimpleSimProcessor(String modelIdToMessage, String instanceIdToMessage) { + _useJson = false; + _modelIdToMessage = modelIdToMessage; + _instanceIdToMessage = instanceIdToMessage; + } + + public int getTimesInvoked() { + return timesInvoked.get(); + } + + @Override + public ProcessingResult processModel(ProcessingContext processingContext, SimpleDigitalTwin simpleDigitalTwin, Date date) { + timesInvoked.addAndGet(1); + SimulationController controller = processingContext.getSimulationController(); + if(simpleDigitalTwin.getId().compareTo("stop") == 0) { + controller.stopSimulation(); + return ProcessingResult.UpdateDigitalTwin; + } else if(simpleDigitalTwin.getId().contains("delay")) { + controller.delay(Duration.ofSeconds(600)); + return ProcessingResult.UpdateDigitalTwin; + } else if (simpleDigitalTwin.getId().contains("timer")) { + processingContext.startTimer("timer", Duration.ofMillis(1000), TimerType.OneTime, new TimerHandler<>() { + @Override + public ProcessingResult onTimedMessage(String s, DigitalTwinBase digitalTwinBase, ProcessingContext processingContext) { + System.out.println("timer called!"); + return ProcessingResult.UpdateDigitalTwin; + } + }); + return ProcessingResult.UpdateDigitalTwin; + } else if (simpleDigitalTwin.getId().contains("log")) { + processingContext.logMessage(Level.INFO, simpleDigitalTwin._stringProp); + processingContext.logMessage(Level.WARNING, simpleDigitalTwin._stringProp); + processingContext.logMessage(Level.SEVERE, simpleDigitalTwin._stringProp); + return ProcessingResult.UpdateDigitalTwin; + } else if (simpleDigitalTwin.getId().contains("alert")) { + processingContext.sendAlert("alert", new AlertMessage(simpleDigitalTwin.getId(), simpleDigitalTwin.getId(), simpleDigitalTwin._stringProp)); + return ProcessingResult.UpdateDigitalTwin; + } else if (simpleDigitalTwin.getId().contains("sleeper")) { + if(simpleDigitalTwin._stringProp.compareTo("WakeUp") == 0) { + System.out.println("Model ran after runThisInstance"); + simpleDigitalTwin._stringProp = "asleep"; + } + System.out.println("Going to sleep..."); + controller.delayIndefinitely(); + return ProcessingResult.UpdateDigitalTwin; + } else if (simpleDigitalTwin.getId().contains("waker")) { + System.out.println("Waking up sleeper..."); + processingContext.sendToDigitalTwin(_modelIdToMessage, _instanceIdToMessage, new SimpleMessage("WakeUp", 23)); + return ProcessingResult.UpdateDigitalTwin; + } else if (simpleDigitalTwin.getId().compareTo("initSimulation") == 0) { + return ProcessingResult.UpdateDigitalTwin; + } + long delay = Long.parseLong(simpleDigitalTwin.getId()); + controller.delay(Duration.ofSeconds(delay)); + if(_useJson) { + byte[] msg = _gson.toJson(new SimpleMessage("SendToSource", 23)).getBytes(StandardCharsets.UTF_8); + controller.emitTelemetry("Simple", msg); + } else { + SimpleMessage telemetry = new SimpleMessage("SendToSource", 23); + controller.emitTelemetry("Simple", telemetry); + } + return ProcessingResult.UpdateDigitalTwin; + } + + @Override + public ProcessingResult onInitSimulation(InitSimulationContext ctx, SimpleDigitalTwin simpleDigitalTwin, Date date) { + if(simpleDigitalTwin.getId().compareTo("initSimulation") == 0) { + timesInvoked.set(1000); + } + + return ProcessingResult.UpdateDigitalTwin; + } + } + + @Test + public void TestWorkbenchNoInstances() throws WorkbenchException { + Gson gson = new Gson(); + SimulationStep result; + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), new SimpleSimProcessor(false), SimpleDigitalTwin.class, SimpleMessage.class); + + result = workbench.runSimulation(System.currentTimeMillis(), System.currentTimeMillis() + 60000, 1, 1000); + Assert.assertSame(SimulationStatus.NoRemainingWork, result.getStatus()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void TestWorkbenchOnlySimulationInstances() throws WorkbenchException { + SimpleSimProcessor processor = new SimpleSimProcessor(false); + Gson gson = new Gson(); + SimulationStep result; + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + + for (int i = 1; i < 2; i++) { + DigitalTwinBase instance = new SimpleDigitalTwin("hello" + i); + workbench.addInstance("SimSimple", "" + i, instance); + } + + result = workbench.runSimulation(System.currentTimeMillis(), System.currentTimeMillis() + 60000, 1, 1000); + Assert.assertSame(SimulationStatus.EndTimeReached, result.getStatus()); + Assert.assertEquals(60, processor.getTimesInvoked()); + } catch (Exception e) { + throw new RuntimeException(e); + } + + + } + + @Test + public void TestWorkbenchSample() throws WorkbenchException { + long expectedStop; + SimulationStep step; + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("RealTimeCar", new RealTimeCarMessageProcessor(), RealTimeCar.class, TirePressureMessage.class); + workbench.addSimulationModel("SimPump", new SimulatedPumpMessageProcessor(), new PumpSimulationProcessor(), SimulationPump.class, TirePressureMessage.class); + + workbench.addInstance("SimPump", "23", new SimulationPump(0.29d)); + long start = System.currentTimeMillis(); + long end = start + 60000; + expectedStop = start + 5000; + step = workbench.initializeSimulation(start, end, 1000); + + while (step.getStatus() == SimulationStatus.Running) { + step = workbench.step(); + HashMap realTimeCars = workbench.getInstances("RealTimeCar"); + RealTimeCar rtCar = (RealTimeCar) realTimeCars.get("23"); + System.out.println("rtCar: " + rtCar.getTirePressure()); + } + Assert.assertEquals(expectedStop, step.getTime()); + System.out.println("Simulation completed. Sim status: " + step.getStatus() + " endTime: " + step.getTime()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void TestWorkbenchSampleRun() throws WorkbenchException { + long expectedStop; + SimulationStep step; + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("RealTimeCar", new RealTimeCarMessageProcessor(), RealTimeCar.class, TirePressureMessage.class); + workbench.addSimulationModel("SimModel", new SimulatedPumpMessageProcessor(), new PumpSimulationProcessor(), SimulationPump.class, TirePressureMessage.class); + + workbench.addInstance("SimModel", "23", new SimulationPump(0.29d)); + long start = System.currentTimeMillis(); + long end = start + 60000; + expectedStop = start + 5000; + step = workbench.runSimulation(start, end, 1, 1000); + Assert.assertEquals(expectedStop, step.getTime()); + System.out.println("Simulation completed. Sim status: " + step.getStatus() + " endTime: " + step.getTime()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void TestWorkbenchSpeedup() throws WorkbenchException { + SimpleSimProcessor processor = new SimpleSimProcessor(false); + Gson gson = new Gson(); + SimulationStep result; + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + + for (int i = 0; i < 1000; i++) { + DigitalTwinBase instance = new SimpleDigitalTwin("hello" + i); + workbench.addInstance("SimSimple", "" + i, instance); + } + + long start = System.currentTimeMillis(); + long stop = start + 60000; + result = workbench.runSimulation(System.currentTimeMillis(), stop, 100, 1000); + Assert.assertSame(SimulationStatus.EndTimeReached, result.getStatus()); + + // each id (0-999) delays for it's id in seconds + Assert.assertEquals(1249, processor.getTimesInvoked()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void TestWorkbenchDebug() throws WorkbenchException{ + Gson gson = new Gson(); + int numInstance = 10; + int numItterations = 0; + for(int i = 0; i < 20; i ++) { + SimpleSimProcessor processor = new SimpleSimProcessor(i >= 10); + SimulationStep result; + long start; + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + + for (int twinCount = 0; twinCount < 1000; twinCount++) { + DigitalTwinBase instance = new SimpleDigitalTwin("hello" + twinCount); + workbench.addInstance("SimSimple", "" + twinCount, instance); + } + result = workbench.initializeSimulation(System.currentTimeMillis(), System.currentTimeMillis() + 60000, 1000); + start = System.currentTimeMillis(); + while (result.getStatus() == SimulationStatus.Running) { + result = workbench.step(); + if (result.getStatus() == SimulationStatus.Running) { + numItterations++; + } + } + long stop = System.currentTimeMillis(); + System.out.println("RunTime: " + (stop-start)); + Assert.assertSame(SimulationStatus.EndTimeReached, result.getStatus()); + // each id (0-999) delays for it's id in seconds, processor.getTimesInvoked()); + Assert.assertEquals(1249, processor.getTimesInvoked()); + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + } + + @Test + public void testWorkbenchDebugOnlySimulationInstances() throws WorkbenchException { + SimpleSimProcessor processor = new SimpleSimProcessor(false); + Gson gson = new Gson(); + long stopTimeMs; + SimulationStep step; + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + + + DigitalTwinBase instance = new SimpleDigitalTwin("hello" + 100); + workbench.addInstance("SimSimple", "" + 100, instance); + + long startTimeMs = System.currentTimeMillis(); + stopTimeMs = startTimeMs + 60000; + long expectedTm = startTimeMs; + step = workbench.initializeSimulation(startTimeMs, stopTimeMs, 1000); + while (step.getStatus() == SimulationStatus.Running) { + step = workbench.step(); + Assert.assertEquals(expectedTm, step.getTime()); + expectedTm += 1000; + } + Assert.assertSame(SimulationStatus.EndTimeReached, step.getStatus()); + Assert.assertEquals(stopTimeMs, step.getTime()); + Assert.assertEquals(60, processor.getTimesInvoked()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void TestWorkbenchStop() throws WorkbenchException{ + Gson gson = new Gson(); + int numInstance = 10; + int numItterations = 0; + SimpleSimProcessor processor = new SimpleSimProcessor(false); + SimulationStep result; + long start; + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + + for (int twinCount = 0; twinCount < 1000; twinCount++) { + DigitalTwinBase instance = new SimpleDigitalTwin("hello" + twinCount); + workbench.addInstance("SimSimple", "" + twinCount, instance); + } + DigitalTwinBase instance = new SimpleDigitalTwin("stop"); + workbench.addInstance("SimSimple", "stop", instance); + + result = workbench.initializeSimulation(System.currentTimeMillis(), System.currentTimeMillis() + 60000, 1000); + start = System.currentTimeMillis(); + while (result.getStatus() == SimulationStatus.Running) { + result = workbench.step(); + } + long stop = System.currentTimeMillis(); + System.out.println("RunTime: " + (stop-start)); + Assert.assertSame(SimulationStatus.InstanceRequestedStop, result.getStatus()); + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + + @Test + public void TestWorkbenchHugeDelays() throws WorkbenchException{ + Gson gson = new Gson(); + int numInstance = 10; + int numItterations = 0; + SimpleSimProcessor processor = new SimpleSimProcessor(false); + SimulationStep result; + long start; + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + + for (int twinCount = 0; twinCount < 1000; twinCount++) { + DigitalTwinBase instance = new SimpleDigitalTwin("delay" + twinCount); + workbench.addInstance("SimSimple", "delay" + twinCount, instance); + } + + result = workbench.initializeSimulation(System.currentTimeMillis(), System.currentTimeMillis() + 60000, 1000); + start = System.currentTimeMillis(); + while (result.getStatus() == SimulationStatus.Running) { + result = workbench.step(); + } + long stop = System.currentTimeMillis(); + System.out.println("RunTime: " + (stop-start)); + Assert.assertSame(SimulationStatus.EndTimeReached, result.getStatus()); + Assert.assertEquals(1000, processor.getTimesInvoked()); + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + + @Test + public void TestWorkbenchTimer() throws WorkbenchException{ + Gson gson = new Gson(); + int numInstance = 10; + int numItterations = 0; + SimpleSimProcessor processor = new SimpleSimProcessor(false); + SimulationStep result; + long start; + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + + for (int twinCount = 0; twinCount < 1; twinCount++) { + DigitalTwinBase instance = new SimpleDigitalTwin("timer" + twinCount); + workbench.addInstance("SimSimple", "timer" + twinCount, instance); + } + + result = workbench.initializeSimulation(System.currentTimeMillis(), System.currentTimeMillis() + 60000, 1000); + start = System.currentTimeMillis(); + while (result.getStatus() == SimulationStatus.Running) { + result = workbench.step(); + } + long stop = System.currentTimeMillis(); + System.out.println("RunTime: " + (stop-start)); + Assert.assertSame(SimulationStatus.EndTimeReached, result.getStatus()); + Assert.assertEquals(60, processor.getTimesInvoked()); + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + + @Test + public void TestWorkbenchRealtimeTimer() throws WorkbenchException, InterruptedException { + Gson gson = new Gson(); + int numInstance = 10; + int numItterations = 0; + SimpleSimProcessor processor = new SimpleSimProcessor(false); + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + + for (int twinCount = 0; twinCount < 1; twinCount++) { + DigitalTwinBase instance = new SimpleDigitalTwin("timer" + twinCount); + workbench.addInstance("Simple", "timer" + twinCount, instance); + } + + List messages = new LinkedList<>(); + messages.add(new SimpleMessage("StartTimer", 0)); + workbench.send("Simple", "timer0", messages); + + Thread.sleep(3000); + messages = new LinkedList<>(); + messages.add(new SimpleMessage("StopTimer", 0)); + workbench.send("Simple", "timer0", messages); + Thread.sleep(2000); + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + + @Test + public void TestWorkbenchRealtimeTimerScope() throws WorkbenchException, InterruptedException { + Gson gson = new Gson(); + int numInstance = 10; + int numItterations = 0; + SimpleSimProcessor processor = new SimpleSimProcessor(false); + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + + for(int twinCount = 0; twinCount < 1; twinCount++) { + DigitalTwinBase instance = new SimpleDigitalTwin("timer"+twinCount); + workbench.addInstance("Simple", "timer" + twinCount, instance); + } + + List messages = new LinkedList<>(); + messages.add(new SimpleMessage("StartTimer", 0)); + workbench.send("Simple", "timer0", messages); + Thread.sleep(3000); + } catch (Exception e) { + Assert.fail(); + } + Thread.sleep(5000); + } + + @Test + public void TestWorkbenchSimulationLogMessage() throws WorkbenchException { + SimpleSimProcessor processor = new SimpleSimProcessor(false); + Gson gson = new Gson(); + String logMessageContent; + long exp; + long start; + long stop; + List messages; + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + + logMessageContent = "this is a log message"; + for (int i = 0; i < 1; i++) { + DigitalTwinBase instance = new SimpleDigitalTwin(logMessageContent); + workbench.addInstance("SimSimple", "log" + i, instance); + } + + exp = 60; + start = System.currentTimeMillis(); + stop = start + (exp * 1000); + SimulationStep result = workbench.runSimulation(start, stop, 1, 1000); + Assert.assertSame(SimulationStatus.EndTimeReached, result.getStatus()); + Assert.assertEquals(stop, result.getTime()); + Assert.assertEquals(exp, processor.getTimesInvoked()); + messages = workbench.getLoggedMessages("SimSimple", start); + Assert.assertEquals(messages.size(), exp * 3); + for (LogMessage message : messages) { + Assert.assertSame(logMessageContent, message.getMessage()); + Assert.assertTrue(message.getSeverity() == Level.INFO || + message.getSeverity() == Level.WARNING || + message.getSeverity() == Level.SEVERE); + Assert.assertTrue(message.getTimestamp() >= start && message.getTimestamp() < stop); + } + + messages = workbench.getLoggedMessages("SimSimple", 0L); + Assert.assertEquals(messages.size(), exp * 3); + for (LogMessage message : messages) { + Assert.assertSame(logMessageContent, message.getMessage()); + Assert.assertTrue(message.getSeverity() == Level.INFO || + message.getSeverity() == Level.WARNING || + message.getSeverity() == Level.SEVERE); + Assert.assertTrue(message.getTimestamp() >= start && message.getTimestamp() < stop); + } + + messages = workbench.getLoggedMessages("SimSimple", start + 5000); + Assert.assertEquals(messages.size(), (exp*3 - (5*3))); + for(LogMessage message : messages) { + Assert.assertSame(logMessageContent, message.getMessage()); + Assert.assertTrue(message.getSeverity() == Level.INFO || + message.getSeverity() == Level.WARNING || + message.getSeverity() == Level.SEVERE); + Assert.assertTrue(message.getTimestamp() >= start && message.getTimestamp() < stop); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void TestWorkbenchSimulationAlertMessage() throws WorkbenchException { + SimpleSimProcessor processor = new SimpleSimProcessor(false); + Gson gson = new Gson(); + SimulationStep result; + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addAlertProvider("SimSimple", new AlertProviderConfiguration("test", "www.url.com", "integrationkey", "routingKey", "alert", "entityId")); + + String alertMessageContent = "this is an alert message"; + String id = "alert"; + for (int i = 0; i < 1; i++) { + DigitalTwinBase instance = new SimpleDigitalTwin(alertMessageContent); + workbench.addInstance("SimSimple", id, instance); + } + long exp = 60; + long start = System.currentTimeMillis(); + long stop = start + (exp * 1000); + result = workbench.runSimulation(System.currentTimeMillis(), System.currentTimeMillis() + 60000, 1, 1000); + Assert.assertSame(SimulationStatus.EndTimeReached, result.getStatus()); + Assert.assertEquals(stop, result.getTime()); + Assert.assertEquals(exp, processor.getTimesInvoked()); + List messages = workbench.getAlertMessages("SimSimple", "alert"); + Assert.assertEquals(messages.size(), exp); + for(AlertMessage msg : messages) { + Assert.assertSame(msg.getMessage(), alertMessageContent); + Assert.assertSame(msg.getSeverity(), id); + Assert.assertSame(msg.getTitle(), id); + Assert.assertNull(msg.getOptionalTwinInstanceProperties()); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test(expected = WorkbenchException.class) + public void TestWorkbenchException() throws Exception { + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", null, SimpleDigitalTwin.class, SimpleMessage.class); + } catch (Exception e) { + throw e; + } + } + + @Test + public void TestWorkbenchPeek() throws Exception { + SimpleSimProcessor processor = new SimpleSimProcessor(false); + long stopTimeMs; + SimulationStep step; + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + + + DigitalTwinBase instance = new SimpleDigitalTwin("hello" + 100); + workbench.addInstance("SimSimple", "" + 100, instance); + + long startTimeMs = System.currentTimeMillis(); + stopTimeMs = startTimeMs + 60000; + long expectedTm = startTimeMs; + step = workbench.initializeSimulation(startTimeMs, stopTimeMs, 1000); + while (step.getStatus() == SimulationStatus.Running) { + step = workbench.step(); + Assert.assertEquals(expectedTm, step.getTime()); + expectedTm += 1000; + if(step.getStatus() == SimulationStatus.Running) { + Date peek = workbench.peek(); + Assert.assertEquals(expectedTm, peek.getTime()); + } + } + Assert.assertSame(SimulationStatus.EndTimeReached, step.getStatus()); + Assert.assertEquals(stopTimeMs, step.getTime()); + Assert.assertEquals(60, processor.getTimesInvoked()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void TestWorkbenchGenerateModelSchema() throws Exception { + SimpleSimProcessor processor = new SimpleSimProcessor(false); + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + String schemaAsJson = workbench.generateModelSchema("Simple"); + Assert.assertSame(schemaAsJson, "{\"modelType\":\"com.scaleoutsoftware.digitaltwin.development.TestWorkbench$SimpleDigitalTwin\",\"messageProcessorType\":\"com.scaleoutsoftware.digitaltwin.development.TestWorkbench$SimpleMessageProcessor\",\"messageType\":\"com.scaleoutsoftware.digitaltwin.development.TestWorkbench$SimpleMessage\",\"assemblyName\":\"NOT_USED_BY_JAVA_MODELS\",\"enablePersistence\":false,\"enableSimulationSupport\":false,\"alertProviders\":[]}"); + String dir = workbench.generateModelSchema("SimSimple", System.getProperty("user.dir")); + Assert.assertEquals(String.format("%s\\model.json", System.getProperty("user.dir")), dir); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test (expected = WorkbenchException.class) + public void TestWorkbenchGenerateModelSchemaExceptionally() throws Exception { + SimpleSimProcessor processor = new SimpleSimProcessor(false); + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("SimSimple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + String schemaAsJson = workbench.generateModelSchema(""); + Assert.assertNotNull(schemaAsJson); + } catch (Exception e) { + throw e; + } + } + + @Test + public void TestWorkbenchSharedData() throws Exception { + try (Workbench workbench = new Workbench()) { + workbench.addRealTimeModel("Simple", new SimpleMessageProcessor(), SimpleDigitalTwin.class, SimpleMessage.class); + LinkedList messages = new LinkedList<>(); + messages.add(new SimpleMessage("SharedData", 29)); + workbench.send("Simple", "23", messages); + CacheResult result = workbench.getSharedModelData("Simple").get("modelTest"); + Assert.assertEquals(CacheOperationStatus.ObjectRetrieved, result.getStatus()); + Assert.assertEquals("modelTest", result.getKey()); + Assert.assertEquals("assert", new String(result.getValue(), StandardCharsets.UTF_8)); + result = workbench.getSharedGlobalData("Simple").get("globalTest"); + Assert.assertEquals(CacheOperationStatus.ObjectRetrieved, result.getStatus()); + Assert.assertEquals("globalTest", result.getKey()); + Assert.assertEquals("assert", new String(result.getValue(), StandardCharsets.UTF_8)); + } catch (Exception e) { + throw e; + } + } + + @Test + public void TestWorkbenchRunThisInstance() throws Exception { + try (Workbench workbench = new Workbench()) { + workbench.addSimulationModel("Simple", new SimpleMessageProcessor(), new SimpleSimProcessor("Simple2", "sleeper"), SimpleDigitalTwin.class, SimpleMessage.class); + workbench.addSimulationModel("Simple2", new SimpleMessageProcessor(), new SimpleSimProcessor(false), SimpleDigitalTwin.class, SimpleMessage.class); + + workbench.addInstance("Simple", "waker", new SimpleDigitalTwin("waker")); + workbench.addInstance("Simple2", "sleeper", new SimpleDigitalTwin("sleeper")); + long startTimeMs = System.currentTimeMillis(); + long stopTimeMs = startTimeMs + 15000L; + long step = 1000L; + workbench.runSimulation(startTimeMs, stopTimeMs, 1, step); + SimpleDigitalTwin waker = (SimpleDigitalTwin) workbench.getInstances("Simple").get("waker"); + SimpleDigitalTwin sleeper = (SimpleDigitalTwin) workbench.getInstances("Simple2").get("sleeper"); + Assert.assertNotNull(waker); + Assert.assertNotNull(sleeper); + Assert.assertEquals("waker", waker._stringProp); + Assert.assertEquals("asleep", sleeper._stringProp); + } catch (Exception e) { + throw e; + } + } + + @Test + public void TestWorkbenchInitSimulation() throws Exception { + try (Workbench workbench = new Workbench()) { + SimpleSimProcessor processor = new SimpleSimProcessor(false); + workbench.addSimulationModel("Simple", new SimpleMessageProcessor(), processor, SimpleDigitalTwin.class, SimpleMessage.class); + + workbench.addInstance("Simple", "initSimulation", new SimpleDigitalTwin("waker")); + + long simRuntimeMs = 15000L; + long startTimeMs = System.currentTimeMillis(); + long stopTimeMs = startTimeMs + simRuntimeMs; + int speedup = 1; + long step = 1000L; + long expectedInvokes = simRuntimeMs/1000L; + int initSimExpectedInvokes = 1000; + workbench.runSimulation(startTimeMs, stopTimeMs, speedup, step); + Assert.assertEquals(expectedInvokes + initSimExpectedInvokes, processor.timesInvoked.get()); + } catch (Exception e) { + throw e; + } + } +} diff --git a/docs/help-doc.html b/docs/help-doc.html index 2af3cbe..16c9fe8 100644 --- a/docs/help-doc.html +++ b/docs/help-doc.html @@ -2,7 +2,7 @@ -API Help (digitaltwin-core-docs 3.0.4 API) +API Help (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/index-all.html b/docs/index-all.html index e149a6e..282504b 100644 --- a/docs/index-all.html +++ b/docs/index-all.html @@ -2,7 +2,7 @@ -Index (digitaltwin-core-docs 3.0.4 API) +Index (digitaltwin-core-docs 3.0.5 API) @@ -56,6 +56,10 @@

        A

        Adds an alert provider configuration to the specified model on this workbench.
        +
        addGlobalModelData(String, byte[]) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
        +
        +
        Add a key/value pair to the global SharedData.
        +
        addInstance(String, String, DigitalTwinBase) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
        Adds a digital twin instance to the workbench.
        @@ -64,6 +68,10 @@

        A

        Adds a real-time digital twin model to the workbench.
        +
        addSharedModelData(String, String, byte[]) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
        +
        +
        Add a key/value pair to SharedData for a model.
        +
        addSimulationModel(String, MessageProcessor<T, V>, SimulationProcessor<T>, Class<T>, Class<V>) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
        Adds a simulation digital twin model to the workbench.
        @@ -95,6 +103,22 @@

        A

        C

        +
        CacheCleared - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
        +
        +
        The cache was cleared successfully.
        +
        +
        CacheOperationStatus - Enum Class in com.scaleoutsoftware.digitaltwin.core
        +
        +
        Status of a cache operation.
        +
        +
        CacheResult - Interface in com.scaleoutsoftware.digitaltwin.core
        +
        +
        Represents a response from a SharedData operation.
        +
        +
        clear() - Method in interface com.scaleoutsoftware.digitaltwin.core.SharedData
        +
        +
        Clear the shared data cache.
        +
        close() - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
         
        com.scaleoutsoftware.digitaltwin.core - package com.scaleoutsoftware.digitaltwin.core
        @@ -105,6 +129,10 @@

        C

        Digital twin development API - Develop and test simulation/real-time digital twins.
        +
        CosmosDb - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
        +
        +
        Enum for CosmosDB
        +
        createInstance(String, String, T) - Method in interface com.scaleoutsoftware.digitaltwin.core.SimulationController
        Create a new digital twin instance for simulation processing.
        @@ -125,6 +153,11 @@

        D

        Delay simulation processing for this DigitalTwin instance for a duration of time.
        +
        delayIndefinitely() - Method in interface com.scaleoutsoftware.digitaltwin.core.SimulationController
        +
        +
        + Delay simulation processing for this DigitalTwin instance, indefinitely.
        +
        deleteInstance(String, String) - Method in interface com.scaleoutsoftware.digitaltwin.core.SimulationController
        Delete and remove a digital twin instance from simulation processing.
        @@ -138,7 +171,9 @@

        D

        A real-time digital twin of a data source.
        DigitalTwinBase() - Constructor for class com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase
        -
         
        +
        +
        Default constructor.
        +
        DigitalTwinTimerMessage - Class in com.scaleoutsoftware.digitaltwin.core
        A message sent to a digital twin instance's message processor.
        @@ -147,6 +182,10 @@

        D

        Construct a digital twin timer message.
        +
        DynamoDb - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
        +
        +
        Enum for DynamoDB
        +

        E

        @@ -212,6 +251,10 @@

        G

        Generates a ModelSchema for the parameter modelName and writes the schema to a file on the file system.
        +
        get(String) - Method in interface com.scaleoutsoftware.digitaltwin.core.SharedData
        +
        +
        Retrieves an existing object from the cache.
        +
        getAlertMessages(String, String) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
        Retrieves alert messages from digital twin instances.
        @@ -248,6 +291,10 @@

        G

        Retrieve the entity ID for this alert provider configuration.
        +
        getEntryPoint() - Method in class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        +
        +
        Retrieves the packaged model's entry point (fully-qualified class name -- FQCN -- of a Java main) for launching.
        +
        getId() - Method in class com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase
        The identifier of this DigitalTwin.
        @@ -284,6 +331,10 @@

        G

        Retrieve the integration key for this alert provider configuration.
        +
        getKey() - Method in interface com.scaleoutsoftware.digitaltwin.core.CacheResult
        +
        +
        Gets the key or null to the object associated with the result.
        +
        getLoggedMessages(String, long) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
        Retrieves messages logged by digital twin instances for a specified mdoel.
        @@ -326,6 +377,10 @@

        G

        Retrieve the name of this alert provider configuration.
        +
        getName() - Method in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
        +
        +
        Retrieve the name of the persistence provider type.
        +
        getNextSimulationTimeMs() - Method in class com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase
        Retrieve the next simulation time in milliseconds.
        @@ -374,6 +429,10 @@

        G

        Retrieves a future that will return a property value for a RTDT instance or null if the property doesn't exist.
        +
        getServiceOrdinalValue() - Method in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
        +
        +
        Retrieve the ordinal value (used by the DTBuidler service).
        +
        getSeverity() - Method in class com.scaleoutsoftware.digitaltwin.core.AlertMessage
        Retrieve the severity for this alert message.
        @@ -382,6 +441,38 @@

        G

        Retrieve the severity of this log message.
        +
        getSharedGlobalData() - Method in class com.scaleoutsoftware.digitaltwin.core.InitContext
        +
        +
        Retrieve a SharedData accessor for globally shared data.
        +
        +
        getSharedGlobalData() - Method in interface com.scaleoutsoftware.digitaltwin.core.InitSimulationContext
        +
        +
        Retrieve a SharedData accessor for globally shared data.
        +
        +
        getSharedGlobalData() - Method in class com.scaleoutsoftware.digitaltwin.core.ProcessingContext
        +
        +
        Retrieve a SharedData accessor for globally shared data.
        +
        +
        getSharedGlobalData() - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
        +
        +
        Retrieve the global SharedData.
        +
        +
        getSharedModelData() - Method in class com.scaleoutsoftware.digitaltwin.core.InitContext
        +
        +
        Retrieve a SharedData accessor for this model's shared data.
        +
        +
        getSharedModelData() - Method in interface com.scaleoutsoftware.digitaltwin.core.InitSimulationContext
        +
        +
        Retrieve a SharedData accessor for this model's shared data.
        +
        +
        getSharedModelData() - Method in class com.scaleoutsoftware.digitaltwin.core.ProcessingContext
        +
        +
        Retrieve a SharedData accessor for this model's shared data.
        +
        +
        getSharedModelData(String) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
        +
        +
        Retrieve the SharedData for a model.
        +
        getSimulationController() - Method in class com.scaleoutsoftware.digitaltwin.core.ProcessingContext
        Retrieve the running SimulationController or null if no simulation is running.
        @@ -390,11 +481,20 @@

        G

        Retrieve the simulation processor type (a SimulationProcessor implementation).
        +
        getSimulationStartTime() - Method in interface com.scaleoutsoftware.digitaltwin.core.SimulationController
        +
        +
        + Retrieves the simulation start time.
        +
        getSimulationTimeIncrement() - Method in interface com.scaleoutsoftware.digitaltwin.core.SimulationController
        Retrieves the current simulation time increment.
        +
        getStatus() - Method in interface com.scaleoutsoftware.digitaltwin.core.CacheResult
        +
        +
        Gets the status of the cache operation.
        +
        getStatus() - Method in class com.scaleoutsoftware.digitaltwin.development.SimulationStep
        Retrieve the SimulationStatus of the simulation interval.
        @@ -451,6 +551,10 @@

        G

        Retrieve the URL for this alert provider configuration.
        +
        getValue() - Method in interface com.scaleoutsoftware.digitaltwin.core.CacheResult
        +
        +
        Get the object returned from a Get operation.
        +

        H

        @@ -475,12 +579,19 @@

        I

        digital twin.
        InitContext() - Constructor for class com.scaleoutsoftware.digitaltwin.core.InitContext
        -
         
        +
        +
        Default constructor.
        +
        initializeSimulation(long, long, long) - Method in class com.scaleoutsoftware.digitaltwin.development.Workbench
        Initializes the simulation so that each interval can be run separately by calling the Workbench.step() function.
        +
        InitSimulationContext - Interface in com.scaleoutsoftware.digitaltwin.core
        +
        +
        The InitSimulationContext is passed as a parameter to the SimulationProcessor.onInitSimulation(InitSimulationContext, DigitalTwinBase, Date) method of + digital twin instance when a simulation is initializing.
        +
        InstanceRequestedStop - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.SimulationStatus
        A digital twin instance has requested the simulation to stop by calling SimulationController.stopSimulation()
        @@ -512,13 +623,21 @@

        M

        Processes messages for a real-time digital twin.
        MessageProcessor() - Constructor for class com.scaleoutsoftware.digitaltwin.core.MessageProcessor
        -
         
        +
        +
        Default constructor.
        +
        MessageProcessorBase<T extends DigitalTwinBase> - Class in com.scaleoutsoftware.digitaltwin.core
        Base class for the MessageProcessor to help with typing.
        MessageProcessorBase() - Constructor for class com.scaleoutsoftware.digitaltwin.core.MessageProcessorBase
        -
         
        +
        +
        Default constructor.
        +
        +
        messageRecordingEnabled() - Method in class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        +
        +
        Retrieves the message recording enabled status.
        +
        Model - Variable in class com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase
        The model this twin instance belongs to.
        @@ -532,18 +651,66 @@

        M

        Creates a model schema from a digital twin class, a message processor class, and a message class.
        +
        ModelSchema(String, String, String, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        +
        +
        Creates a model schema from a digital twin class, a message processor class, and a message class.
        +
        +
        ModelSchema(String, String, String, String) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        +
        +
        Model schema with a defined entry point.
        +
        +
        ModelSchema(String, String, String, String, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        +
        +
        Creates a model schema from a digital twin class, a message processor class, and a message class.
        +
        ModelSchema(String, String, String, String, PersistenceProviderType, List<AlertProviderConfiguration>) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        Creates a model schema from a digital twin class, a message processor class, a message class, and alert provider configurations.
        +
        ModelSchema(String, String, String, String, PersistenceProviderType, List<AlertProviderConfiguration>, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        +
        +
        Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
        +
        ModelSchema(String, String, String, String, String, PersistenceProviderType, List<AlertProviderConfiguration>) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        -
         
        +
        +
        Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
        +
        +
        ModelSchema(String, String, String, String, String, PersistenceProviderType, List<AlertProviderConfiguration>, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        +
        +
        Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
        +
        +
        ModelSchema(String, String, String, String, String, String, PersistenceProviderType, List<AlertProviderConfiguration>, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        +
        +
        Creates a model schema from a digital twin class, a message processor class, a message class, + a simulation processor class, an Azure Digital Twin Model name class, a persistence provider type, + and an alert provider configuration.
        +
        +
        ModelSchema(String, String, String, String, String, List<AlertProviderConfiguration>) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        +
        +
        Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
        +
        +
        ModelSchema(String, String, String, String, String, List<AlertProviderConfiguration>, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        +
        +
        Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
        +
        ModelSchema(String, String, String, String, List<AlertProviderConfiguration>) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        Creates a model schema from a digital twin class, a message processor class, a message class, and alert provider configurations.
        +
        ModelSchema(String, String, String, String, List<AlertProviderConfiguration>, boolean) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        +
        +
        Creates a model schema from a digital twin class, a message processor class, a message class, and + alert provider configurations.
        +
        ModelSchema(String, String, String, List<AlertProviderConfiguration>) - Constructor for class com.scaleoutsoftware.digitaltwin.core.ModelSchema
        Creates a model schema from a digital twin class, a message processor class, a message class, and @@ -575,10 +742,31 @@

        N

        O

        +
        ObjectDoesNotExist - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
        +
        +
        The object could not be retrieved because it was not found.
        +
        +
        ObjectPut - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
        +
        +
        The object was successfully added/updated.
        +
        +
        ObjectRemoved - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
        +
        +
        The object was removed successfully.
        +
        +
        ObjectRetrieved - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
        +
        +
        The object was successfully retrieved.
        +
        OneTime - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.TimerType
        This timer should trigger one time.
        +
        onInitSimulation(InitSimulationContext, T, Date) - Method in class com.scaleoutsoftware.digitaltwin.core.SimulationProcessor
        +
        +
        + Optional method that is called per-instance when a simulation is started.
        +
        onTimedMessage(String, T, ProcessingContext) - Method in interface com.scaleoutsoftware.digitaltwin.core.TimerHandler
        Callback to handle a timer message.
        @@ -607,7 +795,9 @@

        P

        Context object that allows the user to send a message to a DataSource.
        ProcessingContext() - Constructor for class com.scaleoutsoftware.digitaltwin.core.ProcessingContext
        -
         
        +
        +
        Default constructor.
        +
        ProcessingResult - Enum Class in com.scaleoutsoftware.digitaltwin.core
        The result from a message processor which indicates to update the state object or to ignore
        @@ -628,6 +818,10 @@

        P

        Processes simulation events for a real-time digital twin.
        +
        put(String, byte[]) - Method in interface com.scaleoutsoftware.digitaltwin.core.SharedData
        +
        +
        Put a new key/value mapping into the cache.
        +

        R

        @@ -635,6 +829,10 @@

        R

        This timer should reoccur on a schedule.
        +
        remove(String) - Method in interface com.scaleoutsoftware.digitaltwin.core.SharedData
        +
        +
        Remove a key/value mapping from the cache.
        +
        Running - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.SimulationStatus
        The simulation is running.
        @@ -643,6 +841,10 @@

        R

        Runs a simulation from the given startTime until the given endTime OR there is no more work to do.
        +
        runThisInstance() - Method in interface com.scaleoutsoftware.digitaltwin.core.SimulationController
        +
        +
        Run this instance during this simulation step.
        +

        S

        @@ -698,6 +900,10 @@

        S

        Set the next simulation time in milliseconds.
        +
        SharedData - Interface in com.scaleoutsoftware.digitaltwin.core
        +
        +
        SharedData is used to access a model's, or globally, shared cache.
        +
        SimulationController - Interface in com.scaleoutsoftware.digitaltwin.core
        The SimulationController interface is used to interact with the running DigitalTwin simulation.
        @@ -713,7 +919,9 @@

        S

        Processes simulation events for a digital twin.
        SimulationProcessor() - Constructor for class com.scaleoutsoftware.digitaltwin.core.SimulationProcessor
        -
         
        +
        +
        Default constructor.
        +
        SimulationStatus - Enum Class in com.scaleoutsoftware.digitaltwin.core
        The status of a simulation.
        @@ -793,7 +1001,9 @@

        T

        U

        Unconfigured - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
        -
         
        +
        +
        Enum for an unconfigured PersistenceProvider
        +
        UnexpectedChangeInConfiguration - Enum constant in enum class com.scaleoutsoftware.digitaltwin.core.SimulationStatus
        There was a runtime-change of simulation configuration.
        @@ -825,6 +1035,10 @@

        U

        V

        +
        valueOf(String) - Static method in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
        +
        +
        Returns the enum constant of this class with the specified name.
        +
        valueOf(String) - Static method in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
        Returns the enum constant of this class with the specified name.
        @@ -849,6 +1063,11 @@

        V

        Returns the enum constant of this class with the specified name.
        +
        values() - Static method in enum class com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
        +
        +
        Returns an array containing the constants of this enum class, in +the order they are declared.
        +
        values() - Static method in enum class com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType
        Returns an array containing the constants of this enum class, in @@ -890,6 +1109,10 @@

        W

        Instantiate the workbench.
        +
        Workbench(int) - Constructor for class com.scaleoutsoftware.digitaltwin.development.Workbench
        +
        +
        Instantiate the workbench.
        +
        WorkbenchException - Exception in com.scaleoutsoftware.digitaltwin.development
        A Workbench exception indicates that a real-time or simulated twin caused an exception.
        diff --git a/docs/index.html b/docs/index.html index efbce74..c1028e2 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2,7 +2,7 @@ -Overview (digitaltwin-core-docs 3.0.4 API) +Overview (digitaltwin-core-docs 3.0.5 API) @@ -47,7 +47,7 @@
        -

        digitaltwin-core-docs 3.0.4 API

        +

        digitaltwin-core-docs 3.0.5 API

        Packages
        diff --git a/docs/member-search-index.js b/docs/member-search-index.js index 13931aa..a4c179e 100644 --- a/docs/member-search-index.js +++ b/docs/member-search-index.js @@ -1 +1 @@ -memberSearchIndex = [{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addAlertProvider(String, AlertProviderConfiguration)","u":"addAlertProvider(java.lang.String,com.scaleoutsoftware.digitaltwin.core.AlertProviderConfiguration)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addInstance(String, String, DigitalTwinBase)","u":"addInstance(java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addRealTimeModel(String, MessageProcessor, Class, Class)","u":"addRealTimeModel(java.lang.String,com.scaleoutsoftware.digitaltwin.core.MessageProcessor,java.lang.Class,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addSimulationModel(String, MessageProcessor, SimulationProcessor, Class, Class)","u":"addSimulationModel(java.lang.String,com.scaleoutsoftware.digitaltwin.core.MessageProcessor,com.scaleoutsoftware.digitaltwin.core.SimulationProcessor,java.lang.Class,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"AlertMessage(String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"AlertMessage(String, String, String, HashMap)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.util.HashMap)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"AlertProviderConfiguration(String, String, String, String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"AzureDigitalTwinsService"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"close()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"createInstance(String, String, T)","u":"createInstance(java.lang.String,java.lang.String,T)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"createInstanceFromPersistenceStore(String, String)","u":"createInstanceFromPersistenceStore(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"createInstanceFromPersistenceStore(String, String, T)","u":"createInstanceFromPersistenceStore(java.lang.String,java.lang.String,T)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"delay(Duration)","u":"delay(java.time.Duration)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"deleteInstance(String, String)","u":"deleteInstance(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"deleteThisInstance()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"DigitalTwinBase()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"DigitalTwinTimerMessage(String, String, int, String, TimerType)","u":"%3Cinit%3E(java.lang.String,java.lang.String,int,java.lang.String,com.scaleoutsoftware.digitaltwin.core.TimerType)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"emitTelemetry(String, byte[])","u":"emitTelemetry(java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"emitTelemetry(String, Object)","u":"emitTelemetry(java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"EndTimeReached"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"Enqueued"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedInternalError"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedNoSuchTimer"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedTimerAlreadyExists"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedTooManyTimers"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"fromOrdinal(int)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"fromOrdinal(int)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"fromString(String)","u":"fromString(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"generateModelSchema(String)","u":"generateModelSchema(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"generateModelSchema(String, String)","u":"generateModelSchema(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getAlertMessages(String, String)","u":"getAlertMessages(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getAlertProviders()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getAlertProviderType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getAssemblyName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getAzureDigitalTwinModelName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getCurrentTime()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getDataSourceId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getDigitalTwinModel()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getEntityId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"getId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"getId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageFactory","l":"getIncomingMessages()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstance(String, String)","u":"getInstance(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstanceAsync(String, String)","u":"getInstanceAsync(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstanceIds(String)","u":"getInstanceIds(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstanceIdsAsync(String)","u":"getInstanceIdsAsync(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getInstances(String)","u":"getInstances(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getIntegrationKey()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getLoggedMessages(String, long)","u":"getLoggedMessages(java.lang.String,long)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getMessage()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"LogMessage","l":"getMessage()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"getMessage()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getMessageProcessorType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getMessageType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"getModel()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"getModel()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getModelName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getModelType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"getNextSimulationTimeMs()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getOptionalTwinInstanceProperties()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getPersistenceProvider()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getPersistenceProvider()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getProperty(String, String, String, Class)","u":"getProperty(java.lang.String,java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getPropertyAsync(String, String, String, Class)","u":"getPropertyAsync(java.lang.String,java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getPropertyMap(String)","u":"getPropertyMap(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getPropertyMapAsync(String)","u":"getPropertyMapAsync(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getProviderType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getRoutingKey()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getRtdtProperty(String, String, Class)","u":"getRtdtProperty(java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getRtdtPropertyAsync(String, String, Class)","u":"getRtdtPropertyAsync(java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getSeverity()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"LogMessage","l":"getSeverity()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getSimulationController()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getSimulationProcessorType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"getSimulationTimeIncrement()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"SimulationStep","l":"getStatus()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"SimulationStep","l":"getTime()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getTime()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerHandlerClass()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTimerId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerIntervalMs()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTimerName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTimerType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerType()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"LogMessage","l":"getTimestamp()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getTitle()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTwinId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getURL()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"Handled"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"Id"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"init(InitContext)","u":"init(com.scaleoutsoftware.digitaltwin.core.InitContext)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"InitContext()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"initializeSimulation(long, long, long)","u":"initializeSimulation(long,long,long)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"InstanceRequestedStop"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"isActive()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"logMessage(Level, String)","u":"logMessage(java.util.logging.Level,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessor","l":"MessageProcessor()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessorBase","l":"MessageProcessorBase()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"Model"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, PersistenceProviderType, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, String, PersistenceProviderType, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"NextSimulationTime"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"NoRemainingWork"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"NotHandled"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"NotSet"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"NoUpdate"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"OneTime"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerHandler","l":"onTimedMessage(String, T, ProcessingContext)","u":"onTimedMessage(java.lang.String,T,com.scaleoutsoftware.digitaltwin.core.ProcessingContext)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"peek()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"persistenceEnabled()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"ProcessingContext()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessor","l":"processMessages(ProcessingContext, T, Iterable)","u":"processMessages(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,java.lang.Iterable)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessor","l":"processMessages(ProcessingContext, T, MessageFactory)","u":"processMessages(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,com.scaleoutsoftware.digitaltwin.core.MessageFactory)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessorBase","l":"processMessages(ProcessingContext, T, MessageFactory)","u":"processMessages(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,com.scaleoutsoftware.digitaltwin.core.MessageFactory)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationProcessor","l":"processModel(ProcessingContext, T, Date)","u":"processModel(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,java.util.Date)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"Recurring"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"Running"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"runSimulation(long, long, double, long)","u":"runSimulation(long,long,double,long)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"send(String, String, List)","u":"send(java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendAlert(String, AlertMessage)","u":"sendAlert(java.lang.String,com.scaleoutsoftware.digitaltwin.core.AlertMessage)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDataSource(byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDataSource(List)","u":"sendToDataSource(java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDataSource(Object)","u":"sendToDataSource(java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, byte[])","u":"sendToDigitalTwin(java.lang.String,java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, List)","u":"sendToDigitalTwin(java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, Object)","u":"sendToDigitalTwin(java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, String)","u":"sendToDigitalTwin(java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"setNextSimulationTime(long)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"SimulationEventResult","l":"SimulationEventResult()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationProcessor","l":"SimulationProcessor()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"simulationSupportEnabled()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"SQLite"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"SQLServer"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"startTimer(String, Duration, TimerType, TimerHandler)","u":"startTimer(java.lang.String,java.time.Duration,com.scaleoutsoftware.digitaltwin.core.TimerType,com.scaleoutsoftware.digitaltwin.core.TimerHandler)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"startTimer(String, Duration, TimerType, TimerHandler)","u":"startTimer(java.lang.String,java.time.Duration,com.scaleoutsoftware.digitaltwin.core.TimerType,com.scaleoutsoftware.digitaltwin.core.TimerHandler)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"step()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"stopSimulation()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"stopTimer(String)","u":"stopTimer(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"Success"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"TimerHandlers"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"TimerMetadata(TimerHandler, TimerType, long, int)","u":"%3Cinit%3E(com.scaleoutsoftware.digitaltwin.core.TimerHandler,com.scaleoutsoftware.digitaltwin.core.TimerType,long,int)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"toString()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"toString()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"Unconfigured"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"UnexpectedChangeInConfiguration"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"UpdateDigitalTwin"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updateProperty(String, String, String, Object)","u":"updateProperty(java.lang.String,java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updatePropertyAsync(String, String, String, Object)","u":"updatePropertyAsync(java.lang.String,java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updateRtdtProperty(String, String, Object)","u":"updateRtdtProperty(java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updateRtdtPropertyAsync(String, String, Object)","u":"updateRtdtPropertyAsync(java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"UserRequested"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"Workbench()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"WorkbenchException(Exception)","u":"%3Cinit%3E(java.lang.Exception)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"WorkbenchException(String)","u":"%3Cinit%3E(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"WorkbenchException(String, Exception)","u":"%3Cinit%3E(java.lang.String,java.lang.Exception)"}];updateSearchResults(); \ No newline at end of file +memberSearchIndex = [{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addAlertProvider(String, AlertProviderConfiguration)","u":"addAlertProvider(java.lang.String,com.scaleoutsoftware.digitaltwin.core.AlertProviderConfiguration)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addGlobalModelData(String, byte[])","u":"addGlobalModelData(java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addInstance(String, String, DigitalTwinBase)","u":"addInstance(java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addRealTimeModel(String, MessageProcessor, Class, Class)","u":"addRealTimeModel(java.lang.String,com.scaleoutsoftware.digitaltwin.core.MessageProcessor,java.lang.Class,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addSharedModelData(String, String, byte[])","u":"addSharedModelData(java.lang.String,java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"addSimulationModel(String, MessageProcessor, SimulationProcessor, Class, Class)","u":"addSimulationModel(java.lang.String,com.scaleoutsoftware.digitaltwin.core.MessageProcessor,com.scaleoutsoftware.digitaltwin.core.SimulationProcessor,java.lang.Class,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"AlertMessage(String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"AlertMessage(String, String, String, HashMap)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.util.HashMap)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"AlertProviderConfiguration(String, String, String, String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"AzureDigitalTwinsService"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"CacheCleared"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SharedData","l":"clear()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"close()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"CosmosDb"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"createInstance(String, String, T)","u":"createInstance(java.lang.String,java.lang.String,T)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"createInstanceFromPersistenceStore(String, String)","u":"createInstanceFromPersistenceStore(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"createInstanceFromPersistenceStore(String, String, T)","u":"createInstanceFromPersistenceStore(java.lang.String,java.lang.String,T)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"delay(Duration)","u":"delay(java.time.Duration)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"delayIndefinitely()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"deleteInstance(String, String)","u":"deleteInstance(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"deleteThisInstance()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"DigitalTwinBase()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"DigitalTwinTimerMessage(String, String, int, String, TimerType)","u":"%3Cinit%3E(java.lang.String,java.lang.String,int,java.lang.String,com.scaleoutsoftware.digitaltwin.core.TimerType)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"DynamoDb"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"emitTelemetry(String, byte[])","u":"emitTelemetry(java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"emitTelemetry(String, Object)","u":"emitTelemetry(java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"EndTimeReached"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"Enqueued"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedInternalError"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedNoSuchTimer"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedTimerAlreadyExists"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"FailedTooManyTimers"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"fromOrdinal(int)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"fromOrdinal(int)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"fromString(String)","u":"fromString(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"generateModelSchema(String)","u":"generateModelSchema(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"generateModelSchema(String, String)","u":"generateModelSchema(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SharedData","l":"get(String)","u":"get(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getAlertMessages(String, String)","u":"getAlertMessages(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getAlertProviders()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getAlertProviderType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getAssemblyName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getAzureDigitalTwinModelName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getCurrentTime()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getDataSourceId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getDigitalTwinModel()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getEntityId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getEntryPoint()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"getId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"getId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageFactory","l":"getIncomingMessages()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstance(String, String)","u":"getInstance(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstanceAsync(String, String)","u":"getInstanceAsync(java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstanceIds(String)","u":"getInstanceIds(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getInstanceIdsAsync(String)","u":"getInstanceIdsAsync(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getInstances(String)","u":"getInstances(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getIntegrationKey()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheResult","l":"getKey()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getLoggedMessages(String, long)","u":"getLoggedMessages(java.lang.String,long)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getMessage()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"LogMessage","l":"getMessage()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"getMessage()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getMessageProcessorType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getMessageType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"getModel()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"getModel()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getModelName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getModelType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"getName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"getNextSimulationTimeMs()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getOptionalTwinInstanceProperties()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getPersistenceProvider()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getPersistenceProvider()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getProperty(String, String, String, Class)","u":"getProperty(java.lang.String,java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getPropertyAsync(String, String, String, Class)","u":"getPropertyAsync(java.lang.String,java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getPropertyMap(String)","u":"getPropertyMap(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getPropertyMapAsync(String)","u":"getPropertyMapAsync(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getProviderType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getRoutingKey()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getRtdtProperty(String, String, Class)","u":"getRtdtProperty(java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"getRtdtPropertyAsync(String, String, Class)","u":"getRtdtPropertyAsync(java.lang.String,java.lang.String,java.lang.Class)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"getServiceOrdinalValue()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getSeverity()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"LogMessage","l":"getSeverity()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"getSharedGlobalData()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitSimulationContext","l":"getSharedGlobalData()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getSharedGlobalData()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getSharedGlobalData()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"getSharedModelData()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitSimulationContext","l":"getSharedModelData()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getSharedModelData()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getSharedModelData(String)","u":"getSharedModelData(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"getSimulationController()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"getSimulationProcessorType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"getSimulationStartTime()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"getSimulationTimeIncrement()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheResult","l":"getStatus()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"SimulationStep","l":"getStatus()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"SimulationStep","l":"getTime()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"getTime()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerHandlerClass()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTimerId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerIntervalMs()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTimerName()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTimerType()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"getTimerType()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"LogMessage","l":"getTimestamp()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"getTitle()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinTimerMessage","l":"getTwinId()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"getURL()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheResult","l":"getValue()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"Handled"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"Id"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"init(InitContext)","u":"init(com.scaleoutsoftware.digitaltwin.core.InitContext)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"InitContext()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"initializeSimulation(long, long, long)","u":"initializeSimulation(long,long,long)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"InstanceRequestedStop"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"isActive()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"logMessage(Level, String)","u":"logMessage(java.util.logging.Level,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessor","l":"MessageProcessor()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessorBase","l":"MessageProcessorBase()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"messageRecordingEnabled()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"Model"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, List, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.util.List,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, PersistenceProviderType, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, PersistenceProviderType, List, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, String, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, String, List, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.util.List,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, String, PersistenceProviderType, List)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, String, PersistenceProviderType, List, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"ModelSchema(String, String, String, String, String, String, PersistenceProviderType, List, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType,java.util.List,boolean)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"NextSimulationTime"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"NoRemainingWork"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"NotHandled"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"NotSet"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"NoUpdate"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"ObjectDoesNotExist"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"ObjectPut"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"ObjectRemoved"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"ObjectRetrieved"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"OneTime"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationProcessor","l":"onInitSimulation(InitSimulationContext, T, Date)","u":"onInitSimulation(com.scaleoutsoftware.digitaltwin.core.InitSimulationContext,T,java.util.Date)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerHandler","l":"onTimedMessage(String, T, ProcessingContext)","u":"onTimedMessage(java.lang.String,T,com.scaleoutsoftware.digitaltwin.core.ProcessingContext)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"peek()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"persistenceEnabled()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"ProcessingContext()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessor","l":"processMessages(ProcessingContext, T, Iterable)","u":"processMessages(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,java.lang.Iterable)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessor","l":"processMessages(ProcessingContext, T, MessageFactory)","u":"processMessages(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,com.scaleoutsoftware.digitaltwin.core.MessageFactory)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"MessageProcessorBase","l":"processMessages(ProcessingContext, T, MessageFactory)","u":"processMessages(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,com.scaleoutsoftware.digitaltwin.core.MessageFactory)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationProcessor","l":"processModel(ProcessingContext, T, Date)","u":"processModel(com.scaleoutsoftware.digitaltwin.core.ProcessingContext,T,java.util.Date)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SharedData","l":"put(String, byte[])","u":"put(java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"Recurring"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SharedData","l":"remove(String)","u":"remove(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"Running"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"runSimulation(long, long, double, long)","u":"runSimulation(long,long,double,long)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"runThisInstance()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"send(String, String, List)","u":"send(java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendAlert(String, AlertMessage)","u":"sendAlert(java.lang.String,com.scaleoutsoftware.digitaltwin.core.AlertMessage)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDataSource(byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDataSource(List)","u":"sendToDataSource(java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDataSource(Object)","u":"sendToDataSource(java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, byte[])","u":"sendToDigitalTwin(java.lang.String,java.lang.String,byte[])"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, List)","u":"sendToDigitalTwin(java.lang.String,java.lang.String,java.util.List)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, Object)","u":"sendToDigitalTwin(java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"sendToDigitalTwin(String, String, String)","u":"sendToDigitalTwin(java.lang.String,java.lang.String,java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"setNextSimulationTime(long)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"SimulationEventResult","l":"SimulationEventResult()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationProcessor","l":"SimulationProcessor()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ModelSchema","l":"simulationSupportEnabled()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"SQLite"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"SQLServer"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"InitContext","l":"startTimer(String, Duration, TimerType, TimerHandler)","u":"startTimer(java.lang.String,java.time.Duration,com.scaleoutsoftware.digitaltwin.core.TimerType,com.scaleoutsoftware.digitaltwin.core.TimerHandler)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"startTimer(String, Duration, TimerType, TimerHandler)","u":"startTimer(java.lang.String,java.time.Duration,com.scaleoutsoftware.digitaltwin.core.TimerType,com.scaleoutsoftware.digitaltwin.core.TimerHandler)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"step()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationController","l":"stopSimulation()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingContext","l":"stopTimer(String)","u":"stopTimer(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"Success"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"DigitalTwinBase","l":"TimerHandlers"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerMetadata","l":"TimerMetadata(TimerHandler, TimerType, long, int)","u":"%3Cinit%3E(com.scaleoutsoftware.digitaltwin.core.TimerHandler,com.scaleoutsoftware.digitaltwin.core.TimerType,long,int)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertMessage","l":"toString()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"AlertProviderConfiguration","l":"toString()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"Unconfigured"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"UnexpectedChangeInConfiguration"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"UpdateDigitalTwin"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updateProperty(String, String, String, Object)","u":"updateProperty(java.lang.String,java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updatePropertyAsync(String, String, String, Object)","u":"updatePropertyAsync(java.lang.String,java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updateRtdtProperty(String, String, Object)","u":"updateRtdtProperty(java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProvider","l":"updateRtdtPropertyAsync(String, String, Object)","u":"updateRtdtPropertyAsync(java.lang.String,java.lang.String,java.lang.Object)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"UserRequested"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"CacheOperationStatus","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"PersistenceProviderType","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"ProcessingResult","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SendingResult","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"SimulationStatus","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerActionResult","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.core","c":"TimerType","l":"values()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"Workbench()","u":"%3Cinit%3E()"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"Workbench","l":"Workbench(int)","u":"%3Cinit%3E(int)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"WorkbenchException(Exception)","u":"%3Cinit%3E(java.lang.Exception)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"WorkbenchException(String)","u":"%3Cinit%3E(java.lang.String)"},{"p":"com.scaleoutsoftware.digitaltwin.development","c":"WorkbenchException","l":"WorkbenchException(String, Exception)","u":"%3Cinit%3E(java.lang.String,java.lang.Exception)"}];updateSearchResults(); \ No newline at end of file diff --git a/docs/overview-summary.html b/docs/overview-summary.html index f782a93..0832a3f 100644 --- a/docs/overview-summary.html +++ b/docs/overview-summary.html @@ -2,7 +2,7 @@ -digitaltwin-core-docs 3.0.4 API +digitaltwin-core-docs 3.0.5 API diff --git a/docs/overview-tree.html b/docs/overview-tree.html index 1d46006..e355db6 100644 --- a/docs/overview-tree.html +++ b/docs/overview-tree.html @@ -2,7 +2,7 @@ -Class Hierarchy (digitaltwin-core-docs 3.0.4 API) +Class Hierarchy (digitaltwin-core-docs 3.0.5 API) @@ -93,8 +93,11 @@

        Class Hierarchy

        Interface Hierarchy

        @@ -106,6 +109,7 @@

        Enum Class Hierarchy

        • java.lang.Enum<E> (implements java.lang.Comparable<T>, java.lang.constant.Constable, java.io.Serializable)
            +
          • com.scaleoutsoftware.digitaltwin.core.CacheOperationStatus
          • com.scaleoutsoftware.digitaltwin.core.PersistenceProviderType (implements java.io.Serializable)
          • com.scaleoutsoftware.digitaltwin.core.ProcessingResult
          • com.scaleoutsoftware.digitaltwin.core.SendingResult
          • diff --git a/docs/serialized-form.html b/docs/serialized-form.html index 6f04e5a..86e2438 100644 --- a/docs/serialized-form.html +++ b/docs/serialized-form.html @@ -2,7 +2,7 @@ -Serialized Form (digitaltwin-core-docs 3.0.4 API) +Serialized Form (digitaltwin-core-docs 3.0.5 API) diff --git a/docs/type-search-index.js b/docs/type-search-index.js index 1ff095a..3146686 100644 --- a/docs/type-search-index.js +++ b/docs/type-search-index.js @@ -1 +1 @@ -typeSearchIndex = [{"p":"com.scaleoutsoftware.digitaltwin.core","l":"AlertMessage"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"AlertProviderConfiguration"},{"l":"All Classes and Interfaces","u":"allclasses-index.html"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"DigitalTwinBase"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"DigitalTwinTimerMessage"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"InitContext"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"LogMessage"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"MessageFactory"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"MessageProcessor"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"MessageProcessorBase"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"ModelSchema"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"PersistenceProvider"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"PersistenceProviderType"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"ProcessingContext"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"ProcessingResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SendingResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SimulationController"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"SimulationEventResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SimulationProcessor"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SimulationStatus"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"SimulationStep"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerActionResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerHandler"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerMetadata"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerType"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"Workbench"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"WorkbenchException"}];updateSearchResults(); \ No newline at end of file +typeSearchIndex = [{"p":"com.scaleoutsoftware.digitaltwin.core","l":"AlertMessage"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"AlertProviderConfiguration"},{"l":"All Classes and Interfaces","u":"allclasses-index.html"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"CacheOperationStatus"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"CacheResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"DigitalTwinBase"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"DigitalTwinTimerMessage"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"InitContext"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"InitSimulationContext"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"LogMessage"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"MessageFactory"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"MessageProcessor"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"MessageProcessorBase"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"ModelSchema"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"PersistenceProvider"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"PersistenceProviderType"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"ProcessingContext"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"ProcessingResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SendingResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SharedData"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SimulationController"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"SimulationEventResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SimulationProcessor"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"SimulationStatus"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"SimulationStep"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerActionResult"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerHandler"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerMetadata"},{"p":"com.scaleoutsoftware.digitaltwin.core","l":"TimerType"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"Workbench"},{"p":"com.scaleoutsoftware.digitaltwin.development","l":"WorkbenchException"}];updateSearchResults(); \ No newline at end of file