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