Update deploymentParameters
[clamp.git] / src / main / java / org / onap / clamp / loop / CsarInstaller.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.JsonObject;
29
30 import java.io.IOException;
31 import java.util.Arrays;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Map.Entry;
36
37 import org.json.simple.parser.ParseException;
38 import org.onap.clamp.clds.client.DcaeInventoryServices;
39 import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException;
40 import org.onap.clamp.clds.model.dcae.DcaeInventoryResponse;
41 import org.onap.clamp.clds.sdc.controller.installer.BlueprintArtifact;
42 import org.onap.clamp.clds.sdc.controller.installer.BlueprintParser;
43 import org.onap.clamp.clds.sdc.controller.installer.ChainGenerator;
44 import org.onap.clamp.clds.sdc.controller.installer.CsarHandler;
45 import org.onap.clamp.clds.sdc.controller.installer.MicroService;
46 import org.onap.clamp.clds.util.JsonUtils;
47 import org.onap.clamp.clds.util.drawing.SvgFacade;
48 import org.onap.clamp.loop.deploy.DeployParameters;
49 import org.onap.clamp.loop.service.Service;
50 import org.onap.clamp.loop.service.ServiceRepository;
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.IEntityDetails;
55 import org.onap.sdc.tosca.parser.elements.queries.EntityQuery;
56 import org.onap.sdc.tosca.parser.elements.queries.TopologyTemplateQuery;
57 import org.onap.sdc.tosca.parser.enums.EntityTemplateType;
58 import org.onap.sdc.tosca.parser.enums.SdcTypes;
59 import org.onap.sdc.toscaparser.api.NodeTemplate;
60 import org.onap.sdc.toscaparser.api.Property;
61 import org.springframework.beans.factory.annotation.Autowired;
62 import org.springframework.beans.factory.annotation.Qualifier;
63 import org.springframework.stereotype.Component;
64 import org.springframework.transaction.annotation.Propagation;
65 import org.springframework.transaction.annotation.Transactional;
66 import org.yaml.snakeyaml.Yaml;
67
68 /**
69  * This class will be instantiated by spring config, and used by Sdc Controller.
70  * There is no state kept by the bean. It's used to deploy the csar/notification
71  * received from SDC in DB.
72  */
73 @Component
74 @Qualifier("csarInstaller")
75 public class CsarInstaller {
76
77     private static final EELFLogger logger = EELFManager.getInstance().getLogger(CsarInstaller.class);
78     public static final String CONTROL_NAME_PREFIX = "ClosedLoop-";
79     public static final String GET_INPUT_BLUEPRINT_PARAM = "get_input";
80     // This will be used later as the policy scope
81     public static final String MODEL_NAME_PREFIX = "Loop_";
82
83     @Autowired
84     LoopsRepository loopRepository;
85
86     @Autowired
87     ServiceRepository serviceRepository;
88
89     @Autowired
90     BlueprintParser blueprintParser;
91
92     @Autowired
93     ChainGenerator chainGenerator;
94
95     @Autowired
96     DcaeInventoryServices dcaeInventoryService;
97
98     @Autowired
99     private SvgFacade svgFacade;
100
101    /**
102     * Verify whether Csar is deployed.
103     * 
104     * @param csar The Csar Handler
105     * @return The flag indicating whether Csar is deployed
106     * @throws SdcArtifactInstallerException The SdcArtifactInstallerException
107     */
108     public boolean isCsarAlreadyDeployed(CsarHandler csar) throws SdcArtifactInstallerException {
109         boolean alreadyInstalled = true;
110         JsonObject serviceDetails = JsonUtils.GSON.fromJson(
111                 JsonUtils.GSON.toJson(csar.getSdcCsarHelper().getServiceMetadataAllProperties()), JsonObject.class);
112         alreadyInstalled = alreadyInstalled
113                 && serviceRepository.existsById(serviceDetails.get("UUID").getAsString());
114
115         for (Entry<String, BlueprintArtifact> blueprint : csar.getMapOfBlueprints().entrySet()) {
116             alreadyInstalled = alreadyInstalled
117                     && loopRepository.existsById(Loop.generateLoopName(csar.getSdcNotification().getServiceName(),
118                             csar.getSdcNotification().getServiceVersion(),
119                             blueprint.getValue().getResourceAttached().getResourceInstanceName(),
120                             blueprint.getValue().getBlueprintArtifactName()));
121         }
122         
123         return alreadyInstalled;
124     }
125
126     /**
127      * Install the service and loops from the csar.
128      * 
129      * @param csar The Csar Handler
130      * @throws SdcArtifactInstallerException The SdcArtifactInstallerException
131      * @throws InterruptedException The InterruptedException
132      */
133     public void installTheCsar(CsarHandler csar) throws SdcArtifactInstallerException, InterruptedException {
134         logger.info("Installing the CSAR " + csar.getFilePath());
135         installTheLoop(csar, installTheService(csar));
136         logger.info("Successfully installed the CSAR " + csar.getFilePath());
137     }
138
139     /**
140      * Install the Loop from the csar.
141      * 
142      * @param csar The Csar Handler
143      * @param service The service object that is related to the loop
144      * @throws SdcArtifactInstallerException The SdcArtifactInstallerException
145      * @throws InterruptedException The InterruptedException
146      */
147     @Transactional(propagation = Propagation.REQUIRED)
148     public void installTheLoop(CsarHandler csar, Service service) 
149             throws SdcArtifactInstallerException, InterruptedException {
150         try {
151             logger.info("Installing the Loops");
152             for (Entry<String, BlueprintArtifact> blueprint : csar.getMapOfBlueprints().entrySet()) {
153                 logger.info("Processing blueprint " + blueprint.getValue().getBlueprintArtifactName());
154                 loopRepository.save(createLoopFromBlueprint(csar, blueprint.getValue(), service));
155             }
156             logger.info("Successfully installed the Loops ");
157         } catch (IOException e) {
158             throw new SdcArtifactInstallerException("Exception caught during the Loop installation in database", e);
159         } catch (ParseException e) {
160             throw new SdcArtifactInstallerException("Exception caught during the Dcae query to get ServiceTypeId", e);
161         }
162     }
163
164     /**
165      * Install the Service from the csar.
166      * 
167      * @param csar The Csar Handler
168      * @return The service object
169      */
170     @Transactional
171     public Service installTheService(CsarHandler csar) {
172         logger.info("Start to install the Service from csar");
173         JsonObject serviceDetails = JsonUtils.GSON.fromJson(
174                 JsonUtils.GSON.toJson(csar.getSdcCsarHelper().getServiceMetadataAllProperties()), JsonObject.class);
175
176         // Add properties details for each type, VfModule, VF, VFC, ....
177         JsonObject resourcesProp = createServicePropertiesByType(csar);
178         resourcesProp.add("VFModule", createVfModuleProperties(csar));
179
180         Service modelService = new Service(serviceDetails, resourcesProp, 
181                 csar.getSdcNotification().getServiceVersion());
182
183         serviceRepository.save(modelService);
184         logger.info("Successfully installed the Service");
185         return modelService;
186     }
187
188     private Loop createLoopFromBlueprint(CsarHandler csar, BlueprintArtifact blueprintArtifact, Service service)
189             throws IOException, ParseException, InterruptedException {
190         Loop newLoop = new Loop();
191         newLoop.setBlueprint(blueprintArtifact.getDcaeBlueprint());
192         newLoop.setName(Loop.generateLoopName(csar.getSdcNotification().getServiceName(),
193                 csar.getSdcNotification().getServiceVersion(),
194                 blueprintArtifact.getResourceAttached().getResourceInstanceName(),
195                 blueprintArtifact.getBlueprintArtifactName()));
196         newLoop.setLastComputedState(LoopState.DESIGN);
197
198         List<MicroService> microServicesChain = chainGenerator
199                 .getChainOfMicroServices(blueprintParser.getMicroServices(blueprintArtifact.getDcaeBlueprint()));
200         if (microServicesChain.isEmpty()) {
201             microServicesChain = blueprintParser.fallbackToOneMicroService(blueprintArtifact.getDcaeBlueprint());
202         }
203         newLoop.setModelService(service);
204         newLoop.setMicroServicePolicies(
205                 createMicroServicePolicies(microServicesChain, csar, blueprintArtifact, newLoop));
206         newLoop.setOperationalPolicies(createOperationalPolicies(csar, blueprintArtifact, newLoop));
207
208         newLoop.setSvgRepresentation(svgFacade.getSvgImage(microServicesChain));
209         newLoop.setGlobalPropertiesJson(createGlobalPropertiesJson(blueprintArtifact, newLoop));
210
211         DcaeInventoryResponse dcaeResponse = queryDcaeToGetServiceTypeId(blueprintArtifact);
212         newLoop.setDcaeBlueprintId(dcaeResponse.getTypeId());
213         return newLoop;
214     }
215
216     private HashSet<OperationalPolicy> createOperationalPolicies(CsarHandler csar, BlueprintArtifact blueprintArtifact,
217             Loop newLoop) {
218         return new HashSet<>(Arrays.asList(new OperationalPolicy(Policy.generatePolicyName("OPERATIONAL",
219                 csar.getSdcNotification().getServiceName(), csar.getSdcNotification().getServiceVersion(),
220                 blueprintArtifact.getResourceAttached().getResourceInstanceName(),
221                 blueprintArtifact.getBlueprintArtifactName()), newLoop, new JsonObject())));
222     }
223
224     private HashSet<MicroServicePolicy> createMicroServicePolicies(List<MicroService> microServicesChain,
225             CsarHandler csar, BlueprintArtifact blueprintArtifact, Loop newLoop) throws IOException {
226         HashSet<MicroServicePolicy> newSet = new HashSet<>();
227
228         for (MicroService microService : microServicesChain) {
229             MicroServicePolicy microServicePolicy = new MicroServicePolicy(
230                     Policy.generatePolicyName(microService.getName(), csar.getSdcNotification().getServiceName(),
231                             csar.getSdcNotification().getServiceVersion(),
232                             blueprintArtifact.getResourceAttached().getResourceInstanceName(),
233                             blueprintArtifact.getBlueprintArtifactName()),
234                     microService.getModelType(), csar.getPolicyModelYaml().orElse(""), false,
235                     new HashSet<>(Arrays.asList(newLoop)));
236
237             newSet.add(microServicePolicy);
238             microService.setMappedNameJpa(microServicePolicy.getName());
239         }
240         return newSet;
241     }
242
243     private JsonObject createGlobalPropertiesJson(BlueprintArtifact blueprintArtifact, Loop newLoop) {
244         return new DeployParameters(blueprintArtifact, newLoop).getDeploymentParametersinJson();
245     }
246
247     private static JsonObject createVfModuleProperties(CsarHandler csar) {
248         JsonObject vfModuleProps = new JsonObject();
249         // Loop on all Groups defined in the service (VFModule entries type:
250         // org.openecomp.groups.VfModule)
251         for (IEntityDetails entity : csar.getSdcCsarHelper().getEntity(
252                 EntityQuery.newBuilder(EntityTemplateType.GROUP).build(),
253                 TopologyTemplateQuery.newBuilder(SdcTypes.SERVICE).build(), false)) {
254             // Get all metadata info
255             JsonObject allVfProps = (JsonObject) JsonUtils.GSON.toJsonTree(entity.getMetadata().getAllProperties());
256             vfModuleProps.add(entity.getMetadata().getAllProperties().get("vfModuleModelName"), allVfProps);
257             // now append the properties section so that we can also have isBase,
258             // volume_group, etc ... fields under the VFmodule name
259             for (Entry<String, Property> additionalProp : entity.getProperties().entrySet()) {
260                 allVfProps.add(additionalProp.getValue().getName(),
261                         JsonUtils.GSON.toJsonTree(additionalProp.getValue().getValue()));
262             }
263         }
264         return vfModuleProps;
265     }
266
267     private static JsonObject createServicePropertiesByType(CsarHandler csar) {
268         JsonObject resourcesProp = new JsonObject();
269         // Iterate on all types defined in the tosca lib
270         for (SdcTypes type : SdcTypes.values()) {
271             JsonObject resourcesPropByType = new JsonObject();
272             // For each type, get the metadata of each nodetemplate
273             for (NodeTemplate nodeTemplate : csar.getSdcCsarHelper().getServiceNodeTemplateBySdcType(type)) {
274                 resourcesPropByType.add(nodeTemplate.getName(),
275                         JsonUtils.GSON.toJsonTree(nodeTemplate.getMetaData().getAllProperties()));
276             }
277             resourcesProp.add(type.getValue(), resourcesPropByType);
278         }
279         return resourcesProp;
280     }
281
282     /**
283      * ll get the latest version of the artifact (version can be specified to DCAE
284      * call).
285      *
286      * @return The DcaeInventoryResponse object containing the dcae values
287      */
288     private DcaeInventoryResponse queryDcaeToGetServiceTypeId(BlueprintArtifact blueprintArtifact)
289             throws IOException, ParseException, InterruptedException {
290         return dcaeInventoryService.getDcaeInformation(blueprintArtifact.getBlueprintArtifactName(),
291                 blueprintArtifact.getBlueprintInvariantServiceUuid(),
292                 blueprintArtifact.getResourceAttached().getResourceInvariantUUID());
293     }
294
295 }