Merge "Add data saving"
diff --git a/ui-react/src/api/LoopCache.js b/ui-react/src/api/LoopCache.js
index 4c8f68c..b854c7c 100644
--- a/ui-react/src/api/LoopCache.js
+++ b/ui-react/src/api/LoopCache.js
@@ -29,13 +29,11 @@
 	}
 
 	updateMicroServiceProperties(type, newMsProperties) {
-		if (newMsProperties["name"] === type) {
 			for (var policy in this.loopJsonCache["microServicePolicies"]) {
 				if (this.loopJsonCache["microServicePolicies"][policy]["name"] === type) {
-					this.loopJsonCache["microServicePolicies"][policy] = newMsProperties;
+					this.loopJsonCache["microServicePolicies"][policy]["properties"] = newMsProperties;
 				}
 			}
-		}
 	}
 
 	updateGlobalProperties(newGlobalProperties) {
@@ -51,49 +49,47 @@
 	}
 
 	getOperationalPolicyConfigurationJson() {
-		return JSON.parse(JSON.stringify(this.loopJsonCache["operationalPolicies"]["0"]["configurationsJson"]));
+		return this.loopJsonCache["operationalPolicies"]["0"]["configurationsJson"];
 	}
 
 	getOperationalPolicies() {
-		return JSON.parse(JSON.stringify(this.loopJsonCache["operationalPolicies"]));
+		return this.loopJsonCache["operationalPolicies"];
 	}
 
 	getGlobalProperties() {
-		return JSON.parse(JSON.stringify(this.loopJsonCache["globalPropertiesJson"]));
+		return this.loopJsonCache["globalPropertiesJson"];
 	}
 
 	getDcaeDeploymentProperties() {
-		return JSON.parse(JSON.stringify(this.loopJsonCache["globalPropertiesJson"]["dcaeDeployParameters"]));
+		return this.loopJsonCache["globalPropertiesJson"]["dcaeDeployParameters"];
 	}
 
-	getMicroServicesJsonForType(type) {
-		var msProperties = this.loopJsonCache["microServicePolicies"];
+	getMicroServicePolicies() {
+		return this.loopJsonCache["microServicePolicies"];
+	}
+
+	getMicroServiceForName(name) {
+		var msProperties=this.getMicroServicePolicies();
 		for (var policy in msProperties) {
-			if (msProperties[policy]["name"] === type) {
-				return JSON.parse(JSON.stringify(msProperties[policy]));
+			if (msProperties[policy]["name"] === name) {
+				return msProperties[policy];
 			}
 		}
 		return null;
 	}
 
-	getMicroServiceProperties(type) {
-		var msProperties = this.loopJsonCache["microServicePolicies"];
-		for (var policy in msProperties) {
-			if (msProperties[policy]["name"] === type) {
-				if (msProperties[policy]["properties"] !== null && msProperties[policy]["properties"] !== undefined) {
-					return JSON.parse(JSON.stringify(msProperties[policy]["properties"]));
-				}
-			}
+	getMicroServicePropertiesForName(name) {
+		var msConfig = this.getMicroServiceForName(name);
+		if (msConfig !== null) {
+			return msConfig["properties"];
 		}
 		return null;
 	}
 
-	getMicroServiceJsonRepresentationForType(type) {
-		var msProperties = this.loopJsonCache["microServicePolicies"];
-		for (var policy in msProperties) {
-			if (msProperties[policy]["name"] === type) {
-				return JSON.parse(JSON.stringify(msProperties[policy]["jsonRepresentation"]));
-			}
+	getMicroServiceJsonRepresentationForName(name) {
+		var msConfig = this.getMicroServiceForName(name);
+		if (msConfig !== null) {
+			return msConfig["jsonRepresentation"];
 		}
 		return null;
 	}
diff --git a/ui-react/src/api/LoopService.js b/ui-react/src/api/LoopService.js
index fa7cd2e..020a3bf 100644
--- a/ui-react/src/api/LoopService.js
+++ b/ui-react/src/api/LoopService.js
@@ -42,7 +42,7 @@
 		return fetch('/restservices/clds/v2/loop/' + loopName, {
 			method: 'GET',
 			headers: {
-				"Content-Type": "application/json"
+				"Content-Type": "application/json",
 			},
 			credentials: 'same-origin',
 		})
@@ -64,7 +64,7 @@
 	static getSvg(loopName) {
 		return fetch('/restservices/clds/v2/loop/svgRepresentation/' + loopName, {
 			method: 'GET',
-			credentials: 'same-origin',			
+			credentials: 'same-origin',
 		})
 			.then(function (response) {
 				console.debug("svgRepresentation response received: ", response.status);
@@ -80,4 +80,28 @@
 				return "";
 			});
 	}
+
+	static setMicroServiceProperties(loopName, jsonData) {
+		return fetch('/restservices/clds/v2/loop/updateMicroservicePolicy/' + loopName, {
+			method: 'POST',
+			credentials: 'same-origin',
+			headers: {
+				"Content-Type": "application/json",
+			},
+			body: JSON.stringify(jsonData),
+		})
+			.then(function (response) {
+				console.debug("updateMicroservicePolicy response received: ", response.status);
+				if (response.ok) {
+					return response.text();
+				} else {
+					console.error("updateMicroservicePolicy query failed");
+					return "";
+				}
+			})
+			.catch(function (error) {
+				console.error("updateMicroservicePolicy error received", error);
+				return "";
+			});
+	}
 }
diff --git a/ui-react/src/components/dialogs/ConfigurationPolicy/ConfigurationPolicyModal.js b/ui-react/src/components/dialogs/ConfigurationPolicy/ConfigurationPolicyModal.js
index da2d423..8178bf4 100644
--- a/ui-react/src/components/dialogs/ConfigurationPolicy/ConfigurationPolicyModal.js
+++ b/ui-react/src/components/dialogs/ConfigurationPolicy/ConfigurationPolicyModal.js
@@ -25,7 +25,7 @@
 import Button from 'react-bootstrap/Button';
 import Modal from 'react-bootstrap/Modal';
 import styled from 'styled-components';
-
+import LoopService from '../../../api/LoopService';
 import JSONEditor from '@json-editor/json-editor';
 
 const ModalStyled = styled(Modal)`
@@ -38,17 +38,38 @@
 		show: true,
 		loopCache: this.props.loopCache,
 		jsonEditor: null,
+		componentName: "",
 	};
 
 	constructor(props, context) {
 		super(props, context);
 		this.handleClose = this.handleClose.bind(this);
+		this.handleSave = this.handleSave.bind(this);
 		this.renderJsonEditor = this.renderJsonEditor.bind(this);
+		this.state.componentName = props.match.params.componentName;
+	}
+
+	handleSave() {
+
+		var errors = this.state.jsonEditor.validate();
+		var editorData = this.state.jsonEditor.getValue();
+
+		if (errors.length !== 0) {
+			console.error("Errors detected during config policy data validation ", errors);
+		}
+		else {
+			console.info("NO validation errors found in config policy data");
+			this.state.loopCache.updateMicroServiceProperties(this.state.componentName, editorData[0]);
+			LoopService.setMicroServiceProperties(this.state.loopCache.getLoopName(), this.state.loopCache.getMicroServiceForName(this.state.componentName));
+		}
+
+		this.setState({ show: false });
+		this.props.history.push('/');
 	}
 
 	handleClose() {
 		this.setState({ show: false });
-		this.props.history.push('/')
+		this.props.history.push('/');
 	}
 
 	componentDidMount() {
@@ -56,11 +77,12 @@
 	}
 
 	renderJsonEditor() {
-		var toscaModel = this.state.loopCache.getMicroServiceJsonRepresentationForType("TCA_Jbv1z_v1_0_ResourceInstanceName1_tca");
+		console.debug("Rendering ConfigurationPolicyModal ", this.state.componentName);
+		var toscaModel = this.state.loopCache.getMicroServiceJsonRepresentationForName(this.state.componentName);
 		if (toscaModel == null) {
 			return;
 		}
-		var editorData = this.state.loopCache.getMicroServiceProperties("TCA_Jbv1z_v1_0_ResourceInstanceName1_tca");
+		var editorData = this.state.loopCache.getMicroServicePropertiesForName(this.state.componentName);
 
 		JSONEditor.defaults.options.theme = 'bootstrap4';
 		//JSONEditor.defaults.options.iconlib = 'bootstrap2';
@@ -76,7 +98,6 @@
 			jsonEditor: new JSONEditor(document.getElementById("editor"),
 				{ schema: toscaModel.schema, startval: editorData })
 		})
-
 	}
 
 	render() {
@@ -93,7 +114,7 @@
 					<Button variant="secondary" onClick={this.handleClose}>
 						Close
 	            </Button>
-					<Button variant="primary" onClick={this.handleClose}>
+					<Button variant="primary" onClick={this.handleSave}>
 						Save Changes
 	            </Button>
 				</Modal.Footer>