9627445d610d3cc741c561febee667bacbacdf1c
[clamp.git] / src / main / java / org / onap / clamp / loop / CsarInstallerImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights
6  *                             reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END============================================
20  * ===================================================================
21  *
22  */
23
24 package org.onap.clamp.loop;
25
26 import com.att.eelf.configuration.EELFLogger;
27 import com.att.eelf.configuration.EELFManager;
28 import com.google.gson.Gson;
29 import com.google.gson.JsonObject;
30
31 import java.io.IOException;
32 import java.util.Arrays;
33 import java.util.HashSet;
34 import java.util.Map;
35 import java.util.Map.Entry;
36 import java.util.Optional;
37
38 import org.json.simple.parser.ParseException;
39 import org.onap.clamp.clds.client.DcaeInventoryServices;
40 import org.onap.clamp.clds.exception.policy.PolicyModelException;
41 import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException;
42 import org.onap.clamp.clds.model.dcae.DcaeInventoryResponse;
43 import org.onap.clamp.clds.sdc.controller.installer.BlueprintArtifact;
44 import org.onap.clamp.clds.sdc.controller.installer.BlueprintParser;
45 import org.onap.clamp.clds.sdc.controller.installer.ChainGenerator;
46 import org.onap.clamp.clds.sdc.controller.installer.CsarHandler;
47 import org.onap.clamp.clds.sdc.controller.installer.CsarInstaller;
48 import org.onap.clamp.clds.sdc.controller.installer.MicroService;
49 import org.onap.clamp.clds.util.JsonUtils;
50 import org.onap.clamp.policy.Policy;
51 import org.onap.clamp.policy.microservice.MicroServicePolicy;
52 import org.onap.clamp.policy.operational.OperationalPolicy;
53 import org.onap.sdc.tosca.parser.enums.SdcTypes;
54 import org.onap.sdc.toscaparser.api.NodeTemplate;
55 import org.springframework.beans.factory.annotation.Autowired;
56 import org.springframework.transaction.annotation.Transactional;
57 import org.yaml.snakeyaml.Yaml;
58
59 /**
60  * This class will be instantiated by spring config, and used by Sdc Controller.
61  * There is no state kept by the bean. It's used to deploy the csar/notification
62  * received from SDC in DB.
63  */
64 public class CsarInstallerImpl implements CsarInstaller {
65
66     private static final EELFLogger logger = EELFManager.getInstance().getLogger(CsarInstallerImpl.class);
67     public static final String TEMPLATE_NAME_PREFIX = "DCAE-Designer-Template-";
68     public static final String CONTROL_NAME_PREFIX = "ClosedLoop-";
69     public static final String GET_INPUT_BLUEPRINT_PARAM = "get_input";
70     // This will be used later as the policy scope
71     public static final String MODEL_NAME_PREFIX = "Loop_";
72
73     @Autowired
74     protected LoopsRepository loopRepository;
75
76     @Autowired
77     private BlueprintParser blueprintParser;
78
79     @Autowired
80     private ChainGenerator chainGenerator;
81
82     @Autowired
83     DcaeInventoryServices dcaeInventoryService;
84
85     @Autowired
86     public void CsarInstallerImpl(LoopsRepository loopRepository, BlueprintParser blueprintParser,
87         ChainGenerator chainGenerator, DcaeInventoryServices dcaeInventoryService) {
88         this.loopRepository = loopRepository;
89         this.blueprintParser = blueprintParser;
90         this.chainGenerator = chainGenerator;
91         this.dcaeInventoryService = dcaeInventoryService;
92     }
93
94     @Override
95     public boolean isCsarAlreadyDeployed(CsarHandler csar) throws SdcArtifactInstallerException {
96         boolean alreadyInstalled = true;
97         for (Entry<String, BlueprintArtifact> blueprint : csar.getMapOfBlueprints().entrySet()) {
98             alreadyInstalled = alreadyInstalled
99                 && loopRepository.existsById(buildModelName(csar, blueprint.getValue()));
100         }
101         return alreadyInstalled;
102     }
103
104     public static String buildModelName(CsarHandler csar, BlueprintArtifact artifact) {
105
106         return (MODEL_NAME_PREFIX + "_" + csar.getSdcCsarHelper().getServiceMetadata().getValue("name") + "_v"
107             + csar.getSdcNotification().getServiceVersion() + "_"
108             + artifact.getResourceAttached().getResourceInstanceName().replaceAll(" ", "") + "_"
109             + artifact.getBlueprintArtifactName().replace(".yaml", "")).replace('.', '_');
110     }
111
112     public static String buildOperationalPolicyName(CsarHandler csar, BlueprintArtifact artifact) {
113
114         return (MODEL_NAME_PREFIX + "_" + csar.getSdcCsarHelper().getServiceMetadata().getValue("name") + "_v"
115             + csar.getSdcNotification().getServiceVersion() + "_"
116             + artifact.getResourceAttached().getResourceInstanceName().replaceAll(" ", "") + "_"
117             + artifact.getBlueprintArtifactName().replace(".yaml", "")).replace('.', '_');
118     }
119
120     @Override
121     @Transactional
122     public void installTheCsar(CsarHandler csar)
123         throws SdcArtifactInstallerException, InterruptedException, PolicyModelException {
124         try {
125             logger.info("Installing the CSAR " + csar.getFilePath());
126             for (Entry<String, BlueprintArtifact> blueprint : csar.getMapOfBlueprints().entrySet()) {
127                 logger.info("Processing blueprint " + blueprint.getValue().getBlueprintArtifactName());
128                 createLoopFromBlueprint(csar, blueprint.getValue());
129             }
130             createPolicyModel(csar);
131             logger.info("Successfully installed the CSAR " + csar.getFilePath());
132         } catch (IOException e) {
133             throw new SdcArtifactInstallerException("Exception caught during the Csar installation in database", e);
134         } catch (ParseException e) {
135             throw new SdcArtifactInstallerException("Exception caught during the Dcae query to get ServiceTypeId", e);
136         }
137     }
138
139     private void createPolicyModel(CsarHandler csar) throws PolicyModelException {
140         try {
141             Optional<String> policyModelYaml = csar.getPolicyModelYaml();
142             // save policy model into the database
143         } catch (IOException e) {
144             throw new PolicyModelException("TransformerException when decoding the YamlText", e);
145         }
146     }
147
148     private Loop createLoopFromBlueprint(CsarHandler csar, BlueprintArtifact blueprintArtifact)
149         throws IOException, ParseException, InterruptedException {
150         Loop newLoop = new Loop();
151         newLoop.setBlueprint(blueprintArtifact.getDcaeBlueprint());
152         newLoop.setName(Loop.generateLoopName(csar.getSdcNotification().getServiceName(),
153             csar.getSdcNotification().getServiceVersion(),
154             blueprintArtifact.getResourceAttached().getResourceInstanceName(),
155             blueprintArtifact.getBlueprintArtifactName()));
156         newLoop.setLastComputedState(LoopState.DESIGN);
157         for (MicroService microService : blueprintParser.getMicroServices(blueprintArtifact.getDcaeBlueprint())) {
158             newLoop.getMicroServicePolicies().add(new MicroServicePolicy(microService.getName(),
159                 csar.getPolicyModelYaml().orElse(""), false, new JsonObject(), new HashSet<>(Arrays.asList(newLoop))));
160         }
161         newLoop.setOperationalPolicies(
162             new HashSet<>(Arrays.asList(new OperationalPolicy(Policy.generatePolicyName("OPERATIONAL",
163                 csar.getSdcNotification().getServiceName(), csar.getSdcNotification().getServiceVersion(),
164                 blueprintArtifact.getResourceAttached().getResourceInstanceName(),
165                 blueprintArtifact.getBlueprintArtifactName()), newLoop, new JsonObject()))));
166         // Set SVG XML computed
167         // newLoop.setSvgRepresentation(svgRepresentation);
168         newLoop.setGlobalPropertiesJson(createGlobalPropertiesJson(csar, blueprintArtifact));
169         newLoop.setModelPropertiesJson(createModelPropertiesJson(csar, blueprintArtifact));
170         DcaeInventoryResponse dcaeResponse = queryDcaeToGetServiceTypeId(blueprintArtifact);
171         newLoop.setDcaeBlueprintId(dcaeResponse.getTypeId());
172         return newLoop;
173     }
174
175     private JsonObject createGlobalPropertiesJson(CsarHandler csar, BlueprintArtifact blueprintArtifact) {
176         JsonObject globalProperties = new JsonObject();
177         globalProperties.add("dcaeDeployParameters", getAllBlueprintParametersInJson(blueprintArtifact));
178         return globalProperties;
179
180     }
181
182     private JsonObject createModelPropertiesJson(CsarHandler csar, BlueprintArtifact blueprintArtifact) {
183         JsonObject modelProperties = new JsonObject();
184         Gson gson = new Gson();
185         modelProperties.add("serviceDetails",
186             gson.fromJson(gson.toJson(csar.getSdcCsarHelper().getServiceMetadataAllProperties()), JsonObject.class));
187
188         JsonObject resourcesProp = new JsonObject();
189         for (SdcTypes type : SdcTypes.values()) {
190             JsonObject resourcesPropByType = new JsonObject();
191             for (NodeTemplate nodeTemplate : csar.getSdcCsarHelper().getServiceNodeTemplateBySdcType(type)) {
192                 resourcesPropByType.add(nodeTemplate.getName(), JsonUtils.GSON_JPA_MODEL
193                     .fromJson(new Gson().toJson(nodeTemplate.getMetaData().getAllProperties()), JsonObject.class));
194             }
195             resourcesProp.add(type.getValue(), resourcesPropByType);
196         }
197         modelProperties.add("resourceDetails", resourcesProp);
198         return modelProperties;
199     }
200
201     private JsonObject getAllBlueprintParametersInJson(BlueprintArtifact blueprintArtifact) {
202         JsonObject node = new JsonObject();
203         Yaml yaml = new Yaml();
204         Map<String, Object> inputsNodes = ((Map<String, Object>) ((Map<String, Object>) yaml
205             .load(blueprintArtifact.getDcaeBlueprint())).get("inputs"));
206         inputsNodes.entrySet().stream().filter(e -> !e.getKey().contains("policy_id")).forEach(elem -> {
207             Object defaultValue = ((Map<String, Object>) elem.getValue()).get("default");
208             if (defaultValue != null) {
209                 addPropertyToNode(node, elem.getKey(), defaultValue);
210             } else {
211                 node.addProperty(elem.getKey(), "");
212             }
213         });
214         node.addProperty("policy_id", "AUTO_GENERATED_POLICY_ID_AT_SUBMIT");
215         return node;
216     }
217
218     /**
219      * ll get the latest version of the artifact (version can be specified to DCAE
220      * call)
221      *
222      * @return The DcaeInventoryResponse object containing the dcae values
223      */
224     private DcaeInventoryResponse queryDcaeToGetServiceTypeId(BlueprintArtifact blueprintArtifact)
225         throws IOException, ParseException, InterruptedException {
226         return dcaeInventoryService.getDcaeInformation(blueprintArtifact.getBlueprintArtifactName(),
227             blueprintArtifact.getBlueprintInvariantServiceUuid(),
228             blueprintArtifact.getResourceAttached().getResourceInvariantUUID());
229     }
230
231     private void addPropertyToNode(JsonObject node, String key, Object value) {
232         if (value instanceof String) {
233             node.addProperty(key, (String) value);
234         } else if (value instanceof Number) {
235             node.addProperty(key, (Number) value);
236         } else if (value instanceof Boolean) {
237             node.addProperty(key, (Boolean) value);
238         } else if (value instanceof Character) {
239             node.addProperty(key, (Character) value);
240         } else {
241             node.addProperty(key, JsonUtils.GSON.toJson(value));
242         }
243     }
244 }