From 69c24994501aead95d5ee9fa172fff659ae34fa4 Mon Sep 17 00:00:00 2001 From: xuegao Date: Fri, 6 Dec 2019 10:40:49 +0100 Subject: Update service object Seperate the procedure to install service and loops. Issue-ID: CLAMP-566 Change-Id: Ied7143ce8849baffda7678e82f4d6c4d9f1443d9 Signed-off-by: xuegao --- extra/sql/bulkload/create-tables.sql | 1 + .../config/spring/SdcControllerConfiguration.java | 4 +- .../clds/sdc/controller/SdcSingleController.java | 2 +- .../sdc/controller/installer/CsarInstaller.java | 34 --- .../java/org/onap/clamp/loop/CsarInstaller.java | 327 +++++++++++++++++++++ src/main/java/org/onap/clamp/loop/Loop.java | 2 +- .../org/onap/clamp/loop/LoopCsarInstaller.java | 280 ------------------ .../java/org/onap/clamp/loop/service/Service.java | 6 +- .../onap/clamp/loop/service/ServiceRepository.java | 32 ++ .../sdc/controller/SdcSingleControllerItCase.java | 2 +- .../org/onap/clamp/loop/CsarInstallerItCase.java | 9 +- .../java/org/onap/clamp/loop/LoopToJsonTest.java | 2 +- src/test/java/org/onap/clamp/loop/ServiceTest.java | 6 +- ...OperationalPolicyRepresentationBuilderTest.java | 2 +- 14 files changed, 382 insertions(+), 327 deletions(-) delete mode 100644 src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarInstaller.java create mode 100644 src/main/java/org/onap/clamp/loop/CsarInstaller.java delete mode 100644 src/main/java/org/onap/clamp/loop/LoopCsarInstaller.java create mode 100644 src/main/java/org/onap/clamp/loop/service/ServiceRepository.java diff --git a/extra/sql/bulkload/create-tables.sql b/extra/sql/bulkload/create-tables.sql index dafd80034..85b8f85f9 100644 --- a/extra/sql/bulkload/create-tables.sql +++ b/extra/sql/bulkload/create-tables.sql @@ -57,6 +57,7 @@ name varchar(255) not null, resource_details json, service_details json, + version varchar(255), primary key (service_uuid) ) engine=InnoDB; diff --git a/src/main/java/org/onap/clamp/clds/config/spring/SdcControllerConfiguration.java b/src/main/java/org/onap/clamp/clds/config/spring/SdcControllerConfiguration.java index b4794c940..261288503 100644 --- a/src/main/java/org/onap/clamp/clds/config/spring/SdcControllerConfiguration.java +++ b/src/main/java/org/onap/clamp/clds/config/spring/SdcControllerConfiguration.java @@ -37,7 +37,7 @@ import org.onap.clamp.clds.config.sdc.SdcControllersConfiguration; import org.onap.clamp.clds.exception.sdc.controller.SdcControllerException; import org.onap.clamp.clds.sdc.controller.SdcSingleController; import org.onap.clamp.clds.sdc.controller.SdcSingleControllerStatus; -import org.onap.clamp.clds.sdc.controller.installer.CsarInstaller; +import org.onap.clamp.loop.CsarInstaller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; @@ -58,7 +58,7 @@ public class SdcControllerConfiguration { @Autowired public SdcControllerConfiguration(ClampProperties clampProp, - @Qualifier("loopInstaller") CsarInstaller csarInstaller) { + @Qualifier("csarInstaller") CsarInstaller csarInstaller) { this.clampProp = clampProp; this.csarInstaller = csarInstaller; } diff --git a/src/main/java/org/onap/clamp/clds/sdc/controller/SdcSingleController.java b/src/main/java/org/onap/clamp/clds/sdc/controller/SdcSingleController.java index 3e684f425..bd18baea6 100644 --- a/src/main/java/org/onap/clamp/clds/sdc/controller/SdcSingleController.java +++ b/src/main/java/org/onap/clamp/clds/sdc/controller/SdcSingleController.java @@ -39,8 +39,8 @@ import org.onap.clamp.clds.exception.sdc.controller.SdcControllerException; import org.onap.clamp.clds.exception.sdc.controller.SdcDownloadException; import org.onap.clamp.clds.sdc.controller.installer.BlueprintArtifact; import org.onap.clamp.clds.sdc.controller.installer.CsarHandler; -import org.onap.clamp.clds.sdc.controller.installer.CsarInstaller; import org.onap.clamp.clds.util.LoggingUtils; +import org.onap.clamp.loop.CsarInstaller; import org.onap.sdc.api.IDistributionClient; import org.onap.sdc.api.consumer.IDistributionStatusMessage; import org.onap.sdc.api.consumer.INotificationCallback; diff --git a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarInstaller.java b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarInstaller.java deleted file mode 100644 index 10e2790f6..000000000 --- a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarInstaller.java +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP CLAMP - * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights - * reserved. - * ================================================================================ - * 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. - * ============LICENSE_END============================================ - * =================================================================== - * - */ - -package org.onap.clamp.clds.sdc.controller.installer; - -import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException; - -public interface CsarInstaller { - String TEMPLATE_NAME_PREFIX = "DCAE-Designer-Template-"; - - boolean isCsarAlreadyDeployed(CsarHandler csar) throws SdcArtifactInstallerException; - - public void installTheCsar(CsarHandler csar) throws SdcArtifactInstallerException, InterruptedException; -} diff --git a/src/main/java/org/onap/clamp/loop/CsarInstaller.java b/src/main/java/org/onap/clamp/loop/CsarInstaller.java new file mode 100644 index 000000000..3f69e116c --- /dev/null +++ b/src/main/java/org/onap/clamp/loop/CsarInstaller.java @@ -0,0 +1,327 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * 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. + * ============LICENSE_END============================================ + * =================================================================== + * + */ + +package org.onap.clamp.loop; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.google.gson.JsonObject; + +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.json.simple.parser.ParseException; +import org.onap.clamp.clds.client.DcaeInventoryServices; +import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException; +import org.onap.clamp.clds.model.dcae.DcaeInventoryResponse; +import org.onap.clamp.clds.sdc.controller.installer.BlueprintArtifact; +import org.onap.clamp.clds.sdc.controller.installer.BlueprintParser; +import org.onap.clamp.clds.sdc.controller.installer.ChainGenerator; +import org.onap.clamp.clds.sdc.controller.installer.CsarHandler; +import org.onap.clamp.clds.sdc.controller.installer.MicroService; +import org.onap.clamp.clds.util.JsonUtils; +import org.onap.clamp.clds.util.drawing.SvgFacade; +import org.onap.clamp.loop.service.Service; +import org.onap.clamp.loop.service.ServiceRepository; +import org.onap.clamp.policy.Policy; +import org.onap.clamp.policy.microservice.MicroServicePolicy; +import org.onap.clamp.policy.operational.OperationalPolicy; +import org.onap.sdc.tosca.parser.api.IEntityDetails; +import org.onap.sdc.tosca.parser.elements.queries.EntityQuery; +import org.onap.sdc.tosca.parser.elements.queries.TopologyTemplateQuery; +import org.onap.sdc.tosca.parser.enums.EntityTemplateType; +import org.onap.sdc.tosca.parser.enums.SdcTypes; +import org.onap.sdc.toscaparser.api.NodeTemplate; +import org.onap.sdc.toscaparser.api.Property; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.yaml.snakeyaml.Yaml; + +/** + * This class will be instantiated by spring config, and used by Sdc Controller. + * There is no state kept by the bean. It's used to deploy the csar/notification + * received from SDC in DB. + */ +@Component +@Qualifier("csarInstaller") +public class CsarInstaller { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(CsarInstaller.class); + public static final String CONTROL_NAME_PREFIX = "ClosedLoop-"; + public static final String GET_INPUT_BLUEPRINT_PARAM = "get_input"; + // This will be used later as the policy scope + public static final String MODEL_NAME_PREFIX = "Loop_"; + + @Autowired + LoopsRepository loopRepository; + + @Autowired + ServiceRepository serviceRepository; + + @Autowired + BlueprintParser blueprintParser; + + @Autowired + ChainGenerator chainGenerator; + + @Autowired + DcaeInventoryServices dcaeInventoryService; + + @Autowired + private SvgFacade svgFacade; + + /** + * Verify whether Csar is deployed. + * + * @param csar The Csar Handler + * @return The flag indicating whether Csar is deployed + * @throws SdcArtifactInstallerException The SdcArtifactInstallerException + */ + public boolean isCsarAlreadyDeployed(CsarHandler csar) throws SdcArtifactInstallerException { + boolean alreadyInstalled = true; + JsonObject serviceDetails = JsonUtils.GSON.fromJson( + JsonUtils.GSON.toJson(csar.getSdcCsarHelper().getServiceMetadataAllProperties()), JsonObject.class); + alreadyInstalled = alreadyInstalled + && serviceRepository.existsById(serviceDetails.get("UUID").getAsString()); + + for (Entry blueprint : csar.getMapOfBlueprints().entrySet()) { + alreadyInstalled = alreadyInstalled + && loopRepository.existsById(Loop.generateLoopName(csar.getSdcNotification().getServiceName(), + csar.getSdcNotification().getServiceVersion(), + blueprint.getValue().getResourceAttached().getResourceInstanceName(), + blueprint.getValue().getBlueprintArtifactName())); + } + + return alreadyInstalled; + } + + /** + * Install the service and loops from the csar. + * + * @param csar The Csar Handler + * @throws SdcArtifactInstallerException The SdcArtifactInstallerException + * @throws InterruptedException The InterruptedException + */ + public void installTheCsar(CsarHandler csar) throws SdcArtifactInstallerException, InterruptedException { + logger.info("Installing the CSAR " + csar.getFilePath()); + installTheLoop(csar, installTheService(csar)); + logger.info("Successfully installed the CSAR " + csar.getFilePath()); + } + + /** + * Install the Loop from the csar. + * + * @param csar The Csar Handler + * @param service The service object that is related to the loop + * @throws SdcArtifactInstallerException The SdcArtifactInstallerException + * @throws InterruptedException The InterruptedException + */ + @Transactional(propagation = Propagation.REQUIRED) + public void installTheLoop(CsarHandler csar, Service service) + throws SdcArtifactInstallerException, InterruptedException { + try { + logger.info("Installing the Loops"); + for (Entry blueprint : csar.getMapOfBlueprints().entrySet()) { + logger.info("Processing blueprint " + blueprint.getValue().getBlueprintArtifactName()); + loopRepository.save(createLoopFromBlueprint(csar, blueprint.getValue(), service)); + } + logger.info("Successfully installed the Loops "); + } catch (IOException e) { + throw new SdcArtifactInstallerException("Exception caught during the Loop installation in database", e); + } catch (ParseException e) { + throw new SdcArtifactInstallerException("Exception caught during the Dcae query to get ServiceTypeId", e); + } + } + + /** + * Install the Service from the csar. + * + * @param csar The Csar Handler + * @return The service object + */ + @Transactional + public Service installTheService(CsarHandler csar) { + logger.info("Start to install the Service from csar"); + JsonObject serviceDetails = JsonUtils.GSON.fromJson( + JsonUtils.GSON.toJson(csar.getSdcCsarHelper().getServiceMetadataAllProperties()), JsonObject.class); + + // Add properties details for each type, VfModule, VF, VFC, .... + JsonObject resourcesProp = createServicePropertiesByType(csar); + resourcesProp.add("VFModule", createVfModuleProperties(csar)); + + Service modelService = new Service(serviceDetails, resourcesProp, + csar.getSdcNotification().getServiceVersion()); + + serviceRepository.save(modelService); + logger.info("Successfully installed the Service"); + return modelService; + } + + private Loop createLoopFromBlueprint(CsarHandler csar, BlueprintArtifact blueprintArtifact, Service service) + throws IOException, ParseException, InterruptedException { + Loop newLoop = new Loop(); + newLoop.setBlueprint(blueprintArtifact.getDcaeBlueprint()); + newLoop.setName(Loop.generateLoopName(csar.getSdcNotification().getServiceName(), + csar.getSdcNotification().getServiceVersion(), + blueprintArtifact.getResourceAttached().getResourceInstanceName(), + blueprintArtifact.getBlueprintArtifactName())); + newLoop.setLastComputedState(LoopState.DESIGN); + + List microServicesChain = chainGenerator + .getChainOfMicroServices(blueprintParser.getMicroServices(blueprintArtifact.getDcaeBlueprint())); + if (microServicesChain.isEmpty()) { + microServicesChain = blueprintParser.fallbackToOneMicroService(blueprintArtifact.getDcaeBlueprint()); + } + newLoop.setModelService(service); + newLoop.setMicroServicePolicies( + createMicroServicePolicies(microServicesChain, csar, blueprintArtifact, newLoop)); + newLoop.setOperationalPolicies(createOperationalPolicies(csar, blueprintArtifact, newLoop)); + + newLoop.setSvgRepresentation(svgFacade.getSvgImage(microServicesChain)); + newLoop.setGlobalPropertiesJson(createGlobalPropertiesJson(blueprintArtifact, newLoop)); + + DcaeInventoryResponse dcaeResponse = queryDcaeToGetServiceTypeId(blueprintArtifact); + newLoop.setDcaeBlueprintId(dcaeResponse.getTypeId()); + return newLoop; + } + + private HashSet createOperationalPolicies(CsarHandler csar, BlueprintArtifact blueprintArtifact, + Loop newLoop) { + return new HashSet<>(Arrays.asList(new OperationalPolicy(Policy.generatePolicyName("OPERATIONAL", + csar.getSdcNotification().getServiceName(), csar.getSdcNotification().getServiceVersion(), + blueprintArtifact.getResourceAttached().getResourceInstanceName(), + blueprintArtifact.getBlueprintArtifactName()), newLoop, new JsonObject()))); + } + + private HashSet createMicroServicePolicies(List microServicesChain, + CsarHandler csar, BlueprintArtifact blueprintArtifact, Loop newLoop) throws IOException { + HashSet newSet = new HashSet<>(); + + for (MicroService microService : microServicesChain) { + MicroServicePolicy microServicePolicy = new MicroServicePolicy( + Policy.generatePolicyName(microService.getName(), csar.getSdcNotification().getServiceName(), + csar.getSdcNotification().getServiceVersion(), + blueprintArtifact.getResourceAttached().getResourceInstanceName(), + blueprintArtifact.getBlueprintArtifactName()), + microService.getModelType(), csar.getPolicyModelYaml().orElse(""), false, + new HashSet<>(Arrays.asList(newLoop))); + + newSet.add(microServicePolicy); + microService.setMappedNameJpa(microServicePolicy.getName()); + } + return newSet; + } + + private JsonObject createGlobalPropertiesJson(BlueprintArtifact blueprintArtifact, Loop newLoop) { + JsonObject globalProperties = new JsonObject(); + globalProperties.add("dcaeDeployParameters", getAllBlueprintParametersInJson(blueprintArtifact, newLoop)); + return globalProperties; + } + + private static JsonObject createVfModuleProperties(CsarHandler csar) { + JsonObject vfModuleProps = new JsonObject(); + // Loop on all Groups defined in the service (VFModule entries type: + // org.openecomp.groups.VfModule) + for (IEntityDetails entity : csar.getSdcCsarHelper().getEntity( + EntityQuery.newBuilder(EntityTemplateType.GROUP).build(), + TopologyTemplateQuery.newBuilder(SdcTypes.SERVICE).build(), false)) { + // Get all metadata info + JsonObject allVfProps = (JsonObject) JsonUtils.GSON.toJsonTree(entity.getMetadata().getAllProperties()); + vfModuleProps.add(entity.getMetadata().getAllProperties().get("vfModuleModelName"), allVfProps); + // now append the properties section so that we can also have isBase, + // volume_group, etc ... fields under the VFmodule name + for (Entry additionalProp : entity.getProperties().entrySet()) { + allVfProps.add(additionalProp.getValue().getName(), + JsonUtils.GSON.toJsonTree(additionalProp.getValue().getValue())); + } + } + return vfModuleProps; + } + + private static JsonObject createServicePropertiesByType(CsarHandler csar) { + JsonObject resourcesProp = new JsonObject(); + // Iterate on all types defined in the tosca lib + for (SdcTypes type : SdcTypes.values()) { + JsonObject resourcesPropByType = new JsonObject(); + // For each type, get the metadata of each nodetemplate + for (NodeTemplate nodeTemplate : csar.getSdcCsarHelper().getServiceNodeTemplateBySdcType(type)) { + resourcesPropByType.add(nodeTemplate.getName(), + JsonUtils.GSON.toJsonTree(nodeTemplate.getMetaData().getAllProperties())); + } + resourcesProp.add(type.getValue(), resourcesPropByType); + } + return resourcesProp; + } + + private JsonObject getAllBlueprintParametersInJson(BlueprintArtifact blueprintArtifact, Loop newLoop) { + JsonObject node = new JsonObject(); + Yaml yaml = new Yaml(); + Map inputsNodes = ((Map) ((Map) yaml + .load(blueprintArtifact.getDcaeBlueprint())).get("inputs")); + inputsNodes.entrySet().stream().filter(e -> !e.getKey().contains("policy_id")).forEach(elem -> { + Object defaultValue = ((Map) elem.getValue()).get("default"); + if (defaultValue != null) { + addPropertyToNode(node, elem.getKey(), defaultValue); + } else { + node.addProperty(elem.getKey(), ""); + } + }); + // For Dublin only one micro service is expected + node.addProperty("policy_id", ((MicroServicePolicy) newLoop.getMicroServicePolicies().toArray()[0]).getName()); + return node; + } + + /** + * ll get the latest version of the artifact (version can be specified to DCAE + * call). + * + * @return The DcaeInventoryResponse object containing the dcae values + */ + private DcaeInventoryResponse queryDcaeToGetServiceTypeId(BlueprintArtifact blueprintArtifact) + throws IOException, ParseException, InterruptedException { + return dcaeInventoryService.getDcaeInformation(blueprintArtifact.getBlueprintArtifactName(), + blueprintArtifact.getBlueprintInvariantServiceUuid(), + blueprintArtifact.getResourceAttached().getResourceInvariantUUID()); + } + + private void addPropertyToNode(JsonObject node, String key, Object value) { + if (value instanceof String) { + node.addProperty(key, (String) value); + } else if (value instanceof Number) { + node.addProperty(key, (Number) value); + } else if (value instanceof Boolean) { + node.addProperty(key, (Boolean) value); + } else if (value instanceof Character) { + node.addProperty(key, (Character) value); + } else { + node.addProperty(key, JsonUtils.GSON.toJson(value)); + } + } +} diff --git a/src/main/java/org/onap/clamp/loop/Loop.java b/src/main/java/org/onap/clamp/loop/Loop.java index ef70ba80e..bf6836607 100644 --- a/src/main/java/org/onap/clamp/loop/Loop.java +++ b/src/main/java/org/onap/clamp/loop/Loop.java @@ -111,7 +111,7 @@ public class Loop implements Serializable { private JsonObject globalPropertiesJson; @Expose - @ManyToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL) + @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "service_uuid") private Service modelService; diff --git a/src/main/java/org/onap/clamp/loop/LoopCsarInstaller.java b/src/main/java/org/onap/clamp/loop/LoopCsarInstaller.java deleted file mode 100644 index 55009bc22..000000000 --- a/src/main/java/org/onap/clamp/loop/LoopCsarInstaller.java +++ /dev/null @@ -1,280 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP CLAMP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights - * reserved. - * ================================================================================ - * 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. - * ============LICENSE_END============================================ - * =================================================================== - * - */ - -package org.onap.clamp.loop; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import com.google.gson.JsonObject; - -import java.io.IOException; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.json.simple.parser.ParseException; -import org.onap.clamp.clds.client.DcaeInventoryServices; -import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException; -import org.onap.clamp.clds.model.dcae.DcaeInventoryResponse; -import org.onap.clamp.clds.sdc.controller.installer.BlueprintArtifact; -import org.onap.clamp.clds.sdc.controller.installer.BlueprintParser; -import org.onap.clamp.clds.sdc.controller.installer.ChainGenerator; -import org.onap.clamp.clds.sdc.controller.installer.CsarHandler; -import org.onap.clamp.clds.sdc.controller.installer.CsarInstaller; -import org.onap.clamp.clds.sdc.controller.installer.MicroService; -import org.onap.clamp.clds.util.JsonUtils; -import org.onap.clamp.clds.util.drawing.SvgFacade; -import org.onap.clamp.loop.service.Service; -import org.onap.clamp.policy.Policy; -import org.onap.clamp.policy.microservice.MicroServicePolicy; -import org.onap.clamp.policy.operational.OperationalPolicy; -import org.onap.sdc.tosca.parser.api.IEntityDetails; -import org.onap.sdc.tosca.parser.elements.queries.EntityQuery; -import org.onap.sdc.tosca.parser.elements.queries.TopologyTemplateQuery; -import org.onap.sdc.tosca.parser.enums.EntityTemplateType; -import org.onap.sdc.tosca.parser.enums.SdcTypes; -import org.onap.sdc.toscaparser.api.NodeTemplate; -import org.onap.sdc.toscaparser.api.Property; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; -import org.yaml.snakeyaml.Yaml; - -/** - * This class will be instantiated by spring config, and used by Sdc Controller. - * There is no state kept by the bean. It's used to deploy the csar/notification - * received from SDC in DB. - */ -@Component -@Qualifier("loopInstaller") -public class LoopCsarInstaller implements CsarInstaller { - - private static final EELFLogger logger = EELFManager.getInstance().getLogger(LoopCsarInstaller.class); - public static final String CONTROL_NAME_PREFIX = "ClosedLoop-"; - public static final String GET_INPUT_BLUEPRINT_PARAM = "get_input"; - // This will be used later as the policy scope - public static final String MODEL_NAME_PREFIX = "Loop_"; - - @Autowired - LoopsRepository loopRepository; - - @Autowired - BlueprintParser blueprintParser; - - @Autowired - ChainGenerator chainGenerator; - - @Autowired - DcaeInventoryServices dcaeInventoryService; - - @Autowired - private SvgFacade svgFacade; - - @Override - public boolean isCsarAlreadyDeployed(CsarHandler csar) throws SdcArtifactInstallerException { - boolean alreadyInstalled = true; - for (Entry blueprint : csar.getMapOfBlueprints().entrySet()) { - alreadyInstalled = alreadyInstalled - && loopRepository.existsById(Loop.generateLoopName(csar.getSdcNotification().getServiceName(), - csar.getSdcNotification().getServiceVersion(), - blueprint.getValue().getResourceAttached().getResourceInstanceName(), - blueprint.getValue().getBlueprintArtifactName())); - } - return alreadyInstalled; - } - - @Override - @Transactional(propagation = Propagation.REQUIRED) - public void installTheCsar(CsarHandler csar) throws SdcArtifactInstallerException, InterruptedException { - try { - logger.info("Installing the CSAR " + csar.getFilePath()); - for (Entry blueprint : csar.getMapOfBlueprints().entrySet()) { - logger.info("Processing blueprint " + blueprint.getValue().getBlueprintArtifactName()); - loopRepository.save(createLoopFromBlueprint(csar, blueprint.getValue())); - } - logger.info("Successfully installed the CSAR " + csar.getFilePath()); - } catch (IOException e) { - throw new SdcArtifactInstallerException("Exception caught during the Csar installation in database", e); - } catch (ParseException e) { - throw new SdcArtifactInstallerException("Exception caught during the Dcae query to get ServiceTypeId", e); - } - } - - private Loop createLoopFromBlueprint(CsarHandler csar, BlueprintArtifact blueprintArtifact) - throws IOException, ParseException, InterruptedException { - Loop newLoop = new Loop(); - newLoop.setBlueprint(blueprintArtifact.getDcaeBlueprint()); - newLoop.setName(Loop.generateLoopName(csar.getSdcNotification().getServiceName(), - csar.getSdcNotification().getServiceVersion(), - blueprintArtifact.getResourceAttached().getResourceInstanceName(), - blueprintArtifact.getBlueprintArtifactName())); - newLoop.setLastComputedState(LoopState.DESIGN); - - List microServicesChain = chainGenerator - .getChainOfMicroServices(blueprintParser.getMicroServices(blueprintArtifact.getDcaeBlueprint())); - if (microServicesChain.isEmpty()) { - microServicesChain = blueprintParser.fallbackToOneMicroService(blueprintArtifact.getDcaeBlueprint()); - } - newLoop.setModelService(createServiceModel(csar)); - newLoop.setMicroServicePolicies( - createMicroServicePolicies(microServicesChain, csar, blueprintArtifact, newLoop)); - newLoop.setOperationalPolicies(createOperationalPolicies(csar, blueprintArtifact, newLoop)); - - newLoop.setSvgRepresentation(svgFacade.getSvgImage(microServicesChain)); - newLoop.setGlobalPropertiesJson(createGlobalPropertiesJson(blueprintArtifact, newLoop)); - - DcaeInventoryResponse dcaeResponse = queryDcaeToGetServiceTypeId(blueprintArtifact); - newLoop.setDcaeBlueprintId(dcaeResponse.getTypeId()); - return newLoop; - } - - private HashSet createOperationalPolicies(CsarHandler csar, BlueprintArtifact blueprintArtifact, - Loop newLoop) { - return new HashSet<>(Arrays.asList(new OperationalPolicy(Policy.generatePolicyName("OPERATIONAL", - csar.getSdcNotification().getServiceName(), csar.getSdcNotification().getServiceVersion(), - blueprintArtifact.getResourceAttached().getResourceInstanceName(), - blueprintArtifact.getBlueprintArtifactName()), newLoop, new JsonObject()))); - } - - private HashSet createMicroServicePolicies(List microServicesChain, - CsarHandler csar, BlueprintArtifact blueprintArtifact, Loop newLoop) throws IOException { - HashSet newSet = new HashSet<>(); - - for (MicroService microService : microServicesChain) { - MicroServicePolicy microServicePolicy = new MicroServicePolicy( - Policy.generatePolicyName(microService.getName(), csar.getSdcNotification().getServiceName(), - csar.getSdcNotification().getServiceVersion(), - blueprintArtifact.getResourceAttached().getResourceInstanceName(), - blueprintArtifact.getBlueprintArtifactName()), - microService.getModelType(), csar.getPolicyModelYaml().orElse(""), false, - new HashSet<>(Arrays.asList(newLoop))); - - newSet.add(microServicePolicy); - microService.setMappedNameJpa(microServicePolicy.getName()); - } - return newSet; - } - - private JsonObject createGlobalPropertiesJson(BlueprintArtifact blueprintArtifact, Loop newLoop) { - JsonObject globalProperties = new JsonObject(); - globalProperties.add("dcaeDeployParameters", getAllBlueprintParametersInJson(blueprintArtifact, newLoop)); - return globalProperties; - } - - private static JsonObject createVfModuleProperties(CsarHandler csar) { - JsonObject vfModuleProps = new JsonObject(); - // Loop on all Groups defined in the service (VFModule entries type: - // org.openecomp.groups.VfModule) - for (IEntityDetails entity : csar.getSdcCsarHelper().getEntity( - EntityQuery.newBuilder(EntityTemplateType.GROUP).build(), - TopologyTemplateQuery.newBuilder(SdcTypes.SERVICE).build(), false)) { - // Get all metadata info - JsonObject allVfProps = (JsonObject) JsonUtils.GSON.toJsonTree(entity.getMetadata().getAllProperties()); - vfModuleProps.add(entity.getMetadata().getAllProperties().get("vfModuleModelName"), allVfProps); - // now append the properties section so that we can also have isBase, - // volume_group, etc ... fields under the VFmodule name - for (Entry additionalProp : entity.getProperties().entrySet()) { - allVfProps.add(additionalProp.getValue().getName(), - JsonUtils.GSON.toJsonTree(additionalProp.getValue().getValue())); - } - } - return vfModuleProps; - } - - private static JsonObject createServicePropertiesByType(CsarHandler csar) { - JsonObject resourcesProp = new JsonObject(); - // Iterate on all types defined in the tosca lib - for (SdcTypes type : SdcTypes.values()) { - JsonObject resourcesPropByType = new JsonObject(); - // For each type, get the metadata of each nodetemplate - for (NodeTemplate nodeTemplate : csar.getSdcCsarHelper().getServiceNodeTemplateBySdcType(type)) { - resourcesPropByType.add(nodeTemplate.getName(), - JsonUtils.GSON.toJsonTree(nodeTemplate.getMetaData().getAllProperties())); - } - resourcesProp.add(type.getValue(), resourcesPropByType); - } - return resourcesProp; - } - - private Service createServiceModel(CsarHandler csar) { - JsonObject serviceDetails = JsonUtils.GSON.fromJson( - JsonUtils.GSON.toJson(csar.getSdcCsarHelper().getServiceMetadataAllProperties()), JsonObject.class); - - // Add properties details for each type, VfModule, VF, VFC, .... - JsonObject resourcesProp = createServicePropertiesByType(csar); - resourcesProp.add("VFModule", createVfModuleProperties(csar)); - - Service modelService = new Service(serviceDetails, resourcesProp); - - return modelService; - } - - private JsonObject getAllBlueprintParametersInJson(BlueprintArtifact blueprintArtifact, Loop newLoop) { - JsonObject node = new JsonObject(); - Yaml yaml = new Yaml(); - Map inputsNodes = ((Map) ((Map) yaml - .load(blueprintArtifact.getDcaeBlueprint())).get("inputs")); - inputsNodes.entrySet().stream().filter(e -> !e.getKey().contains("policy_id")).forEach(elem -> { - Object defaultValue = ((Map) elem.getValue()).get("default"); - if (defaultValue != null) { - addPropertyToNode(node, elem.getKey(), defaultValue); - } else { - node.addProperty(elem.getKey(), ""); - } - }); - // For Dublin only one micro service is expected - node.addProperty("policy_id", ((MicroServicePolicy) newLoop.getMicroServicePolicies().toArray()[0]).getName()); - return node; - } - - /** - * ll get the latest version of the artifact (version can be specified to DCAE - * call). - * - * @return The DcaeInventoryResponse object containing the dcae values - */ - private DcaeInventoryResponse queryDcaeToGetServiceTypeId(BlueprintArtifact blueprintArtifact) - throws IOException, ParseException, InterruptedException { - return dcaeInventoryService.getDcaeInformation(blueprintArtifact.getBlueprintArtifactName(), - blueprintArtifact.getBlueprintInvariantServiceUuid(), - blueprintArtifact.getResourceAttached().getResourceInvariantUUID()); - } - - private void addPropertyToNode(JsonObject node, String key, Object value) { - if (value instanceof String) { - node.addProperty(key, (String) value); - } else if (value instanceof Number) { - node.addProperty(key, (Number) value); - } else if (value instanceof Boolean) { - node.addProperty(key, (Boolean) value); - } else if (value instanceof Character) { - node.addProperty(key, (Character) value); - } else { - node.addProperty(key, JsonUtils.GSON.toJson(value)); - } - } -} diff --git a/src/main/java/org/onap/clamp/loop/service/Service.java b/src/main/java/org/onap/clamp/loop/service/Service.java index ac1216b9d..115f9f768 100644 --- a/src/main/java/org/onap/clamp/loop/service/Service.java +++ b/src/main/java/org/onap/clamp/loop/service/Service.java @@ -62,6 +62,9 @@ public class Service implements Serializable { @Column(nullable = false, name = "name") private String name; + @Column(name = "version") + private String version; + @Expose @Type(type = "json") @Column(columnDefinition = "json", name = "service_details") @@ -81,11 +84,12 @@ public class Service implements Serializable { /** * Constructor. */ - public Service(JsonObject serviceDetails, JsonObject resourceDetails) { + public Service(JsonObject serviceDetails, JsonObject resourceDetails, String version) { this.name = serviceDetails.get("name").getAsString(); this.serviceUuid = serviceDetails.get("UUID").getAsString(); this.serviceDetails = serviceDetails; this.resourceDetails = resourceDetails; + this.version = version; } public String getServiceUuid() { diff --git a/src/main/java/org/onap/clamp/loop/service/ServiceRepository.java b/src/main/java/org/onap/clamp/loop/service/ServiceRepository.java new file mode 100644 index 000000000..a6c5ff187 --- /dev/null +++ b/src/main/java/org/onap/clamp/loop/service/ServiceRepository.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * 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. + * ============LICENSE_END============================================ + * =================================================================== + * + */ + +package org.onap.clamp.loop.service; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ServiceRepository extends CrudRepository { + +} diff --git a/src/test/java/org/onap/clamp/clds/it/sdc/controller/SdcSingleControllerItCase.java b/src/test/java/org/onap/clamp/clds/it/sdc/controller/SdcSingleControllerItCase.java index 695b85166..2cbabbe8c 100644 --- a/src/test/java/org/onap/clamp/clds/it/sdc/controller/SdcSingleControllerItCase.java +++ b/src/test/java/org/onap/clamp/clds/it/sdc/controller/SdcSingleControllerItCase.java @@ -45,7 +45,7 @@ import org.onap.clamp.clds.exception.sdc.controller.SdcControllerException; import org.onap.clamp.clds.sdc.controller.SdcSingleController; import org.onap.clamp.clds.sdc.controller.SdcSingleControllerStatus; import org.onap.clamp.clds.sdc.controller.installer.CsarHandler; -import org.onap.clamp.clds.sdc.controller.installer.CsarInstaller; +import org.onap.clamp.loop.CsarInstaller; import org.onap.sdc.api.notification.IArtifactInfo; import org.onap.sdc.api.notification.INotificationData; import org.onap.sdc.api.notification.IResourceInstance; diff --git a/src/test/java/org/onap/clamp/loop/CsarInstallerItCase.java b/src/test/java/org/onap/clamp/loop/CsarInstallerItCase.java index e3271c7a6..df952aa16 100644 --- a/src/test/java/org/onap/clamp/loop/CsarInstallerItCase.java +++ b/src/test/java/org/onap/clamp/loop/CsarInstallerItCase.java @@ -48,9 +48,9 @@ import org.onap.clamp.clds.exception.sdc.controller.CsarHandlerException; import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException; import org.onap.clamp.clds.sdc.controller.installer.BlueprintArtifact; import org.onap.clamp.clds.sdc.controller.installer.CsarHandler; -import org.onap.clamp.clds.sdc.controller.installer.CsarInstaller; import org.onap.clamp.clds.util.JsonUtils; import org.onap.clamp.clds.util.ResourceFileUtil; +import org.onap.clamp.loop.service.ServiceRepository; import org.onap.clamp.policy.microservice.MicroServicePolicy; import org.onap.sdc.api.notification.IArtifactInfo; import org.onap.sdc.api.notification.INotificationData; @@ -83,7 +83,10 @@ public class CsarInstallerItCase { private LoopsRepository loopsRepo; @Autowired - @Qualifier("loopInstaller") + ServiceRepository serviceRepository; + + @Autowired + @Qualifier("csarInstaller") private CsarInstaller csarInstaller; private BlueprintArtifact buildFakeBuildprintArtifact(String instanceName, String invariantResourceUuid, @@ -186,6 +189,8 @@ public class CsarInstallerItCase { String generatedName = RandomStringUtils.randomAlphanumeric(5); CsarHandler csar = buildFakeCsarHandler(generatedName); csarInstaller.installTheCsar(csar); + assertThat(serviceRepository + .existsById("63cac700-ab9a-4115-a74f-7eac85e3fce0")).isTrue(); assertThat(loopsRepo .existsById(Loop.generateLoopName(generatedName, "1.0", RESOURCE_INSTANCE_NAME_RESOURCE1, "tca.yaml"))) .isTrue(); diff --git a/src/test/java/org/onap/clamp/loop/LoopToJsonTest.java b/src/test/java/org/onap/clamp/loop/LoopToJsonTest.java index b68bf48a0..68fe487ef 100644 --- a/src/test/java/org/onap/clamp/loop/LoopToJsonTest.java +++ b/src/test/java/org/onap/clamp/loop/LoopToJsonTest.java @@ -126,7 +126,7 @@ public class LoopToJsonTest { JsonObject jsonModel = new GsonBuilder().create() .fromJson(ResourceFileUtil.getResourceAsString("tosca/model-properties.json"), JsonObject.class); Service service = new Service(jsonModel.get("serviceDetails").getAsJsonObject(), - jsonModel.get("resourceDetails").getAsJsonObject()); + jsonModel.get("resourceDetails").getAsJsonObject(), "1.0"); loopTest2.setModelService(service); String jsonSerialized = JsonUtils.GSON_JPA_MODEL.toJson(loopTest2); diff --git a/src/test/java/org/onap/clamp/loop/ServiceTest.java b/src/test/java/org/onap/clamp/loop/ServiceTest.java index 45de5385e..2b6fab8b6 100644 --- a/src/test/java/org/onap/clamp/loop/ServiceTest.java +++ b/src/test/java/org/onap/clamp/loop/ServiceTest.java @@ -41,12 +41,12 @@ public class ServiceTest { String resourceStr = "{\"CP\": {}}"; Service service1 = new Service(JsonUtils.GSON.fromJson(serviceStr1, JsonObject.class), - JsonUtils.GSON.fromJson(resourceStr, JsonObject.class)); + JsonUtils.GSON.fromJson(resourceStr, JsonObject.class), "1.0"); - Service service2 = new Service(JsonUtils.GSON.fromJson(serviceStr2, JsonObject.class), null); + Service service2 = new Service(JsonUtils.GSON.fromJson(serviceStr2, JsonObject.class), null, "1.0"); Service service3 = new Service(JsonUtils.GSON.fromJson(serviceStr3, JsonObject.class), - JsonUtils.GSON.fromJson(resourceStr, JsonObject.class)); + JsonUtils.GSON.fromJson(resourceStr, JsonObject.class), "1.0"); assertThat(service1.equals(service2)).isEqualTo(true); assertThat(service1.equals(service3)).isEqualTo(false); diff --git a/src/test/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilderTest.java b/src/test/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilderTest.java index 673ac323d..12ddbaa71 100644 --- a/src/test/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilderTest.java +++ b/src/test/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilderTest.java @@ -42,7 +42,7 @@ public class OperationalPolicyRepresentationBuilderTest { JsonObject jsonModel = new GsonBuilder().create() .fromJson(ResourceFileUtil.getResourceAsString("tosca/model-properties.json"), JsonObject.class); Service service = new Service(jsonModel.get("serviceDetails").getAsJsonObject(), - jsonModel.get("resourceDetails").getAsJsonObject()); + jsonModel.get("resourceDetails").getAsJsonObject(), "1.0"); JsonObject jsonSchema = OperationalPolicyRepresentationBuilder.generateOperationalPolicySchema(service); -- cgit 1.2.3-korg