diff options
author | brunomilitzer <bruno.militzer@est.tech> | 2022-05-05 15:20:30 +0100 |
---|---|---|
committer | brunomilitzer <bruno.militzer@est.tech> | 2022-05-25 15:01:02 +0100 |
commit | f35587328e1bd99882ed8a4df85d01660d54c007 (patch) | |
tree | 668b2e35b88a24dbf60ce84d62c21c463e2c0449 | |
parent | b77b61847ddd169da9a71b05742ed51bc826f5f6 (diff) |
Added Edit Instance Properties Functionality
Issue-ID: POLICY-4094
Change-Id: Id52dba3c0912486fa551697be170c05542a0ee22
Signed-off-by: brunomilitzer <bruno.militzer@est.tech>
12 files changed, 434 insertions, 36 deletions
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ServiceTemplateProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ServiceTemplateProvider.java index 0de5f480a..942fe8d46 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ServiceTemplateProvider.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ServiceTemplateProvider.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021-2022 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -133,7 +133,6 @@ public class ServiceTemplateProvider { * @param fullNodeTypes map of all the node types in the specified template * @param common boolean to indicate whether common or instance properties are required * @return node types map that only has common properties - * @throws PfModelException on errors getting node type with common properties */ private Map<String, ToscaNodeType> getInitialNodeTypesMap(Map<String, ToscaNodeType> fullNodeTypes, boolean common) { @@ -215,6 +214,56 @@ public class ServiceTemplateProvider { } /** + * Get the node types derived from those that have been saved by instantiation. + * + * @param initialNodeTypes map of all the node types in the specified template + * @param filteredNodeTypes map of all the node types that have common or instance properties + * @param instanceName automation composition name + * @return all node types that have common properties including their children + */ + private Map<String, ToscaNodeType> getFinalSavedInstanceNodeTypesMap( + Map<String, ToscaNodeType> initialNodeTypes, + Map<String, ToscaNodeType> filteredNodeTypes, String instanceName) { + + for (var i = 0; i < initialNodeTypes.size(); i++) { + initialNodeTypes.forEach((key, nodeType) -> { + var tempToscaNodeType = new ToscaNodeType(); + tempToscaNodeType.setName(key); + + if (filteredNodeTypes.get(nodeType.getDerivedFrom()) != null) { + tempToscaNodeType.setName(key); + + var finalProps = new HashMap<String, ToscaProperty>( + filteredNodeTypes.get(nodeType.getDerivedFrom()).getProperties()); + + tempToscaNodeType.setProperties(finalProps); + } else { + return; + } + filteredNodeTypes.putIfAbsent(key, tempToscaNodeType); + + }); + } + return filteredNodeTypes; + } + + /** + * Get the requested node types by automation composition. + * + * @param instanceName automation composition name + * @param serviceTemplate the ToscaServiceTemplate + * @return the node types with common or instance properties + */ + public Map<String, ToscaNodeType> getSavedInstanceInstancePropertiesFromNodeTypes( + String instanceName, ToscaServiceTemplate serviceTemplate) { + var tempNodeTypesMap = + this.getInitialNodeTypesMap(serviceTemplate.getNodeTypes(), false); + + return this.getFinalSavedInstanceNodeTypesMap(serviceTemplate.getNodeTypes(), tempNodeTypesMap, instanceName); + + } + + /** * Get the requested node types with common or instance properties. * * @param common boolean indicating common or instance properties diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java index 726fcba5c..7d2d4f39c 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021-2022 Nordix Foundation. * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,6 +35,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.apache.commons.lang3.StringUtils; import org.onap.policy.clamp.acm.runtime.supervision.SupervisionHandler; import org.onap.policy.clamp.models.acm.concepts.Participant; import org.onap.policy.clamp.models.acm.messages.rest.commissioning.CommissioningResponse; @@ -237,15 +238,17 @@ public class CommissioningProvider { /** * Get node templates with common properties added. * - * @param common boolean indicating common or instance properties to be used * @param name the name of the definition to use, null for all definitions * @param version the version of the definition to use, null for all definitions + * @param instanceName automation composition name + * @param common boolean indicating common or instance properties to be used * @return the nodes templates with common or instance properties * @throws PfModelException on errors getting common or instance properties from node_templates */ @Transactional(readOnly = true) - public Map<String, ToscaNodeTemplate> getNodeTemplatesWithCommonOrInstanceProperties(boolean common, String name, - String version) throws PfModelException { + public Map<String, ToscaNodeTemplate> getNodeTemplatesWithCommonOrInstanceProperties( + final String name, final String version, final String instanceName, final boolean common) + throws PfModelException { if (common && verifyIfInstancePropertiesExists()) { throw new PfModelException(Status.BAD_REQUEST, @@ -253,11 +256,17 @@ public class CommissioningProvider { } var serviceTemplateList = serviceTemplateProvider.getServiceTemplateList(name, version); + + if (serviceTemplateList.isEmpty()) { + throw new PfModelException(Status.BAD_REQUEST, + "Tosca service template has to be commissioned before saving instance properties"); + } + var commonOrInstanceNodeTypeProps = serviceTemplateProvider.getCommonOrInstancePropertiesFromNodeTypes(common, serviceTemplateList.get(0)); var serviceTemplates = new ToscaServiceTemplates(); - serviceTemplates.setServiceTemplates(filterToscaNodeTemplateInstance(serviceTemplateList)); + serviceTemplates.setServiceTemplates(filterToscaNodeTemplateInstance(serviceTemplateList, instanceName)); return serviceTemplateProvider.getDerivedCommonOrInstanceNodeTemplates( serviceTemplates.getServiceTemplates().get(0).getToscaTopologyTemplate().getNodeTemplates(), @@ -293,14 +302,19 @@ public class CommissioningProvider { * * @param name the name of the template to get, null for all definitions * @param version the version of the template to get, null for all definitions + * @param instanceName automation composition name * @return the tosca service template * @throws PfModelException on errors getting tosca service template */ @Transactional(readOnly = true) - public String getToscaServiceTemplateReduced(String name, String version) throws PfModelException { + public String getToscaServiceTemplateReduced( + final String name, final String version, final String instanceName) + throws PfModelException { + var serviceTemplateList = serviceTemplateProvider.getServiceTemplateList(name, version); - List<ToscaServiceTemplate> filteredServiceTemplateList = filterToscaNodeTemplateInstance(serviceTemplateList); + List<ToscaServiceTemplate> filteredServiceTemplateList = + filterToscaNodeTemplateInstance(serviceTemplateList, instanceName); if (filteredServiceTemplateList.isEmpty()) { throw new PfModelException(Status.BAD_REQUEST, "Invalid Service Template"); @@ -342,16 +356,26 @@ public class CommissioningProvider { } } - private List<ToscaServiceTemplate> filterToscaNodeTemplateInstance(List<ToscaServiceTemplate> serviceTemplates) { + /** + * Filters service templates if is not an instantiation type. + * + * @param serviceTemplates tosca service template + * @param instanceName automation composition name + * @return List of tosca service templates + */ + private List<ToscaServiceTemplate> filterToscaNodeTemplateInstance( + List<ToscaServiceTemplate> serviceTemplates, String instanceName) { List<ToscaServiceTemplate> toscaServiceTemplates = new ArrayList<>(); - serviceTemplates.stream().forEach(serviceTemplate -> { + serviceTemplates.forEach(serviceTemplate -> { Map<String, ToscaNodeTemplate> toscaNodeTemplates = new HashMap<>(); serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().forEach((key, nodeTemplate) -> { - if (!nodeTemplate.getName().contains(HYPHEN)) { + if (StringUtils.isNotEmpty(instanceName) && nodeTemplate.getName().contains(instanceName)) { + toscaNodeTemplates.put(key, nodeTemplate); + } else if (!nodeTemplate.getName().contains(HYPHEN)) { toscaNodeTemplates.put(key, nodeTemplate); } }); diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java index 40d4c5a85..98b59aed7 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java @@ -142,6 +142,61 @@ public class AutomationCompositionInstantiationProvider { } /** + * Updates Instance Properties and Automation Composition Instance. + * + * @param name the name of the automation composition to update + * @param version the version of the automation composition to update + * @param serviceTemplate tosca service template body + * @return InstancePropertiesResponse response from updating instance properties + * @throws PfModelException exception if incorrect instance name + */ + public InstancePropertiesResponse updatesInstanceProperties( + String name, String version, ToscaServiceTemplate serviceTemplate) throws PfModelException { + + if (name.length() < 3) { + throw new PfModelException(Status.BAD_REQUEST, "Instance Name cannot be empty or less than 3 characters!"); + } + + Map<String, ToscaNodeTemplate> nodeTemplates = deepCloneNodeTemplate(serviceTemplate); + Map<String, ToscaNodeTemplate> updatedNodeTemplates = new HashMap<>(); + + String instanceName = serviceTemplate.getName(); + + nodeTemplates.forEach((key, template) -> { + ToscaNodeTemplate toscaNodeTemplate = new ToscaNodeTemplate(); + + String updatedName = updateInstanceNameDescription(instanceName, name, key); + String updatedDescription = updateInstanceNameDescription( + instanceName, name, template.getDescription()); + + toscaNodeTemplate.setName(updatedName); + toscaNodeTemplate.setDescription(updatedDescription); + toscaNodeTemplate.setCapabilities(template.getCapabilities()); + toscaNodeTemplate.setRequirements(template.getRequirements()); + toscaNodeTemplate.setMetadata(template.getMetadata()); + toscaNodeTemplate.setProperties(template.getProperties()); + toscaNodeTemplate.setDerivedFrom(template.getDerivedFrom()); + toscaNodeTemplate.setVersion(template.getVersion()); + toscaNodeTemplate.setType(template.getType()); + toscaNodeTemplate.setTypeVersion(template.getTypeVersion()); + + String updatedKey = updateInstanceNameDescription(instanceName, name, key); + + updatedNodeTemplates.put(updatedKey, toscaNodeTemplate); + }); + + serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().clear(); + serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().putAll(updatedNodeTemplates); + + AutomationCompositions automationCompositions = updateAutomationComposition( + name, instanceName); + + deleteInstanceProperties(name, version); + + return saveInstancePropertiesAndAutomationComposition(serviceTemplate, automationCompositions); + } + + /** * Deletes Instance Properties. * * @param name the name of the automation composition to delete @@ -616,4 +671,64 @@ public class AutomationCompositionInstantiationProvider { Type type = new TypeToken<HashMap<String, ToscaNodeTemplate>>() {}.getType(); return GSON.fromJson(jsonString, type); } + + /** + * Updates Automation composition instance name. + * + * @param oldInstanceName previous saved instance name + * @param newInstanceName new instance name to replace the previous one + * @return AutomationCompositions updated + * @throws PfModelException exception to compositions is not defined + */ + private AutomationCompositions updateAutomationComposition( + String oldInstanceName, String newInstanceName) throws PfModelException { + + List<AutomationComposition> filteredAcmList = automationCompositionProvider.getAutomationCompositions() + .stream().filter(acm -> acm.getName().contains(oldInstanceName)).collect(Collectors.toList()); + + if (filteredAcmList.isEmpty()) { + throw new PfModelException(Status.BAD_REQUEST, "Automation compositions not defined!"); + } + + AutomationComposition automationComposition = filteredAcmList.get(0); + + automationComposition.getDefinition() + .setName(updateInstanceNameDescription(newInstanceName, oldInstanceName, + automationComposition.getDefinition().getName())); + + automationComposition.setName(newInstanceName); + + automationComposition.setDescription( + updateInstanceNameDescription(newInstanceName, oldInstanceName, + automationComposition.getDescription())); + + automationComposition.getElements().forEach((uuid, automationCompositionElement) -> { + automationCompositionElement.getDefinition() + .setName(updateInstanceNameDescription(newInstanceName, oldInstanceName, + automationCompositionElement.getDefinition().getName())); + }); + + AutomationCompositions automationCompositions = new AutomationCompositions(); + automationCompositions.getAutomationCompositionList().add(automationComposition); + + return automationCompositions; + + } + + /** + * Updates instance and description. + * + * @param newInstanceName new instance name to replace the previous one + * @param oldInstanceName previous saved instance name + * @param value to be updated + * @return String updated instance name or description + */ + private String updateInstanceNameDescription( + String newInstanceName, String oldInstanceName, String value) { + String toBeReplaced = value.substring(value.indexOf(oldInstanceName)); + + String replace = value.replace(toBeReplaced, newInstanceName); + + return replace; + } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/CommissioningController.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/CommissioningController.java index 0fd8661b4..0458b074a 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/CommissioningController.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/CommissioningController.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021-2022 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,6 @@ import javax.ws.rs.core.Response.Status; import lombok.RequiredArgsConstructor; import org.onap.policy.clamp.acm.runtime.commissioning.CommissioningProvider; import org.onap.policy.clamp.acm.runtime.main.web.AbstractRestController; -import org.onap.policy.clamp.common.acm.exception.AutomationCompositionException; import org.onap.policy.clamp.models.acm.messages.rest.commissioning.CommissioningResponse; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; @@ -305,10 +304,13 @@ public class CommissioningController extends AbstractRestController { required = false) String name, @ApiParam(value = "Tosca service template version", required = false) @RequestParam( value = "version", - required = false) String version) + required = false) String version, + @ApiParam(value = "Automation composition name", required = false) @RequestParam( + value = "instanceName", + required = false) String instanceName) throws PfModelException { - return ResponseEntity.ok().body(provider.getToscaServiceTemplateReduced(name, version)); + return ResponseEntity.ok().body(provider.getToscaServiceTemplateReduced(name, version, instanceName)); } /** @@ -376,7 +378,6 @@ public class CommissioningController extends AbstractRestController { * @param version the version of the tosca service template to get * @return the specified tosca service template or section Json Schema * @throws PfModelException on errors getting the Common or Instance Properties - * @throws AutomationCompositionException on error getting the Common or Instance Properties */ // @formatter:off @GetMapping(value = "/commission/getCommonOrInstanceProperties", @@ -418,18 +419,23 @@ public class CommissioningController extends AbstractRestController { // @formatter:on public ResponseEntity<Map<String, ToscaNodeTemplate>> queryToscaServiceCommonOrInstanceProperties( @RequestHeader(name = REQUEST_ID_NAME, required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam( - value = "Flag, true for common properties, false for instance", - required = false) @RequestParam(value = "common", defaultValue = "false", required = false) boolean common, @ApiParam(value = "Tosca service template name", required = false) @RequestParam( value = "name", required = false) String name, @ApiParam(value = "Tosca service template version", required = false) @RequestParam( value = "version", - required = false) String version) + required = false) String version, + @ApiParam(value = "Automation composition name", required = false) @RequestParam( + value = "instanceName", + required = false) String instanceName, + @ApiParam( + value = "Flag, true for common properties, false for instance", + required = false) + @RequestParam(value = "common", defaultValue = "false", required = false) boolean common) throws PfModelException { - return ResponseEntity.ok().body(provider.getNodeTemplatesWithCommonOrInstanceProperties(common, name, version)); + return ResponseEntity.ok().body(provider + .getNodeTemplatesWithCommonOrInstanceProperties(name, version, instanceName, common)); } /** diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/InstantiationController.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/InstantiationController.java index dc56c77e7..b4d978d77 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/InstantiationController.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/InstantiationController.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021-2022 Nordix Foundation. * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -193,6 +193,74 @@ public class InstantiationController extends AbstractRestController { } /** + * Updates instance properties. + * + * @param name the name of the automation composition to update + * @param version the version of the automation composition to update + * @param body the body of automation composition following TOSCA definition + * @return a response + */ + // @formatter:off + @PutMapping(value = "/instanceProperties", + consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}, + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation( + value = "Updates instance properties", + notes = "Updates 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> updatesInstanceProperties( + @RequestHeader(name = REQUEST_ID_NAME, required = false) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Automation composition definition name", required = true) + @RequestParam("name") String name, + @ApiParam(value = "Automation composition definition version", required = true) + @RequestParam("version") String version, + @ApiParam(value = "Body of instance properties", required = true) @RequestBody ToscaServiceTemplate body) + throws PfModelException { + + return ResponseEntity.ok().body(provider.updatesInstanceProperties(name, version, body)); + } + + /** * Deletes a automation composition definition and instance properties. * * @param requestId request ID used in ONAP logging @@ -248,8 +316,8 @@ public class InstantiationController extends AbstractRestController { public ResponseEntity<InstantiationResponse> deleteInstanceProperties( @RequestHeader(name = REQUEST_ID_NAME, required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Automation composition definition name", required = true) @RequestParam("name") String name, - @ApiParam(value = "Automation composition definition version") @RequestParam( + @ApiParam(value = "Automation composition definition name", required = true) @RequestParam("name") String name, + @ApiParam(value = "Automation composition definition version") @RequestParam( value = "version", required = true) String version) throws PfModelException { diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java index 71aadccb9..152171f9e 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java @@ -163,7 +163,8 @@ class CommissioningProviderTest { when(serviceTemplateProvider.getServiceTemplateList(any(), any())) .thenReturn(List.of(Objects.requireNonNull(serviceTemplate))); - String returnedServiceTemplate = provider.getToscaServiceTemplateReduced(null, null); + String returnedServiceTemplate = provider + .getToscaServiceTemplateReduced(null, null, null); assertThat(returnedServiceTemplate).isNotNull(); ToscaServiceTemplate parsedServiceTemplate = CODER.decode(returnedServiceTemplate, ToscaServiceTemplate.class); diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/rest/CommissioningControllerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/rest/CommissioningControllerTest.java index 87633dfd4..a0f1a7590 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/rest/CommissioningControllerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/rest/CommissioningControllerTest.java @@ -158,7 +158,7 @@ class CommissioningControllerTest extends CommonRestController { createFullEntryInDbWithCommonProps(); Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT - + "/getCommonOrInstanceProperties" + "?common=true&name=ToscaServiceTemplateSimple&version=1.0.0"); + + "/getCommonOrInstanceProperties?common=true"); Response rawresp = invocationBuilder.buildGet().invoke(); assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java index 248b04595..b826eebbc 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java @@ -120,6 +120,11 @@ class AutomationCompositionInstantiationProviderTest { automationComposition.setVersion(ID_VERSION); when(acProvider.getAutomationCompositions(ID_NAME, ID_VERSION)).thenReturn(List.of(automationComposition)); + var updatedInstancePropertyList = instantiationProvider.createInstanceProperties(serviceTemplate); + assertNull(updatedInstancePropertyList.getErrorDetails()); + var updatedId = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); + assertEquals(updatedId, instancePropertyList.getAffectedInstanceProperties().get(0)); + var instanceOrderState = instantiationProvider.getInstantiationOrderState(ID_NAME, ID_VERSION); assertEquals(AutomationCompositionOrderedState.UNINITIALISED, instanceOrderState.getOrderedState()); assertEquals(ID_NAME, instanceOrderState.getAutomationCompositionIdentifierList().get(0).getName()); diff --git a/runtime/extra/sql/bulkload/create-db.sql b/runtime/extra/sql/bulkload/create-db.sql index 5fa34ca04..a9d81d7c5 100644 --- a/runtime/extra/sql/bulkload/create-db.sql +++ b/runtime/extra/sql/bulkload/create-db.sql @@ -7,9 +7,9 @@ USE `cldsdb4`; DROP USER 'clds'; CREATE USER 'clds'; GRANT ALL on cldsdb4.* to 'clds' identified by 'sidnnd83K' with GRANT OPTION; -CREATE DATABASE `controlloop`; -USE `controlloop`; +CREATE DATABASE `clampacm`; +USE `clampacm`; DROP USER 'policy'; CREATE USER 'policy'; -GRANT ALL on controlloop.* to 'policy' identified by 'P01icY' with GRANT OPTION; +GRANT ALL on clampacm.* to 'policy' identified by 'P01icY' with GRANT OPTION; FLUSH PRIVILEGES; diff --git a/runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml b/runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml index 8ad20a844..7db468024 100644 --- a/runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml +++ b/runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml @@ -1480,7 +1480,7 @@ produces="application/json"> <route> <removeHeaders pattern="*" - excludePattern="name|version"/> + excludePattern="name|version|instanceName"/> <doTry> <to uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=startLog(*, 'GET Tosca Service Template ')"/> @@ -1860,6 +1860,50 @@ </doTry> </route> </post> + + <put uri="/v2/acm/putToscaInstanceProperties" + type="java.lang.String" + consumes="plain/text" + outType="java.lang.String" + produces="application/json" + bindingMode="off"> + <route> + <removeHeaders pattern="*" excludePattern="name|version"/> + <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:put-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="Updating Instance Properties FAILED"/> + + <setHeader name="CamelHttpResponseCode"> + <constant>500</constant> + </setHeader> + <setBody> + <simple>Updating Instance Properties FAILED</simple> + </setBody> + </doCatch> + </doTry> + </route> + </put> + <delete uri="/v2/acm/deleteToscaInstanceProperties" type="java.lang.String" consumes="plain/text" @@ -1907,7 +1951,7 @@ <get uri="/v2/acm/getCommonOrInstanceProperties" outType="java.lang.String" bindingMode="off" produces="application/json"> <route> <removeHeaders pattern="*" - excludePattern="name|version|requestId|common"/> + excludePattern="name|version|instanceName|requestId|common"/> <doTry> <to uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=startLog(*, 'GET Common Properties ')"/> <to uri="bean:org.onap.policy.clamp.authorization.AuthorizationController?method=authorize(*,'cl','','read')"/> @@ -1932,7 +1976,7 @@ <constant>500</constant> </setHeader> <setBody> - <simple>GET Common Properties FAILED</simple> + <simple>GET Common or Instance Properties FAILED</simple> </setBody> </doCatch> </doTry> diff --git a/runtime/src/main/resources/clds/camel/routes/acm-flows.xml b/runtime/src/main/resources/clds/camel/routes/acm-flows.xml index c304c5360..9150a2335 100644 --- a/runtime/src/main/resources/clds/camel/routes/acm-flows.xml +++ b/runtime/src/main/resources/clds/camel/routes/acm-flows.xml @@ -18,9 +18,12 @@ <setProperty name="version"> <simple>${header.version}</simple> </setProperty> + <setProperty name="instanceName"> + <simple>${header.instanceName}</simple> + </setProperty> <log loggingLevel="INFO" message="Endpoint to get Tosca Service Template: {{clamp.config.acm.runtime.url}}/onap/policy/clamp/acm/v2/commission/toscaservicetemplate"></log> - <toD uri="{{clamp.config.acm.runtime.url}}/onap/policy/clamp/acm/v2/commission/toscaservicetemplate?name=${exchangeProperty[name]}&version=${exchangeProperty[version]}&bridgeEndpoint=true&useSystemProperties=true&throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&authMethod=Basic&authUsername={{clamp.config.acm.runtime.userName}}&authPassword={{clamp.config.acm.runtime.password}}&authenticationPreemptive=true&connectionClose=true"/> + <toD uri="{{clamp.config.acm.runtime.url}}/onap/policy/clamp/acm/v2/commission/toscaservicetemplate?name=${exchangeProperty[name]}&version=${exchangeProperty[version]}&instanceName=${exchangeProperty[instanceName]}&bridgeEndpoint=true&useSystemProperties=true&throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&authMethod=Basic&authUsername={{clamp.config.acm.runtime.userName}}&authPassword={{clamp.config.acm.runtime.password}}&authenticationPreemptive=true&connectionClose=true"/> <convertBodyTo type="java.lang.String"/> <doFinally> <to uri="direct:reset-raise-http-exception-flag"/> @@ -166,6 +169,37 @@ </doFinally> </doTry> </route> + <route id="put-tosca-instance-properties"> + <from uri="direct:put-tosca-instance-properties"/> + <doTry> + <log loggingLevel="INFO" + message="Updating the tosca instance properties"/> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeLog('AutomationComposition', 'Updating the tosca instance properties')"/> + <setHeader name="CamelHttpMethod"> + <constant>PUT</constant> + </setHeader> + <setHeader name="Content-Type"> + <constant>application/json</constant> + </setHeader> + <setProperty name="name"> + <simple>${header.name}</simple> + </setProperty> + <setProperty name="version"> + <simple>${header.version}</simple> + </setProperty> + <log loggingLevel="INFO" + message="Endpoint to send Tosca Instance Properties: {{clamp.config.acm.runtime.url}}/onap/policy/clamp/acm/v2/instanceProperties"></log> + <toD + uri="{{clamp.config.acm.runtime.url}}/onap/policy/clamp/acm/v2/instanceProperties?name=${exchangeProperty[name]}&version=${exchangeProperty[version]}&bridgeEndpoint=true&useSystemProperties=true&throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&authMethod=Basic&authUsername={{clamp.config.acm.runtime.userName}}&authPassword={{clamp.config.acm.runtime.password}}&authenticationPreemptive=true&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="delete-tosca-instance-properties"> <from uri="direct:delete-tosca-instance-properties"/> <doTry> @@ -369,13 +403,56 @@ <setHeader name="Content-Type"> <constant>application/json</constant> </setHeader> + <setProperty name="name"> + <simple>${header.name}</simple> + </setProperty> + <setProperty name="version"> + <simple>${header.version}</simple> + </setProperty> + <setProperty name="instanceName"> + <simple>${header.instanceName}</simple> + </setProperty> <setProperty name="common"> <simple>${header.common}</simple> </setProperty> <log loggingLevel="INFO" message="Endpoint to get Common Or Instance Properties: {{clamp.config.acm.runtime.url}}/onap/policy/clamp/acm/v2/commission/getCommonOrInstanceProperties"></log> <toD - uri="{{clamp.config.acm.runtime.url}}/onap/policy/clamp/acm/v2/commission/getCommonOrInstanceProperties?common=${exchangeProperty[common]}&bridgeEndpoint=true&useSystemProperties=true&throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&authMethod=Basic&authUsername={{clamp.config.acm.runtime.userName}}&authPassword={{clamp.config.acm.runtime.password}}&authenticationPreemptive=true&connectionClose=true"/> + uri="{{clamp.config.acm.runtime.url}}/onap/policy/clamp/acm/v2/commission/getCommonOrInstanceProperties?name=${exchangeProperty[name]}&version=${exchangeProperty[version]}&instanceName=${exchangeProperty[instanceName]}&common=${exchangeProperty[common]}&bridgeEndpoint=true&useSystemProperties=true&throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&authMethod=Basic&authUsername={{clamp.config.acm.runtime.userName}}&authPassword={{clamp.config.acm.runtime.password}}&authenticationPreemptive=true&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="get-saved-instance-name-instance-properties"> + <from uri="direct:get-saved-instance-name-instance-properties"/> + <doTry> + <log loggingLevel="INFO" + message="Getting Common Or Instance Properties"/> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeLog('AutomationComposition', 'Getting Saved Instance Name Instance Properties')"/> + <setHeader name="CamelHttpMethod"> + <constant>GET</constant> + </setHeader> + <setHeader name="Content-Type"> + <constant>application/json</constant> + </setHeader> + <setProperty name="name"> + <simple>${header.name}</simple> + </setProperty> + <setProperty name="version"> + <simple>${header.version}</simple> + </setProperty> + <setProperty name="instanceName"> + <simple>${header.instanceName}</simple> + </setProperty> + <log loggingLevel="INFO" + message="Endpoint to get Common Or Instance Properties: {{clamp.config.acm.runtime.url}}/onap/policy/clamp/acm/v2/commission/getSavedInstanceNameInstanceProperties"></log> + <toD + uri="{{clamp.config.acm.runtime.url}}/onap/policy/clamp/acm/v2/commission/getSavedInstanceNameInstanceProperties?name=${exchangeProperty[name]}&version=${exchangeProperty[version]}&instanceName=${exchangeProperty[instanceName]}&bridgeEndpoint=true&useSystemProperties=true&throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&authMethod=Basic&authUsername={{clamp.config.acm.runtime.userName}}&authPassword={{clamp.config.acm.runtime.password}}&authenticationPreemptive=true&connectionClose=true"/> <convertBodyTo type="java.lang.String"/> <doFinally> <to uri="direct:reset-raise-http-exception-flag"/> diff --git a/runtime/src/test/resources/http-cache/third_party_proxy.py b/runtime/src/test/resources/http-cache/third_party_proxy.py index 9c22f3ff5..e116c92ce 100644 --- a/runtime/src/test/resources/http-cache/third_party_proxy.py +++ b/runtime/src/test/resources/http-cache/third_party_proxy.py @@ -5,7 +5,7 @@ # ================================================================================ # Copyright (C) 2018 AT&T Intellectual Property. All rights # reserved. -# Modifications Copyright (C) 2021 Nordix Foundation. +# Modifications Copyright (C) 2021-2022 Nordix Foundation. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -340,6 +340,15 @@ class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler): with open(cached_file_content, 'w+') as f: f.write(self.data_string) return True + elif (self.path.startswith("/onap/policy/clamp/acm/v2/instanceProperties")) and http_type == "PUT": + print("self.path start with PUT /onap/policy/clamp/acm/v2/instanceProperties, updating body to response ...") + if not os.path.exists(cached_file_folder): + os.makedirs(cached_file_folder, 0o777) + with open(cached_file_header, 'w+') as f: + f.write("{\"Content-Length\": \"" + str(len(self.data_string)) + "\", \"Content-Type\": \""+str(self.headers['Content-Type'])+"\"}") + with open(cached_file_content, 'w+') as f: + f.write(self.data_string) + return True elif (self.path.startswith("/onap/policy/clamp/acm/v2/instanceProperties")) and http_type == "DELETE": print("self.path start with /instanceProperties Deleting instance properties, generating response json...") jsonGenerated = "{\"errorDetails\": null,\"affectedControlLoopDefinitions\": [{ \"name\": \"PMSH_Instance1\", \"version\": \"2.3.1\" }]}" |