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