Catalog alignment
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / operations / impl / ArtifactOperation.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.operations.impl;
22
23 import org.janusgraph.core.JanusGraph;
24 import org.janusgraph.core.JanusGraphVertex;
25 import fj.data.Either;
26 import org.apache.commons.lang3.tuple.ImmutablePair;
27 import org.apache.tinkerpop.gremlin.structure.Direction;
28 import org.apache.tinkerpop.gremlin.structure.Edge;
29 import org.apache.tinkerpop.gremlin.structure.Vertex;
30 import org.openecomp.sdc.be.config.BeEcompErrorManager;
31 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
32 import org.openecomp.sdc.be.dao.graph.GraphElementFactory;
33 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
34 import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum;
35 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
36 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
37 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
38 import org.openecomp.sdc.be.dao.neo4j.GraphEdgePropertiesDictionary;
39 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
40 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao;
41 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
42 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
43 import org.openecomp.sdc.be.model.ArtifactDefinition;
44 import org.openecomp.sdc.be.model.HeatParameterDefinition;
45 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
46 import org.openecomp.sdc.be.resources.data.ArtifactData;
47 import org.openecomp.sdc.be.resources.data.HeatParameterData;
48 import org.openecomp.sdc.be.resources.data.HeatParameterValueData;
49 import org.openecomp.sdc.be.resources.data.UniqueIdData;
50 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
51 import org.openecomp.sdc.common.log.api.ILogConfiguration;
52 import org.openecomp.sdc.common.log.wrappers.Logger;
53 import org.slf4j.MDC;
54 import org.springframework.stereotype.Component;
55
56 import java.util.*;
57
58 @Component("artifact-operation")
59 public class ArtifactOperation {
60
61     private static final String THE_RETURNED_ARTIFACT_DEFINTION_IS = "The returned ArtifactDefintion is {}";
62
63         @javax.annotation.Resource
64     private JanusGraphGenericDao janusGraphGenericDao;
65
66     @javax.annotation.Resource
67     private HeatParametersOperation heatParametersOperation;
68
69     @javax.annotation.Resource
70     private GroupOperation groupOperation;
71     @javax.annotation.Resource
72     private GroupInstanceOperation groupInstanceOperation;
73
74     private static final Logger log = Logger.getLogger(ArtifactOperation.class.getName());
75
76     public ArtifactOperation() {
77         super();
78     }
79
80     public JanusGraphGenericDao getJanusGraphGenericDao() {
81         return janusGraphGenericDao;
82     }
83
84     public void setJanusGraphGenericDao(JanusGraphGenericDao janusGraphGenericDao) {
85         this.janusGraphGenericDao = janusGraphGenericDao;
86     }
87
88     public HeatParametersOperation getHeatParametersOperation() {
89         return heatParametersOperation;
90     }
91
92     public void setHeatParametersOperation(HeatParametersOperation heatParametersOperation) {
93         this.heatParametersOperation = heatParametersOperation;
94     }
95
96     public Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, boolean inTransaction) {
97
98         Either<ArtifactData, StorageOperationStatus> status = addArtifactToGraph(artifactInfo, parentId, type, failIfExist);
99
100         if (status.isRight()) {
101             if (!inTransaction) {
102                 janusGraphGenericDao.rollback();
103             }
104             log.debug("Failed to add artifact {} to {} {}", artifactInfo.getArtifactName(), type , parentId);
105             return Either.right(status.right().value());
106         } else {
107             if (!inTransaction) {
108                 janusGraphGenericDao.commit();
109             }
110             ArtifactData artifactData = status.left().value();
111
112             ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData);
113
114             log.debug(THE_RETURNED_ARTIFACT_DEFINTION_IS, artifactDefResult);
115             return Either.left(artifactDefResult);
116         }
117
118     }
119
120     public StorageOperationStatus addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, JanusGraphVertex parentVertex) {
121
122         StorageOperationStatus status = addArtifactToGraph(artifactInfo, parentId, type, failIfExist, parentVertex);
123
124         if (status.equals(StorageOperationStatus.OK)) {
125             log.debug("Failed to add artifact {} {} to {}", artifactInfo.getArtifactName(), type, parentId);
126         }
127         return status;
128     }
129
130     private StorageOperationStatus addArtifactToGraph(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfexist, JanusGraphVertex parentVertex) {
131
132         if (artifactInfo.getUniqueId() == null || artifactInfo.getUniqueId().isEmpty()) {
133             String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel());
134             artifactInfo.setUniqueId(uniqueId);
135         }
136
137         if (!validateParentType(type)) {
138             return StorageOperationStatus.GENERAL_ERROR;
139         }
140
141         ArtifactData artifactData = new ArtifactData(artifactInfo);
142
143         Either<JanusGraphVertex, JanusGraphOperationStatus> existArtifact = janusGraphGenericDao
144             .getVertexByProperty(artifactData.getUniqueIdKey(), artifactData.getUniqueId());
145         if (existArtifact.isRight()) {
146             if (existArtifact.right().value().equals(JanusGraphOperationStatus.NOT_FOUND)) {
147                 // create new node
148                 log.debug("Before adding artifact to graph {}", artifactData);
149                 if (artifactData.getArtifactDataDefinition().getArtifactUUID() == null || artifactData.getArtifactDataDefinition().getArtifactUUID().isEmpty())
150                     updateUUID(artifactData.getArtifactDataDefinition(), null, artifactData.getArtifactDataDefinition().getArtifactVersion());
151                 Either<JanusGraphVertex, JanusGraphOperationStatus> createNodeResult = janusGraphGenericDao.createNode(artifactData);
152
153                 if (createNodeResult.isRight()) {
154                     JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
155                     log.debug("Failed to add artifact {} to graph. status is {}", artifactData.getArtifactDataDefinition().getArtifactName(), operationStatus);
156                     BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add artifact", artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus));
157                     return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(operationStatus);
158                 }
159
160                 // add heat parameters
161                 if (artifactInfo.getHeatParameters() != null && !artifactInfo.getHeatParameters().isEmpty() && !artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
162                     StorageOperationStatus addPropertiesStatus = heatParametersOperation.addPropertiesToGraph(artifactInfo.getListHeatParameters(), artifactData.getUniqueId().toString(), NodeTypeEnum.ArtifactRef);
163                     if (addPropertiesStatus != StorageOperationStatus.OK) {
164                         log.debug("Failed to create heat parameters on graph for artifact {}", artifactInfo.getArtifactName());
165                         return addPropertiesStatus;
166                     }
167                 }
168
169             } else {
170                 log.debug("Failed to check existance of artifact in graph for id {}", artifactData.getUniqueId());
171                 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(existArtifact.right().value());
172             }
173         } else if (failIfexist) {
174             log.debug("Artifact {} already exist", artifactData.getUniqueId());
175             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ALREADY_EXIST);
176         }
177
178         // save logical artifact ref name on edge as property
179         Map<String, Object> properties = new HashMap<>();
180         properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), artifactInfo.getArtifactLabel());
181         if (artifactInfo.getArtifactGroupType() != null)
182             properties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), artifactInfo.getArtifactGroupType().getType());
183         JanusGraphOperationStatus relation = janusGraphGenericDao
184             .createEdge(parentVertex, artifactData, GraphEdgeLabels.ARTIFACT_REF, properties);
185         if (!relation.equals(JanusGraphOperationStatus.OK)) {
186             log.debug("Failed to create relation in graph for id {} to new artifact", id);
187             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(relation);
188         }
189
190         return StorageOperationStatus.OK;
191     }
192
193     private Either<ArtifactData, StorageOperationStatus> addArtifactToGraph(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfexist) {
194
195         if (artifactInfo.getUniqueId() == null || artifactInfo.getUniqueId().isEmpty()) {
196             String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel());
197             artifactInfo.setUniqueId(uniqueId);
198         }
199
200         if (!validateParentType(type)) {
201             return Either.right(StorageOperationStatus.GENERAL_ERROR);
202         }
203
204         ArtifactData artifactData = new ArtifactData(artifactInfo);
205
206         Either<ArtifactData, JanusGraphOperationStatus> existArtifact = janusGraphGenericDao
207             .getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class);
208         if (existArtifact.isRight()) {
209             if (existArtifact.right().value().equals(JanusGraphOperationStatus.NOT_FOUND)) {
210                 // create new node
211                 log.debug("Before adding artifact to graph {}" , artifactData);
212                 if (artifactData.getArtifactDataDefinition().getArtifactUUID() == null || artifactData.getArtifactDataDefinition().getArtifactUUID().isEmpty())
213                     updateUUID(artifactData.getArtifactDataDefinition(), null, artifactData.getArtifactDataDefinition().getArtifactVersion());
214                 Either<ArtifactData, JanusGraphOperationStatus> createNodeResult = janusGraphGenericDao
215                     .createNode(artifactData, ArtifactData.class);
216                 log.debug("After adding artifact to graph {}", artifactData);
217
218                 if (createNodeResult.isRight()) {
219                     JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
220                     log.debug("Failed to add artifact {} to graph. status is {}", artifactData.getArtifactDataDefinition().getArtifactName(), operationStatus);
221                     BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add artifact", artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus));
222                     return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(operationStatus));
223                 }
224                 artifactData = createNodeResult.left().value();
225
226                 // add heat parameters
227                 if (artifactInfo.getHeatParameters() != null && !artifactInfo.getHeatParameters().isEmpty() && !artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
228                     StorageOperationStatus addPropertiesStatus = heatParametersOperation.addPropertiesToGraph(artifactInfo.getListHeatParameters(), artifactData.getUniqueId().toString(), NodeTypeEnum.ArtifactRef);
229                     if (addPropertiesStatus != StorageOperationStatus.OK) {
230                         log.debug("Failed to create heat parameters on graph for artifact {}", artifactInfo.getArtifactName());
231                         return Either.right(addPropertiesStatus);
232                     }
233                 }
234
235             } else {
236                 log.debug("Failed to check existance of artifact in graph for id {}", artifactData.getUniqueId());
237                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(existArtifact.right().value()));
238             }
239         } else if (failIfexist) {
240             log.debug("Artifact {} already exist", artifactData.getUniqueId());
241             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
242                 JanusGraphOperationStatus.ALREADY_EXIST));
243         } else {
244             artifactData = existArtifact.left().value();
245         }
246
247         UniqueIdData parent = new UniqueIdData(type, id);
248
249         // save logical artifact ref name on edge as property
250         Map<String, Object> properties = new HashMap<>();
251         properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), artifactInfo.getArtifactLabel());
252         if (artifactInfo.getArtifactGroupType() != null)
253             properties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), artifactInfo.getArtifactGroupType().getType());
254         Either<GraphRelation, JanusGraphOperationStatus> relation = janusGraphGenericDao
255             .createRelation(parent, artifactData, GraphEdgeLabels.ARTIFACT_REF, properties);
256         if (relation.isRight()) {
257             log.debug("Failed to create relation in graph fro id {} to new artifact", id);
258             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(relation.right().value()));
259         }
260
261         return Either.left(artifactData);
262     }
263
264     private boolean validateParentType(NodeTypeEnum type) {
265         boolean isValid = false;
266         switch (type) {
267         case Resource:
268         case InterfaceOperation:
269         case Service:
270         case ResourceInstance:
271             isValid = true;
272             break;
273         default:
274             log.debug("Not supported node type for artifact relation : {} ", type);
275         }
276         return isValid;
277     }
278
279
280     protected ArtifactDefinition convertArtifactDataToArtifactDefinition(ArtifactData artifactDefResult) {
281         log.debug("The object returned after create property is {}" ,artifactDefResult);
282
283         ArtifactDefinition propertyDefResult = new ArtifactDefinition(artifactDefResult.getArtifactDataDefinition());
284         List<HeatParameterDefinition> parameters = new ArrayList<>();
285         StorageOperationStatus heatParametersOfNode = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefResult.getUniqueId().toString(), parameters);
286         if ((heatParametersOfNode.equals(StorageOperationStatus.OK)) && !parameters.isEmpty()) {
287             propertyDefResult.setListHeatParameters(parameters);
288         }
289         return propertyDefResult;
290     }
291
292     public Either<ArtifactDefinition, StorageOperationStatus> updateArifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, boolean inTransaction) {
293         Either<ArtifactData, StorageOperationStatus> status = updateArtifactOnGraph(artifactInfo, artifactId, type, id);
294
295         if (status.isRight()) {
296             if (!inTransaction) {
297                 janusGraphGenericDao.rollback();
298             }
299             log.debug("Failed to update artifact {} of {} {}. status is {}", artifactId, type.getName(), id, status.right().value());
300             BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("Update Artifact", artifactId, String.valueOf(status.right().value()));
301             return Either.right(status.right().value());
302         } else {
303             if (!inTransaction) {
304                 janusGraphGenericDao.commit();
305             }
306             ArtifactData artifactData = status.left().value();
307
308             ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData);
309             log.debug(THE_RETURNED_ARTIFACT_DEFINTION_IS, artifactDefResult);
310             return Either.left(artifactDefResult);
311         }
312     }
313
314     public Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact, boolean inTransaction) {
315         Either<ArtifactData, StorageOperationStatus> status = removeArtifactOnGraph(id, artifactId, type, deleteMandatoryArtifact);
316
317         if (status.isRight()) {
318             if (!inTransaction) {
319                 janusGraphGenericDao.rollback();
320             }
321             log.debug("Failed to delete artifact {} of resource {}", artifactId, id);
322
323             BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("Delete Artifact", artifactId, String.valueOf(status.right().value()));
324             return Either.right(status.right().value());
325         } else {
326             if (!inTransaction) {
327                 janusGraphGenericDao.commit();
328             }
329             ArtifactData artifactData = status.left().value();
330
331             ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData);
332             log.debug(THE_RETURNED_ARTIFACT_DEFINTION_IS , artifactDefResult);
333             return Either.left(artifactDefResult);
334         }
335     }
336
337     @SuppressWarnings("null")
338     private Either<ArtifactData, StorageOperationStatus> updateArtifactOnGraph(ArtifactDefinition artifactInfo, String artifactId, NodeTypeEnum type, String id) {
339
340         Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphGenericDao.getGraph();
341         if (graph.isRight()) {
342             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(graph.right().value()));
343         }
344
345         JanusGraph tGraph = graph.left().value();
346
347         @SuppressWarnings("unchecked")
348         Iterable<JanusGraphVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId).vertices();
349         Iterator<JanusGraphVertex> iterator = verticesArtifact.iterator();
350         if (!iterator.hasNext()) {
351             log.debug("No artifact node for id = {}", artifactId);
352             return Either.right(StorageOperationStatus.NOT_FOUND);
353         }
354         JanusGraphVertex artifactV = iterator.next();
355
356         Iterator<Edge> iterEdge = artifactV.edges(Direction.IN, GraphEdgeLabels.ARTIFACT_REF.getProperty());
357
358         int edgeCount = 0;
359         Edge edgeFromTo = null;
360         while (iterEdge.hasNext()) {
361             Edge edge = iterEdge.next();
362             Vertex vertexFrom = edge.outVertex();
363             String vertexId = vertexFrom.value(UniqueIdBuilder.getKeyByNodeType(type));
364             if (id.equals(vertexId)) {
365                 edgeFromTo = edge;
366             }
367             ++edgeCount;
368         }
369
370         if (isNeedUpdateHeatTime(artifactInfo)) {
371             artifactInfo.setHeatParamsUpdateDate(System.currentTimeMillis());
372         }
373
374         ArtifactData artifactData = new ArtifactData(artifactInfo);
375         if (edgeFromTo == null) {
376             log.debug("No relation between artifact  = {} and node with id = {}", artifactId, id);
377             return Either.right(StorageOperationStatus.GENERAL_ERROR);
378         }
379
380         Either<Boolean, StorageOperationStatus> setRelevantHeatParamIdRes = null;
381         if (edgeCount > 1) {
382             // need to remove relation, create new node
383             log.debug("artifactRef have more connection. Need to clone node");
384             log.debug("remove edge {}", edgeFromTo);
385             edgeFromTo.remove();
386             // update resource id in new artifact node
387             String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel());
388             artifactInfo.setUniqueId(uniqueId);
389             // update UUID and artifact version
390             String oldChecksum = artifactV.valueOrNull(
391                 janusGraphGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_CHECKSUM.getProperty()));
392             String oldVersion = artifactV.valueOrNull(
393                 janusGraphGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_VERSION.getProperty()));
394             updateUUID(artifactInfo, oldChecksum, oldVersion);
395             log.debug("try to create new artifact ref node for id {}", uniqueId);
396             Either<ArtifactData, StorageOperationStatus> addedArtifactRes = addArtifactToGraph(artifactInfo, id, type, true);
397
398             if (addedArtifactRes.isLeft()) {
399                 // remove all relations between groups to the old artifact
400                 // add relation between the same groups to the new artifact
401                 StorageOperationStatus reassociateGroupsFromArtifact = groupOperation.dissociateAndAssociateGroupsFromArtifact(id, type, artifactId, addedArtifactRes.left().value(), true);
402                 if (reassociateGroupsFromArtifact != StorageOperationStatus.OK) {
403                     BeEcompErrorManager.getInstance().logInternalFlowError("UpdateArtifact", "Failed to reassociate groups to the new artifact", ErrorSeverity.ERROR);
404                     return Either.right(reassociateGroupsFromArtifact);
405                 }
406
407                 StorageOperationStatus reassociateGroupInstancesFromArtifact = groupInstanceOperation.dissociateAndAssociateGroupsInstanceFromArtifact(id, type, artifactId, addedArtifactRes.left().value());
408                 if (reassociateGroupInstancesFromArtifact != StorageOperationStatus.OK) {
409                     BeEcompErrorManager.getInstance().logInternalFlowError("UpdateArtifact", "Failed to reassociate group instances to the new artifact", ErrorSeverity.ERROR);
410                     return Either.right(reassociateGroupsFromArtifact);
411                 }
412
413                 // If artifact is heat env
414                 if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
415                     ArtifactData addedArtifact = addedArtifactRes.left().value();
416                     String newArtifactUniqueId = addedArtifact.getUniqueId();
417                     Either<HeatParameterValueData, StorageOperationStatus> updateResult = null;
418
419                     setRelevantHeatParamIdRes = setRelevantHeatParamId(artifactV, artifactInfo);
420                     if (setRelevantHeatParamIdRes.isRight()) {
421                         log.error("Failed to set relevant id to heat parameters for heat env artifact {}. Status is {}", artifactInfo.getUniqueId(), setRelevantHeatParamIdRes.right().value());
422                         return Either.right(setRelevantHeatParamIdRes.right().value());
423                     }
424                     for (HeatParameterDefinition heatEnvParam : artifactInfo.getListHeatParameters()) {
425                         updateResult = heatParametersOperation.updateHeatParameterValue(heatEnvParam, newArtifactUniqueId, id, artifactInfo.getArtifactLabel());
426                         if (updateResult.isRight()) {
427                             log.error("Failed to update heat parameter {}. Status is {}", heatEnvParam.getName(), updateResult.right().value());
428                             return Either.right(updateResult.right().value());
429                         }
430                     }
431
432                     Iterator<Edge> iterEdgeGeneratedFrom = artifactV.edges(Direction.OUT, GraphEdgeLabels.GENERATED_FROM.getProperty());
433
434                     if (!iterEdgeGeneratedFrom.hasNext()) {
435                         log.error("No heat artifact node for id = {}", artifactId);
436                         return Either.right(StorageOperationStatus.NOT_FOUND);
437                     }
438                     Edge edgeToHeat = iterEdgeGeneratedFrom.next();
439                     Vertex vertexIn = edgeToHeat.inVertex();
440                     String generatedFromArtifactId = vertexIn.value(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef));
441                     UniqueIdData generatedFromArtifactNode = new UniqueIdData(NodeTypeEnum.ArtifactRef, generatedFromArtifactId);
442                     Either<GraphRelation, JanusGraphOperationStatus> createRelationToGeneratedFromArtifactRes = janusGraphGenericDao
443                         .createRelation(addedArtifact, generatedFromArtifactNode, GraphEdgeLabels.GENERATED_FROM, null);
444                     if (createRelationToGeneratedFromArtifactRes.isRight()) {
445                         log.error("Failed to create relation from heat_env {} to heat {}", addedArtifact.getUniqueId(), generatedFromArtifactNode);
446                         return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createRelationToGeneratedFromArtifactRes.right().value()));
447                     }
448                 }
449             }
450             return addedArtifactRes;
451
452         } else {
453             if (edgeCount == 1) {
454                 String oldChecksum = artifactV.valueOrNull(
455                     janusGraphGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_CHECKSUM.getProperty()));
456                 String oldVersion = artifactV.valueOrNull(
457                     janusGraphGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_VERSION.getProperty()));
458                 updateUUID(artifactInfo, oldChecksum, oldVersion);
459                 // update exist
460                 Either<ArtifactData, JanusGraphOperationStatus> updatedArtifact = janusGraphGenericDao
461                     .updateNode(artifactData, ArtifactData.class);
462                 if (updatedArtifact.isRight()) {
463                     log.debug("failed to update artifact node for id {}", artifactData.getUniqueId());
464                     return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updatedArtifact.right().value()));
465                 }
466
467                 if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
468                     Either<HeatParameterValueData, StorageOperationStatus> updateResult = null;
469                     String artifactUniqueId = artifactInfo.getUniqueId();
470                     setRelevantHeatParamIdRes = setRelevantHeatParamId(artifactV, artifactInfo);
471                     if (setRelevantHeatParamIdRes.isRight()) {
472                         log.error("Failed to set relevant id to heat parameters for heat env artifact {}. Status is {}", artifactInfo.getUniqueId(), setRelevantHeatParamIdRes.right().value());
473                         return Either.right(setRelevantHeatParamIdRes.right().value());
474                     }
475                     for (HeatParameterDefinition heatEnvParam : artifactInfo.getListHeatParameters()) {
476                         updateResult = heatParametersOperation.updateHeatParameterValue(heatEnvParam, artifactUniqueId, id, artifactInfo.getArtifactLabel());
477                         if (updateResult.isRight()) {
478                             log.error("Failed to update heat parameter {}. Status is {}", heatEnvParam.getName(), updateResult.right().value());
479                             return Either.right(updateResult.right().value());
480                         }
481                     }
482                 } else {
483                     if (artifactData.getArtifactDataDefinition().getArtifactChecksum() == null) {
484                         // update heat parameters only if it is not heat env
485                         if (artifactInfo.getGeneratedFromId() == null) {
486                             StorageOperationStatus operationStatus = heatParametersOperation.updateHeatParameters(artifactInfo.getListHeatParameters());
487                             if (operationStatus != StorageOperationStatus.OK) {
488                                 return Either.right(operationStatus);
489                             }
490                         }
491                     } else {
492                         Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteParameters = heatParametersOperation.deleteAllHeatParametersAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactInfo.getUniqueId());
493                         if (deleteParameters.isRight()) {
494                             log.debug("failed to update heat parameters for artifact id {}", artifactData.getUniqueId());
495                             return Either.right(StorageOperationStatus.GENERAL_ERROR);
496                         }
497
498                         StorageOperationStatus addParameters = heatParametersOperation.addPropertiesToGraph(artifactInfo.getListHeatParameters(), artifactId, NodeTypeEnum.ArtifactRef);
499                         if (!addParameters.equals(StorageOperationStatus.OK)) {
500                             log.debug("failed to update heat parameters for artifact id {}", artifactData.getUniqueId());
501                             return Either.right(StorageOperationStatus.GENERAL_ERROR);
502                         }
503
504                     }
505                 }
506
507                 return Either.left(updatedArtifact.left().value());
508             } else {
509                 log.debug("No relevent edges for artifact = {}", artifactId);
510                 return Either.right(StorageOperationStatus.GENERAL_ERROR);
511             }
512         }
513     }
514
515     private boolean isNeedUpdateHeatTime(ArtifactDefinition artifactInfo) {
516         if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) || artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType()) || artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_VOL.getType())) {
517             return true;
518         }
519         return false;
520     }
521
522     private Either<Boolean, StorageOperationStatus> setRelevantHeatParamId(JanusGraphVertex artifactV, ArtifactDefinition artifactInfo) {
523
524         Map<String, String> heatParametersHM = new HashMap<>();
525
526         Iterator<Edge> iterHeat = artifactV.edges(Direction.OUT, GraphEdgeLabels.GENERATED_FROM.getProperty());
527         if (!iterHeat.hasNext()) {
528             log.debug("No edges with label GENERATED_FROM for the node {}" , artifactInfo.getUniqueId());
529             return Either.right(StorageOperationStatus.NOT_FOUND);
530         }
531         Edge heat = iterHeat.next();
532         Vertex heatVertex = heat.inVertex();
533         String heatUniqueId = (String) heatVertex.value(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef));
534
535         Either<List<ImmutablePair<HeatParameterData, GraphEdge>>, JanusGraphOperationStatus> getHeatParametersRes = janusGraphGenericDao
536             .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), heatUniqueId, GraphEdgeLabels.HEAT_PARAMETER,
537                 NodeTypeEnum.HeatParameter, HeatParameterData.class);
538         if (getHeatParametersRes.isRight()) {
539             log.debug("No heat parameters for heat artifact {}", heatUniqueId);
540             return Either.right(StorageOperationStatus.NOT_FOUND);
541         }
542         List<ImmutablePair<HeatParameterData, GraphEdge>> heatParameters = getHeatParametersRes.left().value();
543         if (heatParameters == null) {
544             log.debug("No heat parameters for heat artifact {}", heatUniqueId);
545             return Either.right(StorageOperationStatus.NOT_FOUND);
546         }
547         for (ImmutablePair<HeatParameterData, GraphEdge> heatParamEdge : heatParameters) {
548             HeatParameterData heatParam = heatParamEdge.getLeft();
549             heatParametersHM.put(heatParam.getName(), (String) heatParam.getUniqueId());
550         }
551         String curName = null;
552         for (HeatParameterDefinition heatEnvParam : artifactInfo.getListHeatParameters()) {
553             curName = heatEnvParam.getName();
554             if (heatParametersHM.containsKey(curName)) {
555                 heatEnvParam.setUniqueId(heatParametersHM.get(curName));
556             }
557         }
558         return Either.left(true);
559     }
560
561     private Either<ArtifactData, StorageOperationStatus> removeArtifactOnGraph(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact) {
562         Either<JanusGraph, StorageOperationStatus> graph = janusGraphGenericDao.getGraph()
563                 .right()
564                 .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
565         if (graph.isRight()) {
566             return Either.right(graph.right().value());
567         }
568
569         JanusGraph tGraph = graph.left().value();
570         Either<ArtifactData, StorageOperationStatus> artifactData = janusGraphGenericDao
571             .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId, ArtifactData.class)
572                 .right()
573                 .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
574         if (artifactData.isRight()) {
575             log.debug("Failed to retrieve  artifact for id = {}", artifactId);
576             return Either.right(artifactData.right().value());
577         }
578         ArtifactDataDefinition artifactDefinition = artifactData.left().value().getArtifactDataDefinition();
579         boolean isMandatory = false;
580         if ((artifactDefinition.getMandatory() || artifactDefinition.getServiceApi()) && !deleteMandatoryArtifact) {
581             isMandatory = true;
582         }
583
584         @SuppressWarnings("unchecked")
585         Iterable<JanusGraphVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId).vertices();
586         Iterator<JanusGraphVertex> iterator = verticesArtifact.iterator();
587         if (!iterator.hasNext()) {
588             log.debug("No artifact node for id = {}", artifactId);
589             return Either.right(StorageOperationStatus.NOT_FOUND);
590         }
591         Vertex artifactV = iterator.next();
592         Iterator<Edge> iterEdge = artifactV.edges(Direction.IN, GraphEdgeLabels.ARTIFACT_REF.getProperty());
593         int edgeCount = 0;
594         Edge edgeFromTo = null;
595         while (iterEdge.hasNext()) {
596             Edge edge = iterEdge.next();
597             Vertex vertexFrom = edge.outVertex();
598             String vertexId = vertexFrom.value(UniqueIdBuilder.getKeyByNodeType(type));
599             if (id.equals(vertexId)) {
600                 edgeFromTo = edge;
601             }
602             ++edgeCount;
603         }
604         if (edgeFromTo == null) {
605             log.debug("No relation between artifact  = {} and node with id = {}", artifactId, id);
606             return Either.right(StorageOperationStatus.GENERAL_ERROR);
607         }
608
609         // need to remove relation from resource/interface
610
611         log.debug("remove edge {}", edgeFromTo);
612         if (!isMandatory || (isMandatory && edgeCount > 1)) {
613             edgeFromTo.remove();
614         }
615
616         // delete edges from all groups under the component id which related to
617         // this artifact.
618         // Also in case it is a mandatory artifact.
619         Either<List<GraphRelation>, StorageOperationStatus> dissociateAllGroups = groupOperation.dissociateAllGroupsFromArtifactOnGraph(id, type, artifactId);
620         if (dissociateAllGroups.isRight()) {
621             StorageOperationStatus status = dissociateAllGroups.right().value();
622             if (status != StorageOperationStatus.NOT_FOUND && status != StorageOperationStatus.OK) {
623                 return Either.right(status);
624             }
625         }
626
627         if (edgeCount == 1) {
628             // remove artifactRef node
629             log.debug("Remove artifactRef node from graph");
630             Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteStatus = heatParametersOperation.deleteAllHeatParametersAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactId);
631             if (deleteStatus.isRight()) {
632                 log.error("failed to delete heat parameters of artifact {}", artifactId);
633                 return Either.right(StorageOperationStatus.GENERAL_ERROR);
634             }
635
636             StorageOperationStatus deleteValuesStatus = heatParametersOperation.deleteAllHeatValuesAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactId);
637             if (!deleteValuesStatus.equals(StorageOperationStatus.OK)) {
638                 log.error("failed to delete heat values of artifact {}", artifactId);
639                 return Either.right(StorageOperationStatus.GENERAL_ERROR);
640             }
641             if (!isMandatory) {
642                 artifactV.remove();
643             }
644         } else {
645             log.debug("artifactRef have more connection. ArtifactRef node will not be removed ");
646         }
647
648         return Either.left(artifactData.left().value());
649
650     }
651
652     /**
653      *
654      * @param parentId
655      * @param parentType
656      * @param inTransaction
657      * @return
658      */
659     public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction) {
660         Either<Map<String, ArtifactDefinition>, StorageOperationStatus> result = null;
661         try {
662             Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphGenericDao.getGraph();
663             if (graph.isRight()) {
664                 log.debug("Failed to work with graph {}", graph.right().value());
665                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(graph.right().value()));
666             }
667             JanusGraph tGraph = graph.left().value();
668             @SuppressWarnings("unchecked")
669             Iterable<JanusGraphVertex> vertices = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(parentType), parentId).vertices();
670             if (vertices == null) {
671                 log.debug("No nodes for type {}  for id = {}", parentType, parentId);
672                 result = Either.right(StorageOperationStatus.NOT_FOUND);
673                 return result;
674             }
675             Iterator<JanusGraphVertex> iterator = vertices.iterator();
676
677             Map<String, ArtifactDefinition> artifactMap = new HashMap<>();
678             while (iterator.hasNext()) {
679                 Vertex vertex = iterator.next();
680                 Iterator<Edge> iteratorEdge = vertex.edges(Direction.OUT, GraphEdgeLabels.ARTIFACT_REF.getProperty());
681
682                 if (iteratorEdge != null) {
683
684                     while (iteratorEdge.hasNext()) {
685                         Edge edge = iteratorEdge.next();
686
687                         Vertex artifactV = edge.inVertex();
688
689                         Map<String, Object> properties = this.janusGraphGenericDao.getProperties(artifactV);
690                         ArtifactData artifact = GraphElementFactory.createElement(NodeTypeEnum.ArtifactRef.getName(), GraphElementTypeEnum.Node, properties, ArtifactData.class);
691                         if (artifact != null) {
692
693                             ArtifactDefinition artifactDefinition = new ArtifactDefinition(artifact.getArtifactDataDefinition());
694                             Iterator<Edge> edgesGeneratedFrom = artifactV.edges(Direction.OUT, GraphEdgeLabels.GENERATED_FROM.getProperty());
695                             if (edgesGeneratedFrom != null && edgesGeneratedFrom.hasNext()) {
696                                 JanusGraphVertex inVertex = (JanusGraphVertex) edgesGeneratedFrom.next().inVertex();
697                                 String artifactIdGeneratedFrom = (String) janusGraphGenericDao
698                                     .getProperty(inVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty());
699                                 artifactDefinition.setGeneratedFromId(artifactIdGeneratedFrom);
700                             }
701                             List<HeatParameterDefinition> heatParams = new ArrayList<>();
702                             StorageOperationStatus heatParametersStatus = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefinition.getUniqueId(), heatParams);
703                             if (!heatParametersStatus.equals(StorageOperationStatus.OK)) {
704                                 log.debug("failed to get heat parameters for node {}  {}", parentType.getName(), parentId);
705                                 return Either.right(heatParametersStatus);
706                             }
707                             if (!heatParams.isEmpty()) {
708                                 artifactDefinition.setListHeatParameters(heatParams);
709                             }
710                             artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
711                             log.debug("Artifact was added to list {}", artifact.getUniqueId());
712                         }
713                     }
714                 }
715             }
716             result = Either.left(artifactMap);
717             return result;
718         } finally {
719             if (!inTransaction) {
720                 if (result == null || result.isRight()) {
721                     this.janusGraphGenericDao.rollback();
722                 } else {
723                     this.janusGraphGenericDao.commit();
724                 }
725
726             }
727         }
728
729     }
730
731     private void updateUUID(ArtifactDataDefinition artifactData, String oldChecksum, String oldVesrion) {
732         if (oldVesrion == null || oldVesrion.isEmpty())
733             oldVesrion = "0";
734
735         String currentChecksum = artifactData.getArtifactChecksum();
736         if (oldChecksum == null || oldChecksum.isEmpty()) {
737             if (currentChecksum != null) {
738                 generateUUID(artifactData, oldVesrion);
739             }
740         } else if ((currentChecksum != null && !currentChecksum.isEmpty()) && !oldChecksum.equals(currentChecksum)) {
741             generateUUID(artifactData, oldVesrion);
742         }
743
744     }
745
746     private void generateUUID(ArtifactDataDefinition artifactData, String oldVesrion) {
747
748         UUID uuid = UUID.randomUUID();
749         artifactData.setArtifactUUID(uuid.toString());
750         MDC.put(ILogConfiguration.MDC_SERVICE_INSTANCE_ID, uuid.toString());
751         updateVersionAndDate(artifactData, oldVesrion);
752     }
753
754     private void updateVersionAndDate(ArtifactDataDefinition artifactData, String oldVesrion) {
755         long time = System.currentTimeMillis();
756         artifactData.setPayloadUpdateDate(time);
757         int newVersion = new Integer(oldVesrion).intValue();
758         newVersion++;
759         artifactData.setArtifactVersion(String.valueOf(newVersion));
760     }
761
762 }