From 63c1b064d33c50a7d54642423ae8fa92d697aebf Mon Sep 17 00:00:00 2001 From: sebdet Date: Wed, 6 Mar 2019 08:22:52 +0100 Subject: New CsarInstaller Csar installer to fullfil the new database model Issue-ID: CLAMP-306 Change-Id: I456922b4ca5044df2299350abd85762c84d7435a Signed-off-by: sebdet --- .../config/spring/SdcControllerConfiguration.java | 104 +++++++++ .../sdc/controller/installer/BlueprintParser.java | 21 +- .../clds/sdc/controller/installer/CsarHandler.java | 4 +- .../org/onap/clamp/loop/CsarInstallerImpl.java | 244 +++++++++++++++++++++ src/main/java/org/onap/clamp/loop/Loop.java | 26 ++- src/main/java/org/onap/clamp/policy/Policy.java | 9 +- 6 files changed, 391 insertions(+), 17 deletions(-) create mode 100644 src/main/java/org/onap/clamp/clds/config/spring/SdcControllerConfiguration.java create mode 100644 src/main/java/org/onap/clamp/loop/CsarInstallerImpl.java (limited to 'src/main') 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 new file mode 100644 index 00000000..2977d1a8 --- /dev/null +++ b/src/main/java/org/onap/clamp/clds/config/spring/SdcControllerConfiguration.java @@ -0,0 +1,104 @@ +/*- + * ============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.clds.config.spring; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + +import org.onap.clamp.clds.config.ClampProperties; +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.CsarInstallerImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.scheduling.annotation.Scheduled; + +@Configuration +@Profile("clamp-sdc-controller-new") +public class SdcControllerConfiguration { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(SdcControllerConfiguration.class); + private List sdcControllersList = new ArrayList<>(); + @Autowired + private ClampProperties clampProp; + @Autowired + protected CsarInstaller csarInstaller; + + @PostConstruct + public void loadSdcControllers() { + SdcControllersConfiguration sdcControllersConfig = getSdcControllersConfiguration(); + sdcControllersConfig.getAllDefinedControllers().forEach((k, v) -> { + logger.info("Creating controller instance:" + k); + SdcSingleController sdcController = new SdcSingleController(clampProp, csarInstaller, v, null); + sdcControllersList.add(sdcController); + }); + } + + @Scheduled(fixedRate = 120000) + public void checkAllSdcControllers() { + logger.info("Checking that all SDC Controllers defined are up and running"); + for (SdcSingleController controller : sdcControllersList) { + try { + if (SdcSingleControllerStatus.STOPPED.equals(controller.getControllerStatus())) { + controller.initSdc(); + } + } catch (SdcControllerException e) { + logger.error("Exception caught when booting sdc controller", e); + } + } + logger.info("SDC Controllers check completed"); + } + + @PreDestroy + public void killSdcControllers() { + sdcControllersList.forEach(e -> { + try { + e.closeSdc(); + } catch (SdcControllerException e1) { + logger.error("Exception caught when stopping sdc controller", e1); + } + }); + } + + @Bean(name = "csarInstaller") + public CsarInstaller getCsarInstaller() { + return new CsarInstallerImpl(); + } + + @Bean(name = "sdcControllersConfiguration") + public SdcControllersConfiguration getSdcControllersConfiguration() { + return new SdcControllersConfiguration(); + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParser.java b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParser.java index 16aee277..542411b0 100644 --- a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParser.java +++ b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParser.java @@ -26,12 +26,14 @@ import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; + import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; + import org.json.JSONObject; import org.springframework.stereotype.Component; import org.yaml.snakeyaml.Yaml; @@ -52,10 +54,8 @@ public class BlueprintParser { private static final String CLAMP_NODE_RELATIONSHIPS_GETS_INPUT_FROM = "clamp_node.relationships.gets_input_from"; private static final String TARGET = "target"; - BlueprintParser() {} - - Set getMicroServices(String blueprintString) { - Set microServices = new HashSet<>(); + public Set getMicroServices(String blueprintString) { + Set microServices = new HashSet<>(); JsonObject jsonObject = BlueprintParser.convertToJson(blueprintString); JsonObject results = jsonObject.get(NODE_TEMPLATES).getAsJsonObject(); @@ -70,15 +70,15 @@ public class BlueprintParser { return microServices; } - List fallbackToOneMicroService(String blueprintString) { + public List fallbackToOneMicroService(String blueprintString) { JsonObject jsonObject = BlueprintParser.convertToJson(blueprintString); JsonObject results = jsonObject.get(NODE_TEMPLATES).getAsJsonObject(); String theBiggestMicroServiceContent = ""; String theBiggestMicroServiceKey = ""; for (Entry entry : results.entrySet()) { String msAsString = entry.getValue().toString(); - int len =msAsString.length(); - if(len > theBiggestMicroServiceContent.length()) { + int len = msAsString.length(); + if (len > theBiggestMicroServiceContent.length()) { theBiggestMicroServiceContent = msAsString; theBiggestMicroServiceKey = entry.getKey(); } @@ -105,7 +105,7 @@ public class BlueprintParser { JsonArray relationships = ob.getAsJsonArray(RELATIONSHIPS); for (JsonElement element : relationships) { String target = getTarget(element.getAsJsonObject()); - if(!target.isEmpty()) { + if (!target.isEmpty()) { return target; } } @@ -120,9 +120,8 @@ public class BlueprintParser { } private String getTarget(JsonObject elementObject) { - if (elementObject.has(TYPE) && - elementObject.has(TARGET) && - elementObject.get(TYPE).getAsString().equals(CLAMP_NODE_RELATIONSHIPS_GETS_INPUT_FROM)) { + if (elementObject.has(TYPE) && elementObject.has(TARGET) + && elementObject.get(TYPE).getAsString().equals(CLAMP_NODE_RELATIONSHIPS_GETS_INPUT_FROM)) { return elementObject.get(TARGET).getAsString(); } return ""; diff --git a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarHandler.java b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarHandler.java index f2c75ef2..b60f0728 100644 --- a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarHandler.java +++ b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarHandler.java @@ -170,13 +170,13 @@ public class CsarHandler { return mapOfBlueprints; } - Optional getPolicyModelYaml() throws IOException { + public Optional getPolicyModelYaml() throws IOException { String result = null; try (ZipFile zipFile = new ZipFile(csarFilePath)) { ZipEntry entry = zipFile.getEntry(POLICY_DEFINITION_NAME_SUFFIX); if (entry != null) { result = IOUtils.toString(zipFile.getInputStream(entry)); - } else{ + } else { logger.info("Policy model not found inside the CSAR file: " + csarFilePath); } return Optional.ofNullable(result); diff --git a/src/main/java/org/onap/clamp/loop/CsarInstallerImpl.java b/src/main/java/org/onap/clamp/loop/CsarInstallerImpl.java new file mode 100644 index 00000000..9627445d --- /dev/null +++ b/src/main/java/org/onap/clamp/loop/CsarInstallerImpl.java @@ -0,0 +1,244 @@ +/*- + * ============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.Gson; +import com.google.gson.JsonObject; + +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; + +import org.json.simple.parser.ParseException; +import org.onap.clamp.clds.client.DcaeInventoryServices; +import org.onap.clamp.clds.exception.policy.PolicyModelException; +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.policy.Policy; +import org.onap.clamp.policy.microservice.MicroServicePolicy; +import org.onap.clamp.policy.operational.OperationalPolicy; +import org.onap.sdc.tosca.parser.enums.SdcTypes; +import org.onap.sdc.toscaparser.api.NodeTemplate; +import org.springframework.beans.factory.annotation.Autowired; +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. + */ +public class CsarInstallerImpl implements CsarInstaller { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(CsarInstallerImpl.class); + public static final String TEMPLATE_NAME_PREFIX = "DCAE-Designer-Template-"; + 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 + protected LoopsRepository loopRepository; + + @Autowired + private BlueprintParser blueprintParser; + + @Autowired + private ChainGenerator chainGenerator; + + @Autowired + DcaeInventoryServices dcaeInventoryService; + + @Autowired + public void CsarInstallerImpl(LoopsRepository loopRepository, BlueprintParser blueprintParser, + ChainGenerator chainGenerator, DcaeInventoryServices dcaeInventoryService) { + this.loopRepository = loopRepository; + this.blueprintParser = blueprintParser; + this.chainGenerator = chainGenerator; + this.dcaeInventoryService = dcaeInventoryService; + } + + @Override + public boolean isCsarAlreadyDeployed(CsarHandler csar) throws SdcArtifactInstallerException { + boolean alreadyInstalled = true; + for (Entry blueprint : csar.getMapOfBlueprints().entrySet()) { + alreadyInstalled = alreadyInstalled + && loopRepository.existsById(buildModelName(csar, blueprint.getValue())); + } + return alreadyInstalled; + } + + public static String buildModelName(CsarHandler csar, BlueprintArtifact artifact) { + + return (MODEL_NAME_PREFIX + "_" + csar.getSdcCsarHelper().getServiceMetadata().getValue("name") + "_v" + + csar.getSdcNotification().getServiceVersion() + "_" + + artifact.getResourceAttached().getResourceInstanceName().replaceAll(" ", "") + "_" + + artifact.getBlueprintArtifactName().replace(".yaml", "")).replace('.', '_'); + } + + public static String buildOperationalPolicyName(CsarHandler csar, BlueprintArtifact artifact) { + + return (MODEL_NAME_PREFIX + "_" + csar.getSdcCsarHelper().getServiceMetadata().getValue("name") + "_v" + + csar.getSdcNotification().getServiceVersion() + "_" + + artifact.getResourceAttached().getResourceInstanceName().replaceAll(" ", "") + "_" + + artifact.getBlueprintArtifactName().replace(".yaml", "")).replace('.', '_'); + } + + @Override + @Transactional + public void installTheCsar(CsarHandler csar) + throws SdcArtifactInstallerException, InterruptedException, PolicyModelException { + try { + logger.info("Installing the CSAR " + csar.getFilePath()); + for (Entry blueprint : csar.getMapOfBlueprints().entrySet()) { + logger.info("Processing blueprint " + blueprint.getValue().getBlueprintArtifactName()); + createLoopFromBlueprint(csar, blueprint.getValue()); + } + createPolicyModel(csar); + 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 void createPolicyModel(CsarHandler csar) throws PolicyModelException { + try { + Optional policyModelYaml = csar.getPolicyModelYaml(); + // save policy model into the database + } catch (IOException e) { + throw new PolicyModelException("TransformerException when decoding the YamlText", 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); + for (MicroService microService : blueprintParser.getMicroServices(blueprintArtifact.getDcaeBlueprint())) { + newLoop.getMicroServicePolicies().add(new MicroServicePolicy(microService.getName(), + csar.getPolicyModelYaml().orElse(""), false, new JsonObject(), new HashSet<>(Arrays.asList(newLoop)))); + } + newLoop.setOperationalPolicies( + new HashSet<>(Arrays.asList(new OperationalPolicy(Policy.generatePolicyName("OPERATIONAL", + csar.getSdcNotification().getServiceName(), csar.getSdcNotification().getServiceVersion(), + blueprintArtifact.getResourceAttached().getResourceInstanceName(), + blueprintArtifact.getBlueprintArtifactName()), newLoop, new JsonObject())))); + // Set SVG XML computed + // newLoop.setSvgRepresentation(svgRepresentation); + newLoop.setGlobalPropertiesJson(createGlobalPropertiesJson(csar, blueprintArtifact)); + newLoop.setModelPropertiesJson(createModelPropertiesJson(csar, blueprintArtifact)); + DcaeInventoryResponse dcaeResponse = queryDcaeToGetServiceTypeId(blueprintArtifact); + newLoop.setDcaeBlueprintId(dcaeResponse.getTypeId()); + return newLoop; + } + + private JsonObject createGlobalPropertiesJson(CsarHandler csar, BlueprintArtifact blueprintArtifact) { + JsonObject globalProperties = new JsonObject(); + globalProperties.add("dcaeDeployParameters", getAllBlueprintParametersInJson(blueprintArtifact)); + return globalProperties; + + } + + private JsonObject createModelPropertiesJson(CsarHandler csar, BlueprintArtifact blueprintArtifact) { + JsonObject modelProperties = new JsonObject(); + Gson gson = new Gson(); + modelProperties.add("serviceDetails", + gson.fromJson(gson.toJson(csar.getSdcCsarHelper().getServiceMetadataAllProperties()), JsonObject.class)); + + JsonObject resourcesProp = new JsonObject(); + for (SdcTypes type : SdcTypes.values()) { + JsonObject resourcesPropByType = new JsonObject(); + for (NodeTemplate nodeTemplate : csar.getSdcCsarHelper().getServiceNodeTemplateBySdcType(type)) { + resourcesPropByType.add(nodeTemplate.getName(), JsonUtils.GSON_JPA_MODEL + .fromJson(new Gson().toJson(nodeTemplate.getMetaData().getAllProperties()), JsonObject.class)); + } + resourcesProp.add(type.getValue(), resourcesPropByType); + } + modelProperties.add("resourceDetails", resourcesProp); + return modelProperties; + } + + private JsonObject getAllBlueprintParametersInJson(BlueprintArtifact blueprintArtifact) { + 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(), ""); + } + }); + node.addProperty("policy_id", "AUTO_GENERATED_POLICY_ID_AT_SUBMIT"); + 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 910c5aad..cc7f1803 100644 --- a/src/main/java/org/onap/clamp/loop/Loop.java +++ b/src/main/java/org/onap/clamp/loop/Loop.java @@ -46,10 +46,10 @@ import javax.persistence.Table; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; import org.hibernate.annotations.TypeDefs; +import org.onap.clamp.dao.model.jsontype.StringJsonUserType; import org.onap.clamp.loop.log.LoopLog; import org.onap.clamp.policy.microservice.MicroServicePolicy; import org.onap.clamp.policy.operational.OperationalPolicy; -import org.onap.clamp.dao.model.jsontype.StringJsonUserType; @Entity @Table(name = "loops") @@ -86,6 +86,11 @@ public class Loop implements Serializable { @Column(columnDefinition = "json", name = "global_properties_json") private JsonObject globalPropertiesJson; + @Expose + @Type(type = "json") + @Column(columnDefinition = "json", name = "model_properties_json") + private JsonObject modelPropertiesJson; + @Column(nullable = false, name = "blueprint_yaml") private String blueprint; @@ -213,14 +218,29 @@ public class Loop implements Serializable { log.setLoop(this); } - public String getDcaeBlueprintId() { + String getDcaeBlueprintId() { return dcaeBlueprintId; } - public void setDcaeBlueprintId(String dcaeBlueprintId) { + void setDcaeBlueprintId(String dcaeBlueprintId) { this.dcaeBlueprintId = dcaeBlueprintId; } + JsonObject getModelPropertiesJson() { + return modelPropertiesJson; + } + + void setModelPropertiesJson(JsonObject modelPropertiesJson) { + this.modelPropertiesJson = modelPropertiesJson; + } + + public static String generateLoopName(String serviceName, String serviceVersion, String resourceName, + String blueprintFilename) { + StringBuilder buffer = new StringBuilder("LOOP_").append(serviceName).append("_v").append(serviceVersion) + .append("_").append(resourceName).append("_").append(blueprintFilename.replaceAll(".yaml", "")); + return buffer.toString().replace('.', '_').replaceAll(" ", ""); + } + @Override public int hashCode() { final int prime = 31; diff --git a/src/main/java/org/onap/clamp/policy/Policy.java b/src/main/java/org/onap/clamp/policy/Policy.java index 13ba1a9f..c104b13e 100644 --- a/src/main/java/org/onap/clamp/policy/Policy.java +++ b/src/main/java/org/onap/clamp/policy/Policy.java @@ -21,7 +21,6 @@ * */ - package org.onap.clamp.policy; import com.google.gson.JsonObject; @@ -32,4 +31,12 @@ public interface Policy { JsonObject getJsonRepresentation(); + static String generatePolicyName(String policyType, String serviceName, String serviceVersion, String resourceName, + String blueprintFilename) { + StringBuilder buffer = new StringBuilder(policyType).append("_").append(serviceName).append("_v") + .append(serviceVersion).append("_").append(resourceName).append("_") + .append(blueprintFilename.replaceAll(".yaml", "")); + return buffer.toString().replace('.', '_').replaceAll(" ", ""); + } + } -- cgit 1.2.3-korg