Add Create Instance Rest Endpoint 60/123260/11
authorbrunomilitzer <bruno.militzer@est.tech>
Wed, 28 Jul 2021 15:58:45 +0000 (16:58 +0100)
committerBruno Militzer <bruno.militzer@est.tech>
Mon, 23 Aug 2021 13:00:57 +0000 (13:00 +0000)
Added Camel Endpoint

Will Apply Unit Tests on POLICY-3537, since focus is to
get the functionalities completed.

Issue-ID: POLICY-3436
Change-Id: I8305896b24c30fc0403c57b3925af983065a5ec2
Signed-off-by: brunomilitzer <bruno.militzer@est.tech>
models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java
models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/InstancePropertiesResponse.java [new file with mode: 0644]
runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java
runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java
runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java
runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java
runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java
runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml
runtime/src/main/resources/clds/camel/routes/controlloop-flows.xml

index 4e502c6..7140791 100644 (file)
@@ -22,12 +22,15 @@ package org.onap.policy.clamp.controlloop.models.controlloop.persistence.provide
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 import javax.ws.rs.core.Response;
 import lombok.NonNull;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaControlLoop;
+import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
 import org.onap.policy.models.base.PfAuthorative;
 import org.onap.policy.models.base.PfConceptKey;
 import org.onap.policy.models.base.PfKey;
@@ -38,6 +41,7 @@ import org.onap.policy.models.provider.impl.AbstractModelsProvider;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter;
 import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate;
 import org.springframework.stereotype.Component;
@@ -183,6 +187,26 @@ public class ControlLoopProvider extends AbstractModelsProvider {
         return jpaDeleteControlLoop.toAuthorative();
     }
 
+    /**
+     * Saves Instance Properties to the database.
+     * @param serviceTemplate the service template
+     * @return a Map of tosca node templates
+     */
+    public Map<String, ToscaNodeTemplate> saveInstanceProperties(ToscaServiceTemplate serviceTemplate) {
+
+        Map<String, ToscaNodeTemplate> savedNodeTemplates = new HashMap<>();
+
+        serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().forEach((key, template) -> {
+            JpaToscaNodeTemplate jpaToscaNodeTemplate = new JpaToscaNodeTemplate(template);
+
+            getPfDao().create(jpaToscaNodeTemplate);
+
+            savedNodeTemplates.put(key, template);
+        });
+
+        return savedNodeTemplates;
+    }
+
     /**
      * Get Node Templates.
      *
@@ -220,4 +244,5 @@ public class ControlLoopProvider extends AbstractModelsProvider {
     private <T extends ToscaEntity, J extends PfAuthorative<T>> List<T> asEntityList(List<J> jpaEntityList) {
         return jpaEntityList.stream().map(J::toAuthorative).collect(Collectors.toList());
     }
+
 }
diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/InstancePropertiesResponse.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/InstancePropertiesResponse.java
new file mode 100644 (file)
index 0000000..eed3394
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ *  ================================================================================
+ *  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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.models.messages.rest.instantiation;
+
+import java.util.List;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import org.onap.policy.clamp.controlloop.models.messages.rest.SimpleResponse;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+/**
+ * Response to Instance Properties requests that affect a change.
+ */
+@Getter
+@Setter
+@ToString(callSuper = true)
+public class InstancePropertiesResponse extends SimpleResponse {
+    private List<ToscaConceptIdentifier> affectedInstanceProperties;
+}
index e676cbe..ba632f9 100644 (file)
@@ -33,6 +33,7 @@ import java.util.stream.Collectors;
 import javax.ws.rs.core.Response.Status;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
 import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse;
 import org.onap.policy.models.base.PfModelException;
@@ -85,7 +86,13 @@ public class CommissioningProvider {
      * @throws PfModelException on creation errors
      */
     public CommissioningResponse createControlLoopDefinitions(ToscaServiceTemplate serviceTemplate)
-            throws PfModelException {
+        throws PfModelException, ControlLoopException {
+
+        if (verifyIfInstancePropertiesExists()) {
+            throw new ControlLoopException(Status.BAD_REQUEST,
+                "Delete instances, to commission control loop definitions");
+        }
+
         synchronized (lockit) {
             modelsProvider.createServiceTemplate(serviceTemplate);
         }
@@ -110,7 +117,14 @@ public class CommissioningProvider {
      * @return the result of the deletion
      * @throws PfModelException on deletion errors
      */
-    public CommissioningResponse deleteControlLoopDefinition(String name, String version) throws PfModelException {
+    public CommissioningResponse deleteControlLoopDefinition(String name, String version)
+        throws PfModelException, ControlLoopException {
+
+        if (verifyIfInstancePropertiesExists()) {
+            throw new ControlLoopException(Status.BAD_REQUEST,
+                "Delete instances, to commission control loop definitions");
+        }
+
         synchronized (lockit) {
             modelsProvider.deleteServiceTemplate(name, version);
         }
@@ -365,7 +379,9 @@ public class CommissioningProvider {
      * @return the tosca service template
      * @throws PfModelException on errors getting tosca service template
      */
-    public String getToscaServiceTemplateReduced(String name, String version) throws PfModelException {
+    public String getToscaServiceTemplateReduced(String name, String version)
+        throws PfModelException {
+
         var serviceTemplates = new ToscaServiceTemplates();
         serviceTemplates.setServiceTemplates(modelsProvider.getServiceTemplateList(name, version));
 
@@ -431,4 +447,15 @@ public class CommissioningProvider {
             throw new PfModelException(Status.BAD_REQUEST, "Converion to Json Schema failed", e);
         }
     }
+
+    /**
+     * Validates to see if there is any instance properties saved.
+     *
+     * @return true if exists instance properties
+     */
+    private Boolean verifyIfInstancePropertiesExists() {
+        return clProvider.getNodeTemplates(null, null).stream()
+            .anyMatch(nodeTemplate -> nodeTemplate.getKey().getName().contains("_Instance"));
+
+    }
 }
index cb22132..da85b0a 100644 (file)
@@ -37,6 +37,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
 import org.onap.policy.clamp.controlloop.models.messages.rest.GenericNameVersion;
 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.ControlLoopOrderStateResponse;
+import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstancePropertiesResponse;
 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand;
 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
@@ -48,6 +49,7 @@ import org.onap.policy.common.parameters.ValidationStatus;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.springframework.stereotype.Component;
 
 /**
@@ -62,6 +64,44 @@ public class ControlLoopInstantiationProvider {
 
     private static final Object lockit = new Object();
 
+    private static final String CL_ELEMENT_NAME = "name";
+
+    /**
+     * Create Instance Properties.
+     *
+     * @param serviceTemplate the service template
+     * @return the result of the instantiation operation
+     * @throws PfModelException on creation errors
+     */
+    public InstancePropertiesResponse saveInstanceProperties(ToscaServiceTemplate serviceTemplate) {
+
+        String instanceName = generateSequentialInstanceName();
+
+        Map<String, ToscaNodeTemplate> nodeTemplates = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+
+        nodeTemplates.forEach((key, template) -> {
+            String name = key + instanceName;
+            String description = template.getDescription() + instanceName;
+            template.setName(name);
+            template.setDescription(description);
+
+            changeInstanceElementsName(template, instanceName);
+
+        });
+
+        Map<String, ToscaNodeTemplate> toscaSavedNodeTemplate = controlLoopProvider
+            .saveInstanceProperties(serviceTemplate);
+
+        var response = new InstancePropertiesResponse();
+
+        // @formatter:off
+        response.setAffectedInstanceProperties(toscaSavedNodeTemplate.values().stream().map(template ->
+            template.getKey().asIdentifier()).collect(Collectors.toList()));
+        // @formatter:on
+
+        return response;
+    }
+
     /**
      * Create control loops.
      *
@@ -267,10 +307,10 @@ public class ControlLoopInstantiationProvider {
 
         List<ControlLoop> controlLoops = controlLoopProvider.getControlLoops(name, version);
 
-        ControlLoopOrderStateResponse response = new ControlLoopOrderStateResponse();
+        var response = new ControlLoopOrderStateResponse();
 
         controlLoops.forEach(controlLoop -> {
-            GenericNameVersion genericNameVersion = new GenericNameVersion();
+            var genericNameVersion = new GenericNameVersion();
             genericNameVersion.setName(controlLoop.getName());
             genericNameVersion.setVersion(controlLoop.getVersion());
             response.getControlLoopIdentifierList().add(genericNameVersion);
@@ -278,4 +318,44 @@ public class ControlLoopInstantiationProvider {
 
         return response;
     }
+
+    /**
+     * Creates instance element name.
+     *
+     * @param serviceTemplate the service serviceTemplate
+     * @param instanceName    to amend to the element name
+     */
+    private void changeInstanceElementsName(ToscaNodeTemplate serviceTemplate, String instanceName) {
+
+        @SuppressWarnings("unchecked")
+        List<Map<String, String>> controlLoopElements = (List<Map<String, String>>) serviceTemplate.getProperties()
+            .get("elements");
+
+        if (controlLoopElements != null) {
+            controlLoopElements.forEach(clElement -> {
+                String name = clElement.get(CL_ELEMENT_NAME) + instanceName;
+                clElement.replace(CL_ELEMENT_NAME, name);
+            });
+        }
+    }
+
+
+    /**
+     * Generates Instance Name in sequential order and return it to append to the Node Template Name.
+     *
+     * @return instanceName
+     */
+    private String generateSequentialInstanceName() {
+        List<ToscaNodeTemplate> nodeTemplates = controlLoopProvider.getNodeTemplates(null, null);
+
+        int instanceNumber =
+            nodeTemplates.stream().map(ToscaNodeTemplate::getName)
+                .filter(name -> name.contains("_Instance")).map(n -> {
+                    String[] defNameArr = n.split("_Instance");
+
+                    return Integer.parseInt(defNameArr[1]);
+                }).reduce(0, Math::max);
+
+        return "_Instance" + (instanceNumber + 1);
+    }
 }
index ec7f14d..2c3a41e 100644 (file)
@@ -33,6 +33,7 @@ import java.util.Map;
 import java.util.UUID;
 import javax.ws.rs.core.Response.Status;
 import lombok.RequiredArgsConstructor;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
 import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse;
 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
 import org.onap.policy.clamp.controlloop.runtime.main.web.AbstractRestController;
@@ -120,7 +121,7 @@ public class CommissioningController extends AbstractRestController {
                     name = REQUEST_ID_NAME,
                     required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
             @ApiParam(value = "Entity Body of Control Loop", required = true) @RequestBody ToscaServiceTemplate body)
-            throws PfModelException {
+        throws PfModelException, ControlLoopException {
 
         return ResponseEntity.ok().body(provider.createControlLoopDefinitions(body));
     }
@@ -187,7 +188,7 @@ public class CommissioningController extends AbstractRestController {
             @ApiParam(
                     value = "Control Loop definition version",
                     required = true) @RequestParam("version") String version)
-            throws PfModelException {
+        throws PfModelException, ControlLoopException {
 
         return ResponseEntity.ok().body(provider.deleteControlLoopDefinition(name, version));
     }
index 6f0c859..d2a85c4 100644 (file)
@@ -33,11 +33,13 @@ import lombok.RequiredArgsConstructor;
 import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.ControlLoopOrderStateResponse;
+import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstancePropertiesResponse;
 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand;
 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
 import org.onap.policy.clamp.controlloop.runtime.instantiation.ControlLoopInstantiationProvider;
 import org.onap.policy.clamp.controlloop.runtime.main.web.AbstractRestController;
 import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.DeleteMapping;
@@ -126,6 +128,70 @@ public class InstantiationController extends AbstractRestController {
         return ResponseEntity.ok().body(provider.createControlLoops(controlLoops));
     }
 
+    /**
+     * Saves instance properties.
+     *
+     * @param requestId request ID used in ONAP logging
+     * @param body the body of control loop following TOSCA definition
+     * @return a response
+     */
+    // @formatter:off
+    @PostMapping(value = "/instanceProperties",
+        consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML},
+        produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
+    @ApiOperation(
+        value = "Saves instance properties",
+        notes = "Saves instance properties, returning the saved instances properties and it's version",
+        response = InstancePropertiesResponse.class,
+        tags = {TAGS},
+        authorizations = @Authorization(value = AUTHORIZATION_TYPE),
+        responseHeaders = {
+            @ResponseHeader(
+                name = VERSION_MINOR_NAME,
+                description = VERSION_MINOR_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(
+                name = VERSION_PATCH_NAME,
+                description = VERSION_PATCH_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(
+                name = VERSION_LATEST_NAME,
+                description = VERSION_LATEST_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(
+                name = REQUEST_ID_NAME,
+                description = REQUEST_ID_HDR_DESCRIPTION,
+                response = UUID.class)
+        },
+        extensions = {
+            @Extension
+                (
+                    name = EXTENSION_NAME,
+                    properties = {
+                        @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
+                        @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
+                    }
+                )
+        }
+    )
+    @ApiResponses(
+        value = {
+            @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
+            @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
+            @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
+        }
+    )
+    // @formatter:on
+    public ResponseEntity<InstancePropertiesResponse> createInstanceProperties(
+            @RequestHeader(
+                name = REQUEST_ID_NAME,
+                required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
+            @ApiParam(value = "Body of instance properties", required = true) @RequestBody ToscaServiceTemplate body)
+        throws PfModelException {
+
+        return ResponseEntity.ok().body(provider.saveInstanceProperties(body));
+    }
+
     /**
      * Queries details of all control loops.
      *
index 9a9fc16..e98ad13 100644 (file)
@@ -25,8 +25,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.File;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
+import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstancePropertiesResponse;
 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand;
 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
@@ -133,11 +135,30 @@ public class InstantiationUtils {
      * @throws PfModelException if an error occurs
      */
     public static void storeToscaServiceTemplate(String path, CommissioningProvider commissioningProvider)
-            throws PfModelException {
+        throws PfModelException, ControlLoopException {
 
         ToscaServiceTemplate template =
                 yamlTranslator.fromYaml(ResourceUtils.getResourceAsString(path), ToscaServiceTemplate.class);
 
         commissioningProvider.createControlLoopDefinitions(template);
     }
+
+    /**
+     * Assert that instance properties has been properly saved.
+     *
+     * @param response InstancePropertiesResponse
+     * @throws PfModelException if an error occurs
+     */
+    public static void assertInstancePropertiesResponse(InstancePropertiesResponse response) throws PfModelException {
+
+        assertThat(response).isNotNull();
+        assertThat(response.getErrorDetails()).isNull();
+        assertThat(response.getAffectedInstanceProperties()).hasSize(8);
+
+        boolean containsInstance = response.getAffectedInstanceProperties().stream()
+            .anyMatch(identifier -> identifier.getName().contains("_Instance"));
+
+        assertThat(containsInstance).isTrue();
+
+    }
 }
index 2e71c58..f800efe 100644 (file)
                 <removeHeaders pattern="*"
                                excludePattern="name|version|requestId"/>
                 <setProperty name="raiseHttpExceptionFlag">
-                    <simple resultType="java.lang.Boolean">true</simple>
+                    <simple resultType="java.lang.Boolean">false</simple>
                 </setProperty>
                 <setHeader name="Content-Type">
                     <constant>application/json</constant>
             </route>
         </get>
 
+        <post uri="/v2/toscaControlLoop/postToscaInstanceProperties"
+              type="java.lang.String"
+              consumes="plain/text"
+              outType="java.lang.String"
+              produces="application/json"
+              bindingMode="off">
+            <route>
+                <removeHeaders pattern="*"/>
+                <setProperty name="raiseHttpExceptionFlag">
+                    <simple resultType="java.lang.Boolean">false</simple>
+                </setProperty>
+                <setHeader name="Content-Type">
+                    <constant>application/json</constant>
+                </setHeader>
+                <doTry>
+                    <to
+                            uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=startLog(*, 'Update the global properties')"/>
+                    <to
+                            uri="bean:org.onap.policy.clamp.authorization.AuthorizationController?method=authorize(*,'cl','','update')"/>
+                    <to uri="direct:post-tosca-instance-properties"/>
+                    <to
+                            uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=endLog()"/>
+                    <doCatch>
+                        <exception>java.lang.Exception</exception>
+                        <handled>
+                            <constant>true</constant>
+                        </handled>
+                        <to
+                                uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=errorLog()"/>
+                        <log loggingLevel="ERROR"
+                             message="Creating Instance Properties FAILED"/>
+
+                        <setHeader name="CamelHttpResponseCode">
+                            <constant>500</constant>
+                        </setHeader>
+                        <setBody>
+                            <simple>Creating Instance Properties FAILED</simple>
+                        </setBody>
+                    </doCatch>
+                </doTry>
+            </route>
+        </post>
+
         <get uri="/v2/toscaControlLoop/getCommonOrInstanceProperties" outType="java.lang.String" bindingMode="off" produces="application/json">
             <route>
                 <removeHeaders pattern="*"
index 230aea1..12b43dd 100644 (file)
             </doFinally>
         </doTry>
     </route>
+    <route id="post-tosca-instance-properties">
+        <from uri="direct:post-tosca-instance-properties"/>
+        <doTry>
+            <log loggingLevel="INFO"
+                 message="Creating the tosca instance properties"/>
+            <to
+                    uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeLog('Controlloop', 'Creating the tosca instance properties')"/>
+            <setHeader name="CamelHttpMethod">
+                <constant>POST</constant>
+            </setHeader>
+            <setHeader name="Content-Type">
+                <constant>application/json</constant>
+            </setHeader>
+            <log loggingLevel="INFO"
+                 message="Endpoint to send Tosca Instance Properties: {{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/instanceProperties"></log>
+            <toD
+                    uri="{{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/instanceProperties? bridgeEndpoint=true&amp;useSystemProperties=true&amp;throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&amp;authMethod=Basic&amp;authUsername={{clamp.config.controlloop.runtime.userName}}&amp;authPassword={{clamp.config.controlloop.runtime.password}}&amp;authenticationPreemptive=true&amp;connectionClose=true"/>
+            <convertBodyTo type="java.lang.String"/>
+            <doFinally>
+                <to uri="direct:reset-raise-http-exception-flag"/>
+                <to
+                        uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeReturnLog()"/>
+            </doFinally>
+        </doTry>
+    </route>
     <route id="post-tosca-instantiation">
         <from uri="direct:post-tosca-instantiation"/>
         <doTry>