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