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