Reformat catalog-model
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsonjanusgraph / operations / ArtifactsOperations.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
21
22 import fj.data.Either;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Comparator;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Map.Entry;
30 import java.util.Optional;
31 import java.util.UUID;
32 import java.util.stream.Collectors;
33 import org.apache.commons.collections.MapUtils;
34 import org.apache.commons.lang.text.StrBuilder;
35 import org.apache.commons.lang3.tuple.ImmutableTriple;
36 import org.apache.commons.lang3.tuple.Triple;
37 import org.apache.tinkerpop.gremlin.structure.Direction;
38 import org.openecomp.sdc.be.config.BeEcompErrorManager;
39 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
40 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
41 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
42 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
43 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
44 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
45 import org.openecomp.sdc.be.datatypes.elements.HeatParameterDataDefinition;
46 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
47 import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
48 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
49 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
50 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
51 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
52 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
53 import org.openecomp.sdc.be.model.ArtifactDefinition;
54 import org.openecomp.sdc.be.model.Component;
55 import org.openecomp.sdc.be.model.HeatParameterDefinition;
56 import org.openecomp.sdc.be.model.InterfaceDefinition;
57 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
58 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
59 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
60 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
61 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
62 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
63 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
64 import org.openecomp.sdc.common.log.api.ILogConfiguration;
65 import org.openecomp.sdc.common.log.wrappers.Logger;
66 import org.openecomp.sdc.common.util.GeneralUtility;
67 import org.slf4j.MDC;
68
69 @org.springframework.stereotype.Component("artifacts-operations")
70 public class ArtifactsOperations extends BaseOperation {
71
72     private static final String FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR = "failed to fetch {} for tosca element with id {}, error {}";
73     private static final Logger log = Logger.getLogger(ArtifactsOperations.class.getName());
74
75     public Either<ArtifactDefinition, StorageOperationStatus> addArtifactToComponent(ArtifactDefinition artifactInfo, Component component,
76                                                                                      NodeTypeEnum type, boolean failIfExist, String instanceId) {
77         String parentId = component.getUniqueId();
78         String artifactId = artifactInfo.getUniqueId();
79         if (artifactId == null && artifactInfo.getEsId() != null) {
80             artifactId = artifactInfo.getEsId();
81         }
82         Either<ArtifactDataDefinition, StorageOperationStatus> status = updateArtifactOnGraph(component, artifactInfo, type, artifactId, instanceId,
83             false, false);
84         if (status.isRight()) {
85             log.debug("Failed to update artifact {} of {} {}. status is {}", artifactInfo.getArtifactName(), type.getName(), parentId,
86                 status.right().value());
87             BeEcompErrorManager.getInstance()
88                 .logBeFailedUpdateNodeError("Update Artifact", artifactInfo.getArtifactName(), String.valueOf(status.right().value()));
89             return Either.right(status.right().value());
90         } else {
91             ArtifactDataDefinition artifactData = status.left().value();
92             ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactInfo, artifactData);
93             log.debug("The returned ArtifactDefintion is {}", artifactDefResult);
94             return Either.left(artifactDefResult);
95         }
96     }
97
98     public Either<ArtifactDefinition, StorageOperationStatus> updateArtifactOnResource(ArtifactDefinition artifactInfo, Component component,
99                                                                                        String artifactId, NodeTypeEnum type, String instanceId,
100                                                                                        boolean isUpdate) {
101         String id = component.getUniqueId();
102         Either<ArtifactDataDefinition, StorageOperationStatus> status = updateArtifactOnGraph(component, artifactInfo, type, artifactId, instanceId,
103             isUpdate, false);
104         if (status.isRight()) {
105             log.debug("Failed to update artifact {} of {} {}. status is {}", artifactInfo.getArtifactName(), type.getName(), id,
106                 status.right().value());
107             BeEcompErrorManager.getInstance()
108                 .logBeFailedUpdateNodeError("Update Artifact", artifactInfo.getArtifactName(), String.valueOf(status.right().value()));
109             return Either.right(status.right().value());
110         } else {
111             ArtifactDataDefinition artifactData = status.left().value();
112             ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactInfo, artifactData);
113             log.debug("The returned ArtifactDefinition is {}", artifactDefResult);
114             return Either.left(artifactDefResult);
115         }
116     }
117
118     public Either<Boolean, StorageOperationStatus> isCloneNeeded(String parentId, ArtifactDefinition artifactInfo, NodeTypeEnum type) {
119         ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
120         Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(groupType, type);
121         EdgeLabelEnum edgeLabelEnum = triple.getLeft();
122         return super.isCloneNeeded(parentId, edgeLabelEnum);
123     }
124
125     public Either<ArtifactDefinition, StorageOperationStatus> getArtifactById(String parentId, String id) {
126         return getArtifactById(parentId, id, null, null);
127     }
128
129     public Either<ArtifactDefinition, StorageOperationStatus> getArtifactById(String parentId, String id, ComponentTypeEnum componentType,
130                                                                               String containerId) {
131         Either<ArtifactDefinition, StorageOperationStatus> result = null;
132         ArtifactDataDefinition foundArtifact = null;
133         if (componentType != null && componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
134             foundArtifact = getInstanceArtifactByLabelAndId(parentId, id, containerId, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
135             if (foundArtifact == null) {
136                 foundArtifact = getInstanceArtifactByLabelAndId(parentId, id, containerId, EdgeLabelEnum.INSTANCE_ARTIFACTS);
137             }
138         }
139         if (foundArtifact == null) {
140             foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
141         }
142         if (foundArtifact == null) {
143             foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.TOSCA_ARTIFACTS);
144         }
145         if (foundArtifact == null) {
146             foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.ARTIFACTS);
147         }
148         if (foundArtifact == null) {
149             foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.SERVICE_API_ARTIFACTS);
150         }
151         if (foundArtifact == null) {
152             foundArtifact = findInterfaceArtifact(parentId, id);
153         }
154         if (foundArtifact == null) {
155             result = Either.right(StorageOperationStatus.NOT_FOUND);
156             return result;
157         }
158         ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(null, foundArtifact);
159         return Either.left(artifactDefResult);
160     }
161
162     private ArtifactDataDefinition findInterfaceArtifact(String parentId, String id) {
163         Either<Map<String, InterfaceDefinition>, JanusGraphOperationStatus> dataFromGraph = getDataFromGraph(parentId, EdgeLabelEnum.INTERFACE);
164         if (dataFromGraph.isRight()) {
165             log.debug("failed to fetch interfaces {} for tosca element with id {}, error {}", id, parentId, dataFromGraph.right().value());
166             return null;
167         }
168         Map<String, InterfaceDefinition> interfaceDefinitionMap = dataFromGraph.left().value();
169         if (interfaceDefinitionMap == null) {
170             return null;
171         }
172         Collection<InterfaceDefinition> interfaces = interfaceDefinitionMap.values();
173         if (interfaces == null) {
174             return null;
175         }
176         for (InterfaceDataDefinition interfaceDataDefinition : interfaces) {
177             Map<String, OperationDataDefinition> operationsMap = interfaceDataDefinition.getOperations();
178             if (operationsMap == null) {
179                 return null;
180             }
181             ArtifactDataDefinition implementationArtifact = getArtifactDataDefinition(id, operationsMap);
182             if (implementationArtifact != null) {
183                 return implementationArtifact;
184             }
185         }
186         return null;
187     }
188
189     private ArtifactDataDefinition getArtifactDataDefinition(String id, Map<String, OperationDataDefinition> operationsMap) {
190         for (OperationDataDefinition operationDataDefinition : operationsMap.values()) {
191             ArtifactDataDefinition implementationArtifact = operationDataDefinition.getImplementation();
192             if (implementationArtifact != null) {
193                 String uniqueId = implementationArtifact.getUniqueId();
194                 if (id.equals(uniqueId)) {
195                     return implementationArtifact;
196                 }
197             }
198         }
199         return null;
200     }
201
202     public Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource(String id, String artifactId, NodeTypeEnum type,
203                                                                                         boolean deleteMandatoryArtifact) {
204         Either<ArtifactDefinition, StorageOperationStatus> status = removeArtifactOnGraph(id, artifactId, type, deleteMandatoryArtifact);
205         if (status.isRight()) {
206             log.debug("Failed to delete artifact {} of resource {}", artifactId, id);
207             BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("Delete Artifact", artifactId, String.valueOf(status.right().value()));
208             return Either.right(status.right().value());
209         } else {
210             return Either.left(status.left().value());
211         }
212     }
213
214     public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType,
215                                                                                         ArtifactGroupTypeEnum groupType, String instanceId) {
216         Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(groupType, parentType);
217         EdgeLabelEnum edgeLabelEnum = triple.getLeft();
218         Either<Map<String, ArtifactDefinition>, JanusGraphOperationStatus> foundArtifact = null;
219         Map<String, ArtifactDefinition> resMap = new HashMap<>();
220         foundArtifact = getArtifactByLabel(parentId, instanceId, edgeLabelEnum);
221         if (foundArtifact.isRight()) {
222             log.debug("Failed to find artifact in component {} with label {} ", parentId, edgeLabelEnum);
223             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(foundArtifact.right().value()));
224         }
225         resMap.putAll(foundArtifact.left().value());
226         return Either.left(resMap);
227     }
228
229     /**
230      * @param parentId   the id of the instance container
231      * @param instanceId the id of the instance of which to return its artifacts
232      * @return instance and instance deployment artifacts mapped by artifact label name
233      */
234     public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getAllInstanceArtifacts(String parentId, String instanceId) {
235         Map<String, ArtifactDataDefinition> resMap = new HashMap<>();
236         Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> instArtifacts = getInstanceArtifactsByLabel(parentId, instanceId,
237             EdgeLabelEnum.INSTANCE_ARTIFACTS);
238         if (instArtifacts.isRight()) {
239             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(instArtifacts.right().value()));
240         }
241         Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> deployInstArtifacts = getInstanceArtifactsByLabel(parentId, instanceId,
242             EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
243         if (deployInstArtifacts.isRight()) {
244             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deployInstArtifacts.right().value()));
245         }
246         resMap.putAll(instArtifacts.left().value());
247         resMap.putAll(deployInstArtifacts.left().value());
248         return Either.left(convertArtifactMapToArtifactDefinitionMap(resMap));
249     }
250
251     public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId) {
252         Either<Map<String, ArtifactDefinition>, JanusGraphOperationStatus> foundArtifact = null;
253         Map<String, ArtifactDefinition> resMap = new HashMap<>();
254         foundArtifact = getArtifactByLabel(parentId, null, EdgeLabelEnum.ARTIFACTS);
255         if (foundArtifact.isLeft()) {
256             resMap.putAll(foundArtifact.left().value());
257         }
258         foundArtifact = getArtifactByLabel(parentId, null, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
259         if (foundArtifact.isLeft()) {
260             resMap.putAll(foundArtifact.left().value());
261         }
262         foundArtifact = getArtifactByLabel(parentId, null, EdgeLabelEnum.TOSCA_ARTIFACTS);
263         if (foundArtifact.isLeft()) {
264             resMap.putAll(foundArtifact.left().value());
265         }
266         return Either.left(resMap);
267     }
268
269     public Either<ArtifactDefinition, StorageOperationStatus> removeArtifactOnGraph(String id, String artifactId, NodeTypeEnum type,
270                                                                                     boolean deleteMandatoryArtifact) {
271         Either<ArtifactDefinition, StorageOperationStatus> artifactData = this.getArtifactById(id, artifactId);
272         if (artifactData.isRight()) {
273             log.debug("Failed to find artifact in component {} with id {} ", id, artifactId);
274             return Either.right(artifactData.right().value());
275         }
276         ArtifactDataDefinition artifactDefinition = artifactData.left().value();
277         boolean isMandatory = false;
278         if ((artifactDefinition.getMandatory() || artifactDefinition.getServiceApi()) && !deleteMandatoryArtifact) {
279             // return Either.left(artifactData.left().value());
280             isMandatory = true;
281         }
282         Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(artifactDefinition.getArtifactGroupType(),
283             type);
284         EdgeLabelEnum edgeLabelEnum = triple.getLeft();
285         VertexTypeEnum vertexTypeEnum = triple.getRight();
286         if (!isMandatory) {
287             StorageOperationStatus status = deleteToscaDataElement(id, edgeLabelEnum, vertexTypeEnum, artifactDefinition.getArtifactLabel(),
288                 JsonPresentationFields.ARTIFACT_LABEL);
289             if (status != StorageOperationStatus.OK) {
290                 return Either.right(status);
291             }
292         }
293         return Either.left(artifactData.left().value());
294     }
295
296     private void updateUUID(Map<String, ArtifactDefinition> deploymentArtifacts, ArtifactDefinition updateArtifactData, String oldChecksum,
297                             String oldVesrion, boolean isUpdate, EdgeLabelEnum edgeLabel, String prevArtUid) {
298         if (oldVesrion == null || oldVesrion.isEmpty()) {
299             oldVesrion = "0";
300         }
301         String currentChecksum = updateArtifactData.getArtifactChecksum();
302         if (isUpdate) {
303             final ArtifactTypeEnum type = ArtifactTypeEnum.parse(updateArtifactData.getArtifactType());
304             if (type == null) {
305                 generateUUIDForNonHeatArtifactType(updateArtifactData, oldChecksum, oldVesrion, currentChecksum);
306                 return;
307             }
308             switch (type) {
309                 case HEAT_ENV:
310                     if (edgeLabel == EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS) {
311                         generateUUID(updateArtifactData, oldVesrion);
312                     }
313                     break;
314                 case HEAT:
315                 case HEAT_NET:
316                 case HEAT_VOL:
317                     boolean changed = false;
318                     Optional<Entry<String, ArtifactDefinition>> any = deploymentArtifacts.entrySet().stream()
319                         .filter(e -> e.getKey().equals(updateArtifactData.getArtifactLabel())).findAny();
320                     if (any.isPresent()) {
321                         if (!any.get().getValue().getArtifactChecksum().equals(updateArtifactData.getArtifactChecksum())) {
322                             changed = true;
323                         }
324                     }
325                     Optional<Entry<String, ArtifactDefinition>> anyEnv = deploymentArtifacts.entrySet().stream()
326                         .filter(e -> prevArtUid.equals(e.getValue().getGeneratedFromId())).findAny();
327                     if (anyEnv.isPresent() && anyEnv.get().getValue().getHeatParamUpdated()) {
328                         String newCheckSum = sortAndCalculateChecksumForHeatParameters(updateArtifactData.getHeatParameters());
329                         if (!anyEnv.get().getValue().getArtifactChecksum().equals(newCheckSum)) {
330                             changed = true;
331                             anyEnv.get().getValue().setArtifactChecksum(newCheckSum);
332                             UUID uuid = UUID.randomUUID();
333                             anyEnv.get().getValue().setArtifactUUID(uuid.toString());
334                         }
335                     }
336                     if (changed && anyEnv.isPresent()) {
337                         generateUUID(updateArtifactData, oldVesrion);
338                         anyEnv.get().getValue().setGeneratedFromId(updateArtifactData.getUniqueId());
339                         anyEnv.get().getValue().setDuplicated(false);
340                         anyEnv.get().getValue().setArtifactVersion(updateArtifactData.getArtifactVersion());
341                         anyEnv.get().getValue().setHeatParamUpdated(false);
342                     }
343                     break;
344                 default:
345                     generateUUIDForNonHeatArtifactType(updateArtifactData, oldChecksum, oldVesrion, currentChecksum);
346                     break;
347             }
348         } else {
349             generateUUIDForNonHeatArtifactType(updateArtifactData, oldChecksum, oldVesrion, currentChecksum);
350         }
351     }
352
353     private void generateUUIDForNonHeatArtifactType(ArtifactDataDefinition artifactData, String oldChecksum, String oldVesrion,
354                                                     String currentChecksum) {
355         if (oldChecksum == null || oldChecksum.isEmpty()) {
356             if (currentChecksum != null) {
357                 generateUUID(artifactData, oldVesrion);
358             }
359         } else if ((currentChecksum != null && !currentChecksum.isEmpty()) && !oldChecksum.equals(currentChecksum)) {
360             generateUUID(artifactData, oldVesrion);
361         }
362     }
363
364     public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifactHeat,
365                                                                                  Component component, NodeTypeEnum parentType, boolean failIfExist,
366                                                                                  String instanceId) {
367         artifactHeatEnv.setGeneratedFromId(artifactHeat.getUniqueId());
368         return addArtifactToComponent(artifactHeatEnv, component, parentType, failIfExist, instanceId);
369     }
370
371     public Either<ArtifactDefinition, StorageOperationStatus> getHeatArtifactByHeatEnvId(final String parentId, final ArtifactDefinition heatEnv,
372                                                                                          final String containerId,
373                                                                                          final ComponentTypeEnum componentType) {
374         return getArtifactById(parentId, heatEnv.getGeneratedFromId(), componentType, containerId);
375     }
376
377     public Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact(Component component, ArtifactDefinition artifactEnvInfo,
378                                                                                     String artifactId, String newArtifactId, NodeTypeEnum type,
379                                                                                     String instanceId) {
380         Either<Map<String, ArtifactDefinition>, JanusGraphOperationStatus> artifactsEither = getArtifactByLabel(component.getUniqueId(), instanceId,
381             EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
382         return updateHeatEnvArtifact(artifactsEither, component, artifactEnvInfo, artifactId, newArtifactId, type, instanceId);
383     }
384
385     private Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact(
386         Either<Map<String, ArtifactDefinition>, JanusGraphOperationStatus> artifactsEither, Component component, ArtifactDefinition artifactEnvInfo,
387         String artifactId, String newArtifactId, NodeTypeEnum type, String instanceId) {
388         String id = component.getUniqueId();
389         if (artifactsEither.isRight()) {
390             log.debug("Failed to find artifacts in component {} with id {} ", id, artifactsEither.right().value());
391             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(artifactsEither.right().value()));
392         }
393         Map<String, ArtifactDefinition> artifacts = artifactsEither.left().value();
394         List<ArtifactDefinition> envList = artifacts.values().stream()
395             .filter(a -> a.getGeneratedFromId() != null && a.getGeneratedFromId().equals(artifactId)).collect(Collectors.toList());
396         if (envList != null && !envList.isEmpty()) {
397             envList.forEach(a -> {
398                 a.setGeneratedFromId(newArtifactId);
399                 updateArtifactOnResource(a, component, a.getUniqueId(), type, instanceId, true);
400             });
401         }
402         return Either.left(artifactEnvInfo);
403     }
404
405     public Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifactOnInstance(Component component, ArtifactDefinition artifactEnvInfo,
406                                                                                               String artifactId, String newArtifactId,
407                                                                                               NodeTypeEnum type, String instanceId) {
408         String id = component.getUniqueId();
409         Either<Map<String, ArtifactDefinition>, JanusGraphOperationStatus> artifactsEither = getArtifactByLabel(id, instanceId,
410             EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
411         return updateHeatEnvArtifact(artifactsEither, component, artifactEnvInfo, artifactId, newArtifactId, type, instanceId);
412     }
413
414     public Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvPlaceholder(ArtifactDefinition artifactInfo, Component parent,
415                                                                                        NodeTypeEnum type) {
416         return updateArtifactOnResource(artifactInfo, parent, artifactInfo.getUniqueId(), type, null, true);
417     }
418
419     ///////////////////////////////////////////// private methods ////////////////////////////////////////////////////
420     protected ArtifactDefinition convertArtifactDataToArtifactDefinition(ArtifactDefinition artifactInfo, ArtifactDataDefinition artifactDefResult) {
421         log.debug("The object returned after create property is {}", artifactDefResult);
422         ArtifactDefinition propertyDefResult = new ArtifactDefinition(artifactDefResult);
423         if (artifactInfo != null) {
424             propertyDefResult.setPayload(artifactInfo.getPayloadData());
425         }
426         List<HeatParameterDefinition> parameters = new ArrayList<>();
427         /*
428          * StorageOperationStatus heatParametersOfNode = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefResult.getUniqueId().toString(), parameters); if ((heatParametersOfNode.equals(StorageOperationStatus.OK))
429          * && !parameters.isEmpty()) { propertyDefResult.setHeatParameters(parameters); }
430          */
431         return propertyDefResult;
432     }
433
434     private ArtifactDataDefinition getInstanceArtifactByLabelAndId(String parentId, String id, String containerId, EdgeLabelEnum edgeLabelEnum) {
435         ArtifactDataDefinition foundArtifact = null;
436         Either<Map<String, MapArtifactDataDefinition>, JanusGraphOperationStatus> artifactsEither = getDataFromGraph(containerId, edgeLabelEnum);
437         if (artifactsEither.isRight()) {
438             log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, edgeLabelEnum, containerId, artifactsEither.right().value());
439             return null;
440         }
441         Map<String, MapArtifactDataDefinition> artifacts = artifactsEither.left().value();
442         MapArtifactDataDefinition artifactsPerInstance = artifacts.get(parentId);
443         if (artifactsPerInstance == null) {
444             log.debug("failed to fetch artifacts for instance {} in tosca element with id {}, error {}", parentId, containerId,
445                 artifactsEither.right().value());
446             return null;
447         }
448         Optional<ArtifactDataDefinition> op = artifactsPerInstance.getMapToscaDataDefinition().values().stream()
449             .filter(p -> p.getUniqueId().equals(id)).findAny();
450         if (op.isPresent()) {
451             foundArtifact = op.get();
452         }
453         return foundArtifact;
454     }
455
456     private ArtifactDataDefinition getArtifactByLabelAndId(String parentId, String id, EdgeLabelEnum edgeLabelEnum) {
457         ArtifactDataDefinition foundArtifact = null;
458         Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> artifactsEither = getDataFromGraph(parentId, edgeLabelEnum);
459         if (artifactsEither.isRight()) {
460             log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, edgeLabelEnum, parentId, artifactsEither.right().value());
461             return null;
462         }
463         Map<String, ArtifactDataDefinition> artifacts = artifactsEither.left().value();
464         Optional<ArtifactDataDefinition> op = artifacts.values().stream().filter(p -> p.getUniqueId().equals(id)).findAny();
465         if (op.isPresent()) {
466             foundArtifact = op.get();
467         }
468         return foundArtifact;
469     }
470
471     private Either<Map<String, ArtifactDefinition>, JanusGraphOperationStatus> getArtifactByLabel(String parentId, String instanceId,
472                                                                                                   EdgeLabelEnum edgeLabelEnum) {
473         Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> artifactsEither = getArtifactsDataByLabel(parentId, instanceId,
474             edgeLabelEnum);
475         if (artifactsEither.isRight()) {
476             log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, edgeLabelEnum, parentId, artifactsEither.right().value());
477             return Either.right(artifactsEither.right().value());
478         }
479         Map<String, ArtifactDataDefinition> artifactDataMap = artifactsEither.left().value();
480         return Either.left(convertArtifactMapToArtifactDefinitionMap(artifactDataMap));
481     }
482
483     private Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> getArtifactsDataByLabel(String parentId, String instanceId,
484                                                                                                            EdgeLabelEnum edgeLabelEnum) {
485         return edgeLabelEnum.isInstanceArtifactsLabel() ? getInstanceArtifactsByLabel(parentId, instanceId, edgeLabelEnum)
486             : getDataFromGraph(parentId, edgeLabelEnum);
487     }
488
489     private Map<String, ArtifactDefinition> convertArtifactMapToArtifactDefinitionMap(Map<String, ArtifactDataDefinition> artifactDataMap) {
490         Map<String, ArtifactDefinition> artMap = new HashMap<>();
491         if (artifactDataMap != null && !artifactDataMap.isEmpty()) {
492             artMap = artifactDataMap.entrySet().stream()
493                 .collect(Collectors.toMap(Entry::getKey, e -> convertArtifactDataToArtifactDefinition(null, e.getValue())));
494         }
495         return artMap;
496     }
497
498     private Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> getInstanceArtifactsByLabel(String parentId, String instanceId,
499                                                                                                                EdgeLabelEnum edgeLabelEnum) {
500         Either<Map<String, MapArtifactDataDefinition>, JanusGraphOperationStatus> resultEither = getDataFromGraph(parentId, edgeLabelEnum);
501         if (resultEither.isRight()) {
502             log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, edgeLabelEnum, parentId, resultEither.right().value());
503             return Either.right(resultEither.right().value());
504         }
505         Map<String, MapArtifactDataDefinition> mapArtifacts = resultEither.left().value();
506         MapArtifactDataDefinition artifactPerInstance = mapArtifacts.get(instanceId);
507         return artifactPerInstance != null ? Either.left(artifactPerInstance.getMapToscaDataDefinition()) : Either.left(new HashMap<>());
508     }
509
510     private Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> getEdgeLabelEnumFromArtifactGroupType(ArtifactGroupTypeEnum groupType,
511                                                                                                  NodeTypeEnum nodeType) {
512         EdgeLabelEnum edgeLabelEnum;
513         VertexTypeEnum vertexTypeEnum;
514         Boolean isDeepElement = false;
515         /*
516          * if (nodeType == NodeTypeEnum.ResourceInstance) { edgeLabelEnum = EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS; vertexTypeEnum = VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS; isDeepElement = true; } else {
517          */
518         switch (groupType) {
519             case TOSCA:
520                 edgeLabelEnum = EdgeLabelEnum.TOSCA_ARTIFACTS;
521                 vertexTypeEnum = VertexTypeEnum.TOSCA_ARTIFACTS;
522                 break;
523             case DEPLOYMENT:
524                 if (nodeType == NodeTypeEnum.ResourceInstance) {
525                     edgeLabelEnum = EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS;
526                     vertexTypeEnum = VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS;
527                     isDeepElement = true;
528                 } else {
529                     edgeLabelEnum = EdgeLabelEnum.DEPLOYMENT_ARTIFACTS;
530                     vertexTypeEnum = VertexTypeEnum.DEPLOYMENT_ARTIFACTS;
531                 }
532                 break;
533             case SERVICE_API:
534                 edgeLabelEnum = EdgeLabelEnum.SERVICE_API_ARTIFACTS;
535                 vertexTypeEnum = VertexTypeEnum.SERVICE_API_ARTIFACTS;
536                 break;
537             default:
538                 if (nodeType == NodeTypeEnum.ResourceInstance) {
539                     edgeLabelEnum = EdgeLabelEnum.INSTANCE_ARTIFACTS;
540                     vertexTypeEnum = VertexTypeEnum.INSTANCE_ARTIFACTS;
541                     isDeepElement = true;
542                 } else {
543                     edgeLabelEnum = EdgeLabelEnum.ARTIFACTS;
544                     vertexTypeEnum = VertexTypeEnum.ARTIFACTS;
545                 }
546                 break;
547         }
548         // }
549         return new ImmutableTriple<>(edgeLabelEnum, isDeepElement, vertexTypeEnum);
550     }
551
552     public Either<ArtifactDataDefinition, StorageOperationStatus> updateArtifactOnGraph(Component component, ArtifactDefinition artifactInfo,
553                                                                                         NodeTypeEnum type, String artifactId, String instanceId,
554                                                                                         boolean isUpdate, boolean isDeletePlaceholder) {
555         String componentId = component.getUniqueId();
556         Either<ArtifactDataDefinition, StorageOperationStatus> res = null;
557         ArtifactDefinition artifactToUpdate = new ArtifactDefinition(artifactInfo);
558         ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
559         Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(groupType, type);
560         EdgeLabelEnum edgeLabelEnum = triple.getLeft();
561         VertexTypeEnum vertexTypeEnum = triple.getRight();
562         Either<Boolean, StorageOperationStatus> isNeedToCloneEither = isCloneNeeded(componentId, edgeLabelEnum);
563         if (isNeedToCloneEither.isRight()) {
564             log.debug("Failed check is clone needed {}", componentId);
565             return Either.right(isNeedToCloneEither.right().value());
566         }
567         boolean isNeedToClone = isNeedToCloneEither.left().value();
568         String prevArtUid = artifactToUpdate.getUniqueId();
569         if (artifactId == null || isNeedToClone) {
570             String uniqueId;
571             if (edgeLabelEnum != EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS && edgeLabelEnum != EdgeLabelEnum.INSTANCE_ARTIFACTS) {
572                 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(componentId, artifactToUpdate.getArtifactLabel());
573             } else {
574                 uniqueId = UniqueIdBuilder.buildInstanceArtifactUniqueId(componentId, instanceId, artifactToUpdate.getArtifactLabel());
575             }
576             prevArtUid = artifactToUpdate.getUniqueId();
577             artifactToUpdate.setUniqueId(uniqueId);
578             if (!isDeletePlaceholder) {
579                 artifactToUpdate.setEsId(uniqueId);
580             }
581         } else {
582             artifactToUpdate.setUniqueId(artifactId);
583         }
584         Map<String, ArtifactDefinition> artifacts = new HashMap<>();
585         Map<String, MapArtifactDataDefinition> artifactInst = null;
586         if (edgeLabelEnum != EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS && edgeLabelEnum != EdgeLabelEnum.INSTANCE_ARTIFACTS) {
587             Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> artifactsEither = this
588                 .getDataFromGraph(componentId, edgeLabelEnum);
589             if (artifactsEither.isLeft() && artifactsEither.left().value() != null && !artifactsEither.left().value().isEmpty()) {
590                 artifacts = convertArtifactMapToArtifactDefinitionMap(artifactsEither.left().value());
591                 if (isNeedToClone && artifacts != null) {
592                     artifacts.values().stream().forEach(a -> a.setDuplicated(Boolean.TRUE));
593                 }
594             }
595         } else {
596             Either<Map<String, MapArtifactDataDefinition>, JanusGraphOperationStatus> artifactsEither = this
597                 .getDataFromGraph(componentId, edgeLabelEnum);
598             if (artifactsEither.isLeft()) {
599                 artifactInst = artifactsEither.left().value();
600                 if (isNeedToClone && artifactInst != null) {
601                     artifactInst.values().forEach(ma -> ma.getMapToscaDataDefinition().values().forEach(a -> a.setDuplicated(Boolean.TRUE)));
602                 }
603                 MapArtifactDataDefinition artifatcsOnInstance = artifactInst.get(instanceId);
604                 if (artifatcsOnInstance != null) {
605                     artifacts = convertArtifactMapToArtifactDefinitionMap(artifatcsOnInstance.getMapToscaDataDefinition());
606                 }
607             }
608         }
609         String oldChecksum = null;
610         String oldVersion = null;
611         if (artifacts != null && artifacts.containsKey(artifactInfo.getArtifactLabel())) {
612             ArtifactDataDefinition oldArtifactData = artifacts.get(artifactInfo.getArtifactLabel());
613             oldChecksum = oldArtifactData.getArtifactChecksum();
614             oldVersion = oldArtifactData.getArtifactVersion();
615             //duplicated flag didn't receive from UI, take from DB
616             artifactToUpdate.setDuplicated(oldArtifactData.getDuplicated());
617             if (isNeedToClone) {
618                 artifactToUpdate.setDuplicated(Boolean.FALSE);
619             } else {
620                 if (artifactToUpdate.getDuplicated()) {
621                     String uniqueId = "";
622                     if (type != NodeTypeEnum.ResourceInstance) {
623                         uniqueId = UniqueIdBuilder.buildPropertyUniqueId(componentId, artifactToUpdate.getArtifactLabel());
624                     } else {
625                         uniqueId = UniqueIdBuilder.buildInstanceArtifactUniqueId(componentId, instanceId, artifactToUpdate.getArtifactLabel());
626                     }
627                     artifactToUpdate.setUniqueId(uniqueId);
628                     if (!isDeletePlaceholder) {
629                         artifactToUpdate.setEsId(uniqueId);
630                     }
631                     artifactToUpdate.setDuplicated(Boolean.FALSE);
632                 }
633             }
634         }
635         updateUUID(artifacts, artifactToUpdate, oldChecksum, oldVersion, isUpdate, edgeLabelEnum, prevArtUid);
636         if (artifactInfo.getPayloadData() == null) {
637             if (!artifactToUpdate.getMandatory() || artifactToUpdate.getEsId() != null) {
638                 artifactToUpdate.setEsId(artifactToUpdate.getUniqueId());
639             }
640         } else {
641             if (artifactToUpdate.getEsId() == null) {
642                 artifactToUpdate.setEsId(artifactToUpdate.getUniqueId());
643             }
644         }
645         StorageOperationStatus status = StorageOperationStatus.OK;
646         if (edgeLabelEnum != EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS && edgeLabelEnum != EdgeLabelEnum.INSTANCE_ARTIFACTS) {
647             List<ArtifactDefinition> toscaDataList = new ArrayList<>();
648             toscaDataList.add(artifactToUpdate);
649             if (isNeedToClone && artifacts != null) {
650                 artifacts.values().stream().filter(a -> !a.getArtifactLabel().equals(artifactToUpdate.getArtifactLabel()))
651                     .forEach(toscaDataList::add);
652             } else {
653                 if (artifacts != null) {
654                     artifacts.values().stream().filter(a -> artifactToUpdate.getUniqueId().equals(a.getGeneratedFromId()))
655                         .forEach(toscaDataList::add);
656                 }
657             }
658             status = updateToscaDataOfToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, toscaDataList, JsonPresentationFields.ARTIFACT_LABEL);
659         } else {
660             List<ArtifactDataDefinition> toscaDataList = new ArrayList<>();
661             toscaDataList.add(artifactToUpdate);
662             List<String> pathKeys = new ArrayList<>();
663             pathKeys.add(instanceId);
664             if (isNeedToClone) {
665                 if (artifactInst != null) {
666                     MapArtifactDataDefinition artifatcsOnInstance = artifactInst.get(instanceId);
667                     if (artifatcsOnInstance != null) {
668                         Map<String, ArtifactDataDefinition> mapToscaDataDefinition = artifatcsOnInstance.getMapToscaDataDefinition();
669                         ArtifactDataDefinition artifactDataDefinitionToUpdate = new ArtifactDataDefinition(artifactToUpdate);
670                         mapToscaDataDefinition.put(artifactToUpdate.getArtifactLabel(), artifactDataDefinitionToUpdate);
671                     }
672                     for (Entry<String, MapArtifactDataDefinition> e : artifactInst.entrySet()) {
673                         List<ArtifactDataDefinition> toscaDataListPerInst = e.getValue().getMapToscaDataDefinition().values().stream()
674                             .collect(Collectors.toList());
675                         List<String> pathKeysPerInst = new ArrayList<>();
676                         pathKeysPerInst.add(e.getKey());
677                         status = updateToscaDataDeepElementsOfToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, toscaDataListPerInst,
678                             pathKeysPerInst, JsonPresentationFields.ARTIFACT_LABEL);
679                         if (status != StorageOperationStatus.OK) {
680                             log.debug("Failed to update atifacts group for instance {} in component {} edge type {} error {}", instanceId,
681                                 componentId, edgeLabelEnum, status);
682                             res = Either.right(status);
683                             break;
684                         }
685                     }
686                 }
687             } else {
688                 status = updateToscaDataDeepElementsOfToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, toscaDataList, pathKeys,
689                     JsonPresentationFields.ARTIFACT_LABEL);
690             }
691         }
692         if (status == StorageOperationStatus.OK) {
693             res = Either.left(artifactToUpdate);
694         } else {
695             res = Either.right(status);
696         }
697         return res;
698     }
699
700     public void generateUUID(ArtifactDataDefinition artifactData, String oldVesrion) {
701         UUID uuid = UUID.randomUUID();
702         artifactData.setArtifactUUID(uuid.toString());
703         MDC.put(ILogConfiguration.MDC_SERVICE_INSTANCE_ID, uuid.toString());
704         updateVersionAndDate(artifactData, oldVesrion);
705     }
706
707     private void updateVersionAndDate(ArtifactDataDefinition artifactData, String oldVesrion) {
708         if (artifactData.getArtifactChecksum() != null) {
709             long time = System.currentTimeMillis();
710             artifactData.setPayloadUpdateDate(time);
711         }
712         int newVersion = new Integer(oldVesrion).intValue();
713         newVersion++;
714         artifactData.setArtifactVersion(String.valueOf(newVersion));
715     }
716
717     public Either<ArtifactDataDefinition, StorageOperationStatus> removeArtifactOnGraph(ArtifactDefinition artifactFromGraph, String componentId,
718                                                                                         String instanceId, NodeTypeEnum type,
719                                                                                         boolean deleteMandatoryArtifact) {
720         Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(artifactFromGraph.getArtifactGroupType(), type);
721         EdgeLabelEnum edgeLabelEnum = triple.getLeft();
722         VertexTypeEnum vertexTypeEnum = triple.getRight();
723         if (deleteMandatoryArtifact || !(artifactFromGraph.getMandatory() || artifactFromGraph.getServiceApi())) {
724             StorageOperationStatus status;
725             if (triple.getMiddle()) {
726                 List<String> pathKeys = new ArrayList<>();
727                 pathKeys.add(instanceId);
728                 status = deleteToscaDataDeepElement(componentId, edgeLabelEnum, vertexTypeEnum, artifactFromGraph.getArtifactLabel(), pathKeys,
729                     JsonPresentationFields.ARTIFACT_LABEL);
730             } else {
731                 status = deleteToscaDataElement(componentId, edgeLabelEnum, vertexTypeEnum, artifactFromGraph.getArtifactLabel(),
732                     JsonPresentationFields.ARTIFACT_LABEL);
733             }
734             if (status != StorageOperationStatus.OK) {
735                 return Either.right(status);
736             }
737         }
738         return Either.left(artifactFromGraph);
739     }
740
741     public Either<ArtifactDataDefinition, StorageOperationStatus> deleteArtifactWithCloningOnGraph(String componentId,
742                                                                                                    ArtifactDefinition artifactToDelete,
743                                                                                                    NodeTypeEnum type, String instanceId,
744                                                                                                    boolean deleteMandatoryArtifact) {
745         Either<ArtifactDataDefinition, StorageOperationStatus> result = null;
746         Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(artifactToDelete.getArtifactGroupType(), type);
747         EdgeLabelEnum edgeLabel = triple.getLeft();
748         VertexTypeEnum vertexLabel = triple.getRight();
749         Boolean deleteElement = deleteMandatoryArtifact || !(artifactToDelete.getMandatory() || artifactToDelete.getServiceApi());
750         Map<String, ToscaDataDefinition> artifacts = null;
751         GraphVertex parentVertex = null;
752         Either<Map<String, ToscaDataDefinition>, JanusGraphOperationStatus> getArtifactsRes = null;
753         Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
754         if (getToscaElementRes.isRight()) {
755             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon getting tosca data from graph. Status is {}. ",
756                 componentId, getToscaElementRes.right().value());
757             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getToscaElementRes.right().value()));
758         }
759         if (result == null) {
760             parentVertex = getToscaElementRes.left().value();
761             getArtifactsRes = this.getDataFromGraph(parentVertex, edgeLabel);
762             if (getArtifactsRes.isRight()) {
763                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getArtifactsRes.right().value()));
764             }
765         }
766         if (result == null) {
767             artifacts = getArtifactsRes.left().value();
768             if (triple.getMiddle()) {
769                 artifacts.values()
770                     .forEach(ma -> ((MapArtifactDataDefinition) ma).getMapToscaDataDefinition().values().forEach(a -> a.setDuplicated(Boolean.TRUE)));
771                 MapArtifactDataDefinition artifatcsOnInstance = (MapArtifactDataDefinition) artifacts.get(instanceId);
772                 if (artifatcsOnInstance != null && deleteElement) {
773                     artifatcsOnInstance.getMapToscaDataDefinition().remove(artifactToDelete.getArtifactLabel());
774                 }
775             } else {
776                 if (deleteElement) {
777                     artifacts.remove(artifactToDelete.getArtifactLabel());
778                 }
779                 artifacts.values().stream().forEach(a -> ((ArtifactDataDefinition) a).setDuplicated(Boolean.TRUE));
780             }
781             artifactToDelete.setDuplicated(Boolean.TRUE);
782         }
783         if (artifacts != null) {
784             JanusGraphOperationStatus status = janusGraphDao.deleteEdgeByDirection(parentVertex, Direction.OUT, edgeLabel);
785             if (status != JanusGraphOperationStatus.OK) {
786                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
787             } else if (MapUtils.isNotEmpty(artifacts)) {
788                 Either<GraphVertex, StorageOperationStatus> associateResult = associateElementToData(parentVertex, vertexLabel, edgeLabel, artifacts);
789                 if (associateResult.isRight()) {
790                     result = Either.right(associateResult.right().value());
791                 }
792             }
793         }
794         if (result == null) {
795             result = Either.left(artifactToDelete);
796         }
797         return result;
798     }
799
800     public String sortAndCalculateChecksumForHeatParameters(List<HeatParameterDataDefinition> heatParameters) {
801         StrBuilder sb = new StrBuilder();
802         heatParameters.stream().sorted(Comparator.comparingInt(HeatParameterDataDefinition::hashCode)).map(HeatParameterDataDefinition::hashCode)
803             .collect(Collectors.toSet()).forEach(sb::append);
804         return GeneralUtility.calculateMD5Base64EncodedByString(sb.toString());
805     }
806 }