From 4045d5fd60013534f4ecf85f553ae7da3e32220d Mon Sep 17 00:00:00 2001 From: "saul.gill" Date: Fri, 23 Jul 2021 10:48:25 +0100 Subject: Added endpoint for common or instance properties Runtime-controlloop and Camel endpoionts added Flag common can be used - true common props - false - instance props Changed getServiceTemplate endpoint to return less Added creation of controlloop db to clamp scripts Issue-ID: POLICY-3439 Change-Id: I9d189ca030868b47b46a2e0bc5e731c23fba2a61 Signed-off-by: saul.gill --- .../commissioning/CommissioningProvider.java | 202 ++++++++++++++++++++- .../runtime/main/rest/CommissioningController.java | 79 +++++++- 2 files changed, 271 insertions(+), 10 deletions(-) (limited to 'runtime-controlloop/src/main') diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java index d9dee50bc..891d42072 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java @@ -23,10 +23,10 @@ package org.onap.policy.clamp.controlloop.runtime.commissioning; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.module.jsonSchema.JsonSchema; import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper; 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; @@ -42,6 +42,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.onap.policy.models.tosca.authorative.concepts.ToscaRelationshipType; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplates; @@ -180,6 +181,171 @@ public class CommissioningProvider { return controlLoopElementList; } + /** + * Get the initial node types with common or instance properties. + * + * @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 getInitialNodeTypesMap( + Map fullNodeTypes, boolean common) { + + var tempNodeTypesMap = new HashMap(); + + fullNodeTypes.forEach((key, nodeType) -> { + var tempToscaNodeType = new ToscaNodeType(); + tempToscaNodeType.setName(key); + + var resultantPropertyMap = findCommonOrInstancePropsInNodeTypes( + nodeType, common); + + if (!resultantPropertyMap.isEmpty()) { + tempToscaNodeType.setProperties(resultantPropertyMap); + tempNodeTypesMap.put(key, tempToscaNodeType); + } + }); + return tempNodeTypesMap; + } + + private Map findCommonOrInstancePropsInNodeTypes( + ToscaNodeType nodeType, boolean common) { + + var tempCommonPropertyMap = new HashMap(); + var tempInstancePropertyMap = new HashMap(); + + nodeType.getProperties().forEach((propKey, prop) -> { + + if (prop.getMetadata() != null) { + prop.getMetadata().forEach((k, v) -> { + if (k.equals("common") && v.equals("true") && common) { + tempCommonPropertyMap.put(propKey, prop); + } else if (k.equals("common") && v.equals("false") && !common) { + tempInstancePropertyMap.put(propKey, prop); + } + + }); + } else { + tempInstancePropertyMap.put(propKey, prop); + } + }); + + if (tempCommonPropertyMap.isEmpty() && !common) { + return tempInstancePropertyMap; + } else { + return tempCommonPropertyMap; + } + } + + /** + * Get the node types derived from those that have common properties. + * + * @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 + * @return all node types that have common properties including their children + * @throws PfModelException on errors getting node type with common properties + */ + private Map getFinalNodeTypesMap( + Map initialNodeTypes, + Map filteredNodeTypes) { + 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( + filteredNodeTypes.get(nodeType.getDerivedFrom()).getProperties()); + + tempToscaNodeType.setProperties(finalProps); + } else { + return; + } + filteredNodeTypes.putIfAbsent(key, tempToscaNodeType); + + }); + } + return filteredNodeTypes; + } + + /** + * Get the requested node types with common or instance properties. + * + * @param common boolean indicating common or instance properties + * @param name the name of the definition to get, null for all definitions + * @param version the version of the definition to get, null for all definitions + * @return the node types with common or instance properties + * @throws PfModelException on errors getting node type properties + */ + private Map getCommonOrInstancePropertiesFromNodeTypes( + boolean common, String name, String version) + throws PfModelException { + var serviceTemplates = new ToscaServiceTemplates(); + serviceTemplates.setServiceTemplates(modelsProvider.getServiceTemplateList(name, version)); + var tempNodeTypesMap = + this.getInitialNodeTypesMap(serviceTemplates.getServiceTemplates().get(0).getNodeTypes(), common); + + return this.getFinalNodeTypesMap( + serviceTemplates.getServiceTemplates().get(0).getNodeTypes(), tempNodeTypesMap); + + } + + /** + * Get node templates with appropriate common or instance properties added. + * + * @param initialNodeTemplates map of all the node templates in the specified template + * @param nodeTypeProps map of all the node types that have common or instance properties including children + * @return all node templates with appropriate common or instance properties added + * @throws PfModelException on errors getting map of node templates with common or instance properties added + */ + private Map getDerivedCommonOrInstanceNodeTemplates( + Map initialNodeTemplates, + Map nodeTypeProps) { + + var finalNodeTemplatesMap = new HashMap(); + + initialNodeTemplates.forEach((templateKey, template) -> { + if (nodeTypeProps.containsKey(template.getType())) { + var finalMergedProps = new HashMap(); + + nodeTypeProps.get(template.getType()).getProperties().forEach(finalMergedProps::putIfAbsent); + + template.setProperties(finalMergedProps); + + finalNodeTemplatesMap.put(templateKey, template); + } else { + return; + } + }); + return finalNodeTemplatesMap; + } + + /** + * 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 + * @return the nodes templates with common or instance properties + * @throws PfModelException on errors getting common or instance properties from node_templates + */ + public Map getNodeTemplatesWithCommonOrInstanceProperties( + boolean common, String name, String version) throws PfModelException { + + var commonOrInstanceNodeTypeProps = + this.getCommonOrInstancePropertiesFromNodeTypes(common, name, version); + + var serviceTemplates = new ToscaServiceTemplates(); + serviceTemplates.setServiceTemplates(modelsProvider.getServiceTemplateList(name, version)); + + return this.getDerivedCommonOrInstanceNodeTemplates( + serviceTemplates.getServiceTemplates().get(0).getToscaTopologyTemplate().getNodeTemplates(), + commonOrInstanceNodeTypeProps); + } + /** * Get the requested control loop definitions. * @@ -194,6 +360,30 @@ public class CommissioningProvider { return serviceTemplates.getServiceTemplates().get(0); } + /** + * Get the tosca service template with only required sections. + * + * @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 + * @return the tosca service template + * @throws PfModelException on errors getting tosca service template + */ + public Map getToscaServiceTemplateReduced(String name, String version) throws PfModelException { + var serviceTemplates = new ToscaServiceTemplates(); + serviceTemplates.setServiceTemplates(modelsProvider.getServiceTemplateList(name, version)); + + ToscaServiceTemplate fullTemplate = serviceTemplates.getServiceTemplates().get(0); + + var template = new HashMap(); + template.put("tosca_definitions_version", fullTemplate.getToscaDefinitionsVersion()); + template.put("data_types", fullTemplate.getDataTypes()); + template.put("policy_types", fullTemplate.getPolicyTypes()); + template.put("node_types", fullTemplate.getNodeTypes()); + template.put("topology_template", fullTemplate.getToscaTopologyTemplate()); + + return template; + } + /** * Get the requested json schema. * @@ -203,9 +393,9 @@ public class CommissioningProvider { * @throws JsonProcessingException on errors generating the schema */ public String getToscaServiceTemplateSchema(String section) throws PfModelException, JsonProcessingException { - ObjectMapper mapper = new ObjectMapper(); + var mapper = new ObjectMapper(); mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); - SchemaFactoryWrapper visitor = new SchemaFactoryWrapper(); + var visitor = new SchemaFactoryWrapper(); switch (section) { case "data_types": @@ -234,9 +424,7 @@ public class CommissioningProvider { mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaServiceTemplate.class), visitor); } - JsonSchema jsonSchema = visitor.finalSchema(); - String response = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema); - - return response; + var jsonSchema = visitor.finalSchema(); + return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema); } } diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java index 74548e724..cc4ce16f7 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java @@ -345,10 +345,10 @@ public class CommissioningController extends AbstractRestController { required = false) String version) { try { - ObjectMapper mapper = new ObjectMapper(); + var mapper = new ObjectMapper(); mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); - String response = mapper.writerWithDefaultPrettyPrinter() - .writeValueAsString(provider.getToscaServiceTemplate(name, version)); + var response = mapper.writerWithDefaultPrettyPrinter() + .writeValueAsString(provider.getToscaServiceTemplateReduced(name, version)); return ResponseEntity.ok().body(response); @@ -433,6 +433,79 @@ public class CommissioningController extends AbstractRestController { } } + /** + * Retrieves the Common or Instance Properties for the specified Tosca Service Template. + * + * @param requestId request ID used in ONAP logging + * @param common a flag, true to get common properties, false to get instance properties + * @param name the name of the tosca service template to retrieve + * @param version the version of the tosca service template to get + * @return the specified tosca service template or section Json Schema + */ + // @formatter:off + @GetMapping(value = "/commission/getCommonOrInstanceProperties", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Query details of the requested tosca service template common or instance properties", + notes = "Queries details of the requested commissioned tosca service template json common" + + "or instance properties, returning all tosca service template common or instance property details", + response = ToscaServiceTemplate.class, + tags = {"Clamp Control Loop Commissioning API"}, + 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 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 = true) @RequestParam( + value = "version", + required = false) String version) { + try { + return ResponseEntity.ok().body(provider.getNodeTemplatesWithCommonOrInstanceProperties( + common, name, version)); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("Get of common or instance properties failed", e); + var resp = new CommissioningResponse(); + resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); + } + } + /** * Queries the elements of a specific control loop. * -- cgit 1.2.3-korg