From 9b6443a8b0535aa4575354a4c924714dc8f593aa Mon Sep 17 00:00:00 2001
From: Viktor Vorobev <vorobev@in.tum.de>
Date: Tue, 20 Jun 2023 14:07:07 +0000
Subject: [PATCH] Merged in NRRPLT-8926-mqtt-prefix (pull request #49)

[NRRPLT-8926] MQTT prefix

* [NRRPLT-8926] Add MQTTPrefix alongside with simulationID

* [NRRPLT-8926] Fix MQTTPrefix order

* [NRRPLT-8926] Do not add an empty prefix

* [NRRPLT-8931] Add ws/wss parameter to config

* Merge branch 'NRRPLT-8931-wss' into NRRPLT-8926-mqtt-prefix

* Merge remote-tracking branch 'origin/development' into NRRPLT-8926-mqtt-prefix


Approved-by: Sandro Weber
---
 .../experiment-list/simulation-details.js     |  5 ++-
 .../experiment-time-box.js                    |  1 -
 .../experiment-workbench-service.js           | 32 ++++++++++++-------
 .../experiment-workbench.js                   | 21 +++++++-----
 4 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/src/components/experiment-list/simulation-details.js b/src/components/experiment-list/simulation-details.js
index 7463816..fba5b18 100644
--- a/src/components/experiment-list/simulation-details.js
+++ b/src/components/experiment-list/simulation-details.js
@@ -53,7 +53,10 @@ class SimulationDetails extends React.Component {
    * Opens experiment workbench and sets the running simulation ID in ExperimentWorkbenchService
    */
   joinSimulation(simulationInfo) {
-    ExperimentWorkbenchService.instance.simulationID = simulationInfo.runningSimulation.simulationID;
+    ExperimentWorkbenchService.instance.simulationInfo = {
+      ID: simulationInfo.runningSimulation.simulationID,
+      MQTTPrefix: simulationInfo.runningSimulation.MQTTPrefix
+    };
     ServerResourcesService.instance.getServerConfig(simulationInfo.server).then((serverConfig) => {
       ExperimentWorkbenchService.instance.serverURL = serverConfig['nrp-services'];
       this.props.history.push({
diff --git a/src/components/experiment-workbench/experiment-time-box.js b/src/components/experiment-workbench/experiment-time-box.js
index f2694f0..1fb36b5 100644
--- a/src/components/experiment-workbench/experiment-time-box.js
+++ b/src/components/experiment-workbench/experiment-time-box.js
@@ -32,7 +32,6 @@ export default class ExperimentTimeBox extends React.Component {
       break;
     }
     this.state = {
-      simulationID: undefined,
       timeToken: null,
       simulationTime: undefined
     };
diff --git a/src/components/experiment-workbench/experiment-workbench-service.js b/src/components/experiment-workbench/experiment-workbench-service.js
index dc8817c..4a9edc0 100644
--- a/src/components/experiment-workbench/experiment-workbench-service.js
+++ b/src/components/experiment-workbench/experiment-workbench-service.js
@@ -15,7 +15,7 @@ class ExperimentWorkbenchService extends EventEmitter {
     if (enforcer !== SINGLETON_ENFORCER) {
       throw new Error('Use ' + this.constructor.name + '.instance');
     }
-    this._simulationID = undefined;
+    this._simulationInfo = undefined;
     this._serverURL = undefined;
     this._errorToken = undefined;
     this._statusToken = undefined;
@@ -53,17 +53,23 @@ class ExperimentWorkbenchService extends EventEmitter {
     console.info(['ExperimentWorkbenchService - serverURL', this._serverURL]);
   }
 
-  get simulationID() {
-    return this._simulationID;
+  /**
+   * Returns the simulation MQTT description
+   * @returns {object} the simulation info
+   * @returns {string} simulationInfo.ID the simulation ID
+   * @returns {string} simulationInfo.MQTTPrefix the simulation MQTT Prefix
+   */
+  get simulationInfo() {
+    return this._simulationInfo;
   }
-  set simulationID(simulationID) {
-    this._simulationID = simulationID;
-    console.info(['ExperimentWorkbenchService - simulationID', this._simulationID]);
+  set simulationInfo(simulationInfo) {
+    this._simulationInfo = simulationInfo;
+    console.info(['ExperimentWorkbenchService - simulationInfo', this._simulationInfo]);
     ExperimentWorkbenchService.instance.emit(
       ExperimentWorkbenchService.EVENTS.SIMULATION_SET,
-      this._simulationID
+      this._simulationInfo
     );
-    this.setTopics(this._simulationID);
+    this.setTopics(this._simulationInfo);
   }
 
   /**
@@ -74,7 +80,7 @@ class ExperimentWorkbenchService extends EventEmitter {
     return MqttClientService.instance.isConnected();
   }
 
-  setTopics = (simulationID) => {
+  setTopics = (simulationInfo) => {
     if (this._errorToken) {
       MqttClientService.instance.unsubscribe(this._errorToken);
       this._errorToken = undefined;
@@ -83,9 +89,11 @@ class ExperimentWorkbenchService extends EventEmitter {
       MqttClientService.instance.unsubscribe(this._statusToken);
       this._statusToken = undefined;
     }
-    if (simulationID !== undefined) {
-      const topicBase = MqttClientService.instance.getConfig().mqtt.topics.base + '/'
-        + simulationID + '/';
+    if (simulationInfo !== undefined) {
+      const mqttTopics = MqttClientService.instance.getConfig().mqtt.topics;
+      const topicBase = simulationInfo.MQTTPrefix ?
+        simulationInfo.MQTTPrefix + '/' + mqttTopics.base + '/' + simulationInfo.ID + '/' :
+        mqttTopics.base + '/' + simulationInfo.ID + '/';
       // assign error MQTT topic
       const errorTopic = topicBase + MqttClientService.instance.getConfig().mqtt.topics.errors;
       const errorToken = MqttClientService.instance.subscribeToTopic(errorTopic, this.errorMsgHandler);
diff --git a/src/components/experiment-workbench/experiment-workbench.js b/src/components/experiment-workbench/experiment-workbench.js
index 3fbe88c..58bbed9 100644
--- a/src/components/experiment-workbench/experiment-workbench.js
+++ b/src/components/experiment-workbench/experiment-workbench.js
@@ -212,7 +212,9 @@ class ExperimentWorkbench extends React.Component {
 
   async componentDidMount() {
     // Get the simulation ID from ExperimentWorkbenchService, if is defined (for joining the simulation)
-    this.state.runningSimulationID = ExperimentWorkbenchService.instance.simulationID;
+    if (ExperimentWorkbenchService.instance.simulationInfo !== undefined) {
+      this.state.runningSimulationID = ExperimentWorkbenchService.instance.simulationInfo.ID;
+    }
 
     // Update simulation state, if it is defined
     if (this.state.runningSimulationID !== undefined) {
@@ -255,7 +257,7 @@ class ExperimentWorkbench extends React.Component {
       this.onUpdateServerAvailability
     );
     // Remove the simulation when we leave the workbench
-    ExperimentWorkbenchService.instance.simulationID = undefined;
+    ExperimentWorkbenchService.instance.simulationInfo = undefined;
   }
 
   /**
@@ -283,9 +285,9 @@ class ExperimentWorkbench extends React.Component {
           DialogService.instance.progressNotification({
             message: 'The experiment is ' + this.state.simulationState
           });
-          // clear simulationID for the finilized experiments
+          // clear simulationInfo for the finilized experiments
           if (EXPERIMENT_FINAL_STATE.includes(this.state.simulationState)) {
-            ExperimentWorkbenchService.instance.simulationID = undefined;
+            ExperimentWorkbenchService.instance.simulationInfo = undefined;
             this.setState({ runningSimulationID: undefined });
           }
         }
@@ -320,7 +322,10 @@ class ExperimentWorkbench extends React.Component {
         const simInfo = await simRespose['simulation'].json();
         // TODO: get proper simulation information
         if (simInfo) {
-          ExperimentWorkbenchService.instance.simulationID = simInfo.simulationID;
+          ExperimentWorkbenchService.instance.simulationInfo = {
+            ID: simInfo.simulationID,
+            MQTTPrefix: simInfo.MQTTPrefix
+          };
           this.setState({ runningSimulationID: simInfo.simulationID });
           // get the simulationState from MQTT only
           this.setState({ simStateLoading: true });
@@ -361,7 +366,7 @@ class ExperimentWorkbench extends React.Component {
     await this.setSimulationState(newState).then(() => {
       if (this.state.simulationState === EXPERIMENT_STATE.STOPPED) {
         this.setState({ runningSimulationID: undefined });
-        ExperimentWorkbenchService.instance.simulationID = undefined;
+        ExperimentWorkbenchService.instance.simulationInfo = undefined;
       }
     });
   }
@@ -379,8 +384,8 @@ class ExperimentWorkbench extends React.Component {
         if (simInfo.state === EXPERIMENT_STATE.STOPPED) {
           this.setState({ simulationState: simInfo.state });
           this.setState({ simStateLoading: false });
-          // clear simulationID for the finilized experiments
-          ExperimentWorkbenchService.instance.simulationID = undefined;
+          // clear simulationInfo for the finilized experiments
+          ExperimentWorkbenchService.instance.simulationInfo = undefined;
           this.setState({ runningSimulationID: undefined });
         }
       });
-- 
GitLab