Clamp uses new Loop implementation by default
[clamp.git] / src / main / java / org / onap / clamp / loop / LoopCsarInstaller.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.List;
35 import java.util.Map;
36 import java.util.Map.Entry;
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.clds.util.drawing.SvgFacade;
51 import org.onap.clamp.policy.Policy;
52 import org.onap.clamp.policy.microservice.MicroServicePolicy;
53 import org.onap.clamp.policy.operational.OperationalPolicy;
54 import org.onap.sdc.tosca.parser.api.ISdcCsarHelper;
55 import org.onap.sdc.tosca.parser.enums.SdcTypes;
56 import org.onap.sdc.toscaparser.api.NodeTemplate;
57 import org.springframework.beans.factory.annotation.Autowired;
58 import org.springframework.beans.factory.annotation.Qualifier;
59 import org.springframework.stereotype.Component;
60 import org.springframework.transaction.annotation.Propagation;
61 import org.springframework.transaction.annotation.Transactional;
62 import org.yaml.snakeyaml.Yaml;
63
64 /**
65  * This class will be instantiated by spring config, and used by Sdc Controller.
66  * There is no state kept by the bean. It's used to deploy the csar/notification
67  * received from SDC in DB.
68  */
69 @Component
70 @Qualifier("loopInstaller")
71 public class LoopCsarInstaller implements CsarInstaller {
72
73     private static final EELFLogger logger = EELFManager.getInstance().getLogger(LoopCsarInstaller.class);
74     public static final String CONTROL_NAME_PREFIX = "ClosedLoop-";
75     public static final String GET_INPUT_BLUEPRINT_PARAM = "get_input";
76     // This will be used later as the policy scope
77     public static final String MODEL_NAME_PREFIX = "Loop_";
78
79     @Autowired
80     LoopsRepository loopRepository;
81
82     @Autowired
83     BlueprintParser blueprintParser;
84
85     @Autowired
86     ChainGenerator chainGenerator;
87
88     @Autowired
89     DcaeInventoryServices dcaeInventoryService;
90
91     @Autowired
92     private SvgFacade svgFacade;
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(Loop.generateLoopName(csar.getSdcNotification().getServiceName(),
100                     csar.getSdcNotification().getServiceVersion(),
101                     blueprint.getValue().getResourceAttached().getResourceInstanceName(),
102                     blueprint.getValue().getBlueprintArtifactName()));
103         }
104         return alreadyInstalled;
105     }
106
107     @Override
108     @Transactional(propagation = Propagation.REQUIRED)
109     public void installTheCsar(CsarHandler csar)
110         throws SdcArtifactInstallerException, InterruptedException, PolicyModelException {
111         try {
112             logger.info("Installing the CSAR " + csar.getFilePath());
113             for (Entry<String, BlueprintArtifact> blueprint : csar.getMapOfBlueprints().entrySet()) {
114                 logger.info("Processing blueprint " + blueprint.getValue().getBlueprintArtifactName());
115                 loopRepository.save(createLoopFromBlueprint(csar, blueprint.getValue()));
116             }
117             logger.info("Successfully installed the CSAR " + csar.getFilePath());
118         } catch (IOException e) {
119             throw new SdcArtifactInstallerException("Exception caught during the Csar installation in database", e);
120         } catch (ParseException e) {
121             throw new SdcArtifactInstallerException("Exception caught during the Dcae query to get ServiceTypeId", e);
122         }
123     }
124
125     private Loop createLoopFromBlueprint(CsarHandler csar, BlueprintArtifact blueprintArtifact)
126         throws IOException, ParseException, InterruptedException {
127         Loop newLoop = new Loop();
128         newLoop.setBlueprint(blueprintArtifact.getDcaeBlueprint());
129         newLoop.setName(Loop.generateLoopName(csar.getSdcNotification().getServiceName(),
130             csar.getSdcNotification().getServiceVersion(),
131             blueprintArtifact.getResourceAttached().getResourceInstanceName(),
132             blueprintArtifact.getBlueprintArtifactName()));
133         newLoop.setLastComputedState(LoopState.DESIGN);
134
135         List<MicroService> microServicesChain = chainGenerator
136             .getChainOfMicroServices(blueprintParser.getMicroServices(blueprintArtifact.getDcaeBlueprint()));
137         if (microServicesChain.isEmpty()) {
138             microServicesChain = blueprintParser.fallbackToOneMicroService(blueprintArtifact.getDcaeBlueprint());
139         }
140
141         newLoop
142             .setMicroServicePolicies(createMicroServicePolicies(microServicesChain, csar, blueprintArtifact, newLoop));
143         newLoop.setOperationalPolicies(createOperationalPolicies(csar, blueprintArtifact, newLoop));
144
145         newLoop.setSvgRepresentation(svgFacade.getSvgImage(microServicesChain));
146         newLoop.setGlobalPropertiesJson(createGlobalPropertiesJson(blueprintArtifact, newLoop));
147         newLoop.setModelPropertiesJson(createModelPropertiesJson(csar));
148         DcaeInventoryResponse dcaeResponse = queryDcaeToGetServiceTypeId(blueprintArtifact);
149         newLoop.setDcaeBlueprintId(dcaeResponse.getTypeId());
150         return newLoop;
151     }
152
153     private HashSet<OperationalPolicy> createOperationalPolicies(CsarHandler csar, BlueprintArtifact blueprintArtifact,
154         Loop newLoop) {
155         return new HashSet<>(Arrays.asList(new OperationalPolicy(Policy.generatePolicyName("OPERATIONAL",
156             csar.getSdcNotification().getServiceName(), csar.getSdcNotification().getServiceVersion(),
157             blueprintArtifact.getResourceAttached().getResourceInstanceName(),
158             blueprintArtifact.getBlueprintArtifactName()), newLoop, new JsonObject())));
159     }
160
161     private HashSet<MicroServicePolicy> createMicroServicePolicies(List<MicroService> microServicesChain,
162         CsarHandler csar, BlueprintArtifact blueprintArtifact, Loop newLoop) throws IOException {
163         HashSet<MicroServicePolicy> newSet = new HashSet<>();
164
165         for (MicroService microService : microServicesChain) {
166             MicroServicePolicy microServicePolicy = new MicroServicePolicy(
167                 Policy.generatePolicyName(microService.getName(), csar.getSdcNotification().getServiceName(),
168                     csar.getSdcNotification().getServiceVersion(),
169                     blueprintArtifact.getResourceAttached().getResourceInstanceName(),
170                     blueprintArtifact.getBlueprintArtifactName()),
171                 microService.getModelType(), csar.getPolicyModelYaml().orElse(""), false,
172                 new HashSet<>(Arrays.asList(newLoop)));
173
174             newSet.add(microServicePolicy);
175             microService.setMappedNameJpa(microServicePolicy.getName());
176         }
177         return newSet;
178     }
179
180     private JsonObject createGlobalPropertiesJson(BlueprintArtifact blueprintArtifact, Loop newLoop) {
181         JsonObject globalProperties = new JsonObject();
182         globalProperties.add("dcaeDeployParameters", getAllBlueprintParametersInJson(blueprintArtifact, newLoop));
183         return globalProperties;
184     }
185
186     private JsonObject createModelPropertiesJson(CsarHandler csar) {
187         JsonObject modelProperties = new JsonObject();
188         Gson gson = new Gson();
189         ISdcCsarHelper csarHelper = csar.getSdcCsarHelper();
190         modelProperties.add("serviceDetails",
191             gson.fromJson(gson.toJson(csarHelper.getServiceMetadataAllProperties()), JsonObject.class));
192
193         JsonObject resourcesProp = new JsonObject();
194         for (SdcTypes type : SdcTypes.values()) {
195             JsonObject resourcesPropByType = new JsonObject();
196             for (NodeTemplate nodeTemplate : csarHelper.getServiceNodeTemplateBySdcType(type)) {
197                 resourcesPropByType.add(nodeTemplate.getName(), JsonUtils.GSON_JPA_MODEL
198                     .fromJson(new Gson().toJson(nodeTemplate.getMetaData().getAllProperties()), JsonObject.class));
199             }
200             resourcesProp.add(type.getValue(), resourcesPropByType);
201         }
202         modelProperties.add("resourceDetails", resourcesProp);
203         return modelProperties;
204     }
205
206     private JsonObject getAllBlueprintParametersInJson(BlueprintArtifact blueprintArtifact, Loop newLoop) {
207         JsonObject node = new JsonObject();
208         Yaml yaml = new Yaml();
209         Map<String, Object> inputsNodes = ((Map<String, Object>) ((Map<String, Object>) yaml
210             .load(blueprintArtifact.getDcaeBlueprint())).get("inputs"));
211         inputsNodes.entrySet().stream().filter(e -> !e.getKey().contains("policy_id")).forEach(elem -> {
212             Object defaultValue = ((Map<String, Object>) elem.getValue()).get("default");
213             if (defaultValue != null) {
214                 addPropertyToNode(node, elem.getKey(), defaultValue);
215             } else {
216                 node.addProperty(elem.getKey(), "");
217             }
218         });
219         // For Dublin only one micro service is expected
220         node.addProperty("policy_id", ((MicroServicePolicy) newLoop.getMicroServicePolicies().toArray()[0]).getName());
221         return node;
222     }
223
224     /**
225      * ll get the latest version of the artifact (version can be specified to DCAE
226      * call).
227      *
228      * @return The DcaeInventoryResponse object containing the dcae values
229      */
230     private DcaeInventoryResponse queryDcaeToGetServiceTypeId(BlueprintArtifact blueprintArtifact)
231         throws IOException, ParseException, InterruptedException {
232         return dcaeInventoryService.getDcaeInformation(blueprintArtifact.getBlueprintArtifactName(),
233             blueprintArtifact.getBlueprintInvariantServiceUuid(),
234             blueprintArtifact.getResourceAttached().getResourceInvariantUUID());
235     }
236
237     private void addPropertyToNode(JsonObject node, String key, Object value) {
238         if (value instanceof String) {
239             node.addProperty(key, (String) value);
240         } else if (value instanceof Number) {
241             node.addProperty(key, (Number) value);
242         } else if (value instanceof Boolean) {
243             node.addProperty(key, (Boolean) value);
244         } else if (value instanceof Character) {
245             node.addProperty(key, (Character) value);
246         } else {
247             node.addProperty(key, JsonUtils.GSON.toJson(value));
248         }
249     }
250 }