95e65e1e82e8fe30ad8f43b163848315c9711562
[sdc.git] /
1 package org.openecomp.sdc.be.model.jsontitan.operations;
2
3 import java.lang.reflect.Type;
4 import java.util.ArrayList;
5 import java.util.HashMap;
6 import java.util.HashSet;
7 import java.util.Iterator;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Map.Entry;
11 import java.util.Set;
12
13 import org.apache.tinkerpop.gremlin.structure.Direction;
14 import org.apache.tinkerpop.gremlin.structure.Edge;
15 import org.apache.tinkerpop.gremlin.structure.Vertex;
16 import org.openecomp.sdc.be.config.ConfigurationManager;
17 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
18 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
19 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
20 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
21 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
22 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
23 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
24 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
25 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
26 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
27 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
28 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
29 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
30 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
31 import org.openecomp.sdc.be.model.ComponentParametersView;
32 import org.openecomp.sdc.be.model.LifecycleStateEnum;
33 import org.openecomp.sdc.be.model.category.CategoryDefinition;
34 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
35 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
36 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
37 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
38 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
39 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
40 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
41 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
42 import org.openecomp.sdc.be.resources.data.UserData;
43 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
44 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
45 import org.openecomp.sdc.common.util.ValidationUtils;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48 import org.springframework.beans.factory.annotation.Autowired;
49
50 import com.google.gson.Gson;
51 import com.google.gson.reflect.TypeToken;
52
53 import fj.data.Either;
54
55 public abstract class ToscaElementOperation extends BaseOperation {
56         private static Logger log = LoggerFactory.getLogger(ToscaElementOperation.class.getName());
57
58         private static final Gson gson = new Gson();
59
60         protected Gson getGson() {
61                 return gson;
62         }
63
64         @Autowired
65         protected CategoryOperation categoryOperation;
66
67         protected Either<GraphVertex, StorageOperationStatus> getComponentByLabelAndId(String uniqueId, ToscaElementTypeEnum nodeType, JsonParseFlagEnum parseFlag) {
68
69                 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<GraphPropertyEnum, Object>();
70                 propertiesToMatch.put(GraphPropertyEnum.UNIQUE_ID, uniqueId);
71
72                 VertexTypeEnum vertexType = ToscaElementTypeEnum.getVertexTypeByToscaType(nodeType);
73                 Either<List<GraphVertex>, TitanOperationStatus> getResponse = titanDao.getByCriteria(vertexType, propertiesToMatch, parseFlag);
74                 if (getResponse.isRight()) {
75                         log.debug("Couldn't fetch component with type {} and unique id {}, error: {}", vertexType, uniqueId, getResponse.right().value());
76                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getResponse.right().value()));
77
78                 }
79                 List<GraphVertex> componentList = getResponse.left().value();
80                 if (componentList.isEmpty()) {
81                         log.debug("Component with type {} and unique id {} was not found", vertexType, uniqueId);
82                         return Either.right(StorageOperationStatus.NOT_FOUND);
83                 }
84                 GraphVertex vertexG = componentList.get(0);
85                 return Either.left(vertexG);
86         }
87
88         public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId) {
89                 return getToscaElement(uniqueId, new ComponentParametersView());
90         }
91
92         public Either<GraphVertex, StorageOperationStatus> markComponentToDelete(GraphVertex componentToDelete) {
93                 Either<GraphVertex, StorageOperationStatus> result = null;
94
95                 Boolean isDeleted = (Boolean) componentToDelete.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
96                 if (isDeleted != null && isDeleted && !(Boolean) componentToDelete.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION)) {
97                         // component already marked for delete
98                         result = Either.left(componentToDelete);
99                         return result;
100                 } else {
101
102                         componentToDelete.addMetadataProperty(GraphPropertyEnum.IS_DELETED, Boolean.TRUE);
103                         componentToDelete.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
104
105                         Either<GraphVertex, TitanOperationStatus> updateNode = titanDao.updateVertex(componentToDelete);
106
107                         StorageOperationStatus updateComponent;
108                         if (updateNode.isRight()) {
109                                 log.debug("Failed to update component {}. status is {}", componentToDelete.getUniqueId(), updateNode.right().value());
110                                 updateComponent = DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value());
111                                 result = Either.right(updateComponent);
112                                 return result;
113                         }
114
115                         result = Either.left(componentToDelete);
116                         return result;
117                 }
118         }
119
120         /**
121          * Performs a shadow clone of previousToscaElement
122          * 
123          * @param previousToscaElement
124          * @param nextToscaElement
125          * @param user
126          * @return
127          */
128         public Either<GraphVertex, StorageOperationStatus> cloneToscaElement(GraphVertex previousToscaElement, GraphVertex nextToscaElement, GraphVertex user) {
129
130                 Either<GraphVertex, StorageOperationStatus> result = null;
131                 GraphVertex createdToscaElementVertex = null;
132                 TitanOperationStatus status;
133                 
134                 Either<GraphVertex, TitanOperationStatus> createNextVersionRes = titanDao.createVertex(nextToscaElement);
135                 if (createNextVersionRes.isRight()) {
136                         status = createNextVersionRes.right().value();
137                         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create tosca element vertex {} with version {} on graph. Status is {}. ", previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME),
138                                         previousToscaElement.getMetadataProperty(GraphPropertyEnum.VERSION), status);
139                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
140                 }
141                 if (result == null) {
142                         createdToscaElementVertex = createNextVersionRes.left().value();
143                         Map<EdgePropertyEnum, Object> properties = new HashMap<EdgePropertyEnum, Object>();
144                         properties.put(EdgePropertyEnum.STATE, createdToscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE));
145                         status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.STATE, properties);
146                         if (status != TitanOperationStatus.OK) {
147                                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from user vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.STATE, user.getUniqueId(),
148                                                 previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
149                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
150                         }
151                 }
152                 if (result == null) {
153                         status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
154                         if (status != TitanOperationStatus.OK) {
155                                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from user vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.LAST_MODIFIER, user.getUniqueId(),
156                                                 nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
157                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
158                         }
159                 }
160                 if (result == null) {
161                         status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.CREATOR, new HashMap<>());
162                         if (status != TitanOperationStatus.OK) {
163                                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from user vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.CREATOR, user.getUniqueId(),
164                                                 nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
165                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
166                         }
167                 }
168                 if (result == null) {
169                         Iterator<Edge> edgesToCopyIter = previousToscaElement.getVertex().edges(Direction.OUT);
170                         while (edgesToCopyIter.hasNext()) {
171                                 Edge currEdge = edgesToCopyIter.next();
172                                 Vertex currVertex = currEdge.inVertex();
173                                 // if(EdgeLabelEnum.getEdgeLabelEnum(currEdge.label()).equals(EdgeLabelEnum.VERSION)){
174                                 // continue;
175                                 // }
176                                 status = titanDao.createEdge(createdToscaElementVertex.getVertex(), currVertex, EdgeLabelEnum.getEdgeLabelEnum(currEdge.label()), currEdge);
177                                 if (status != TitanOperationStatus.OK) {
178                                         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from tosca element vertex {} to vertex with label {} on graph. Status is {}. ", currEdge.label(), createdToscaElementVertex.getUniqueId(),
179                                                         currVertex.property(GraphPropertyEnum.LABEL.getProperty()), status);
180                                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
181                                         break;
182                                 }
183                         }
184                 }
185                 
186                 if (result == null) {
187                         result = Either.left(createdToscaElementVertex);
188                 } else {
189                         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element {} with the name {}. ", previousToscaElement.getUniqueId(), previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME));
190                 }
191                 return result;
192         }
193
194         protected TitanOperationStatus setLastModifierFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
195                 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(componentV, EdgeLabelEnum.LAST_MODIFIER, JsonParseFlagEnum.NoParse);
196                 if (parentVertex.isRight()) {
197                         log.debug("Failed to fetch last modifier for tosca element with id {} error {}", componentV.getUniqueId(), parentVertex.right().value());
198                         return parentVertex.right().value();
199                 }
200                 GraphVertex userV = parentVertex.left().value();
201                 String userId = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
202                 toscaElement.setLastUpdaterUserId(userId);
203                 toscaElement.setLastUpdaterFullName(buildFullName(userV));
204                 return TitanOperationStatus.OK;
205         }
206         public String buildFullName(GraphVertex userV) {
207
208                 String fullName = (String) userV.getMetadataProperty(GraphPropertyEnum.FIRST_NAME);
209                 if (fullName == null) {
210                         fullName = "";
211                 } else {
212                         fullName = fullName + " ";
213                 }
214                 String lastName = (String) userV.getMetadataProperty(GraphPropertyEnum.LAST_NAME);
215                 if (lastName != null) {
216                         fullName += lastName;
217                 }
218                 return fullName;
219         }
220         protected TitanOperationStatus setCreatorFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
221                 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(componentV, EdgeLabelEnum.CREATOR, JsonParseFlagEnum.NoParse);
222                 if (parentVertex.isRight()) {
223                         log.debug("Failed to fetch creator for tosca element with id {} error {}", componentV.getUniqueId(), parentVertex.right().value());
224                         return parentVertex.right().value();
225                 }
226                 GraphVertex userV = parentVertex.left().value();
227                 String creatorUserId = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
228                 toscaElement.setCreatorUserId(creatorUserId);
229                 toscaElement.setCreatorFullName(buildFullName(userV));
230                 
231                 return TitanOperationStatus.OK;
232         }
233
234         protected <T extends ToscaElement> T getResourceMetaDataFromResource(T toscaElement) {
235                 if (toscaElement.getNormalizedName() == null || toscaElement.getNormalizedName().isEmpty()) {
236                         toscaElement.setNormalizedName(ValidationUtils.normaliseComponentName(toscaElement.getName()));
237                 }
238                 if (toscaElement.getSystemName() == null || toscaElement.getSystemName().isEmpty()) {
239                         toscaElement.setSystemName(ValidationUtils.convertToSystemName(toscaElement.getName()));
240                 }
241
242                 LifecycleStateEnum lifecycleStateEnum = toscaElement.getLifecycleState();
243                 if (lifecycleStateEnum == null) {
244                         toscaElement.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
245                 }
246                 long currentDate = System.currentTimeMillis();
247                 if (toscaElement.getCreationDate() == null) {
248                         toscaElement.setCreationDate(currentDate);
249                 }
250                 toscaElement.setLastUpdateDate(currentDate);
251
252                 return toscaElement;
253         }
254
255         protected void fillCommonMetadata(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
256                 if (toscaElement.isHighestVersion() == null) {
257                         toscaElement.setHighestVersion(true);
258                 }
259                 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_DELETED, toscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED));
260                 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, toscaElement.getMetadataValueOrDefault(JsonPresentationFields.HIGHEST_VERSION, Boolean.TRUE));
261                 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.STATE, toscaElement.getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
262                 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.RESOURCE_TYPE, toscaElement.getMetadataValue(JsonPresentationFields.RESOURCE_TYPE));
263                 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.VERSION, toscaElement.getMetadataValue(JsonPresentationFields.VERSION));
264                 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME, toscaElement.getMetadataValue(JsonPresentationFields.NORMALIZED_NAME));
265                 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, toscaElement.getMetadataValue(JsonPresentationFields.UNIQUE_ID));
266                 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
267                 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.UUID, toscaElement.getMetadataValue(JsonPresentationFields.UUID));
268                 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_ABSTRACT, toscaElement.getMetadataValue(JsonPresentationFields.IS_ABSTRACT));
269                 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.INVARIANT_UUID, toscaElement.getMetadataValue(JsonPresentationFields.INVARIANT_UUID));
270                 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.NAME, toscaElement.getMetadataValue(JsonPresentationFields.NAME));
271                 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.SYSTEM_NAME, toscaElement.getMetadataValue(JsonPresentationFields.SYSTEM_NAME));
272                 toscaElement.getMetadata().entrySet().stream().filter(e -> e.getValue() != null).forEach(e -> nodeTypeVertex.setJsonMetadataField(JsonPresentationFields.getByPresentation(e.getKey()), e.getValue()));
273
274                 nodeTypeVertex.setUniqueId(toscaElement.getUniqueId());
275                 nodeTypeVertex.setType(toscaElement.getComponentType());
276
277         }
278
279         protected StorageOperationStatus assosiateToUsers(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
280                 // handle user
281                 String userId = toscaElement.getCreatorUserId();
282
283                 Either<GraphVertex, TitanOperationStatus> findUser = findUserVertex(userId);
284
285                 if (findUser.isRight()) {
286                         TitanOperationStatus status = findUser.right().value();
287                         log.error("Cannot find user {} in the graph. status is {}", userId, status);
288                         return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
289
290                 }
291                 GraphVertex creatorVertex = findUser.left().value();
292                 GraphVertex updaterVertex = creatorVertex;
293                 String updaterId = toscaElement.getLastUpdaterUserId();
294                 if (updaterId != null && !updaterId.equals(userId)) {
295                         findUser = findUserVertex(updaterId);
296                         if (findUser.isRight()) {
297                                 TitanOperationStatus status = findUser.right().value();
298                                 log.error("Cannot find user {} in the graph. status is {}", userId, status);
299                                 return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
300                         } else {
301                                 updaterVertex = findUser.left().value();
302                         }
303                 }
304                 Map<EdgePropertyEnum, Object> props = new HashMap<EdgePropertyEnum, Object>();
305                 props.put(EdgePropertyEnum.STATE, (String) toscaElement.getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
306
307                 TitanOperationStatus result = titanDao.createEdge(updaterVertex, nodeTypeVertex, EdgeLabelEnum.STATE, props);
308                 log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.STATE);
309                 if (TitanOperationStatus.OK != result) {
310                         return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
311                 }
312                 result = titanDao.createEdge(updaterVertex, nodeTypeVertex, EdgeLabelEnum.LAST_MODIFIER, null);
313                 log.debug("After associating user {}  to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
314                 if (!result.equals(TitanOperationStatus.OK)) {
315                         log.error("Failed to associate user {}  to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
316                         return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
317                 }
318
319                 toscaElement.setLastUpdaterUserId(toscaElement.getCreatorUserId());
320                 toscaElement.setLastUpdaterFullName(toscaElement.getCreatorFullName());
321                 
322                 result = titanDao.createEdge(creatorVertex, nodeTypeVertex, EdgeLabelEnum.CREATOR, null);
323                 log.debug("After associating user {} to resource {}. Edge type is {} ", creatorVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.CREATOR);
324                 if (!result.equals(TitanOperationStatus.OK)) {
325                         log.error("Failed to associate user {} to resource {}. Edge type is {} ", creatorVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.CREATOR);
326                         return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
327                 }
328                 return StorageOperationStatus.OK;
329         }
330
331         protected StorageOperationStatus assosiateResourceMetadataToCategory(GraphVertex nodeTypeVertex, ToscaElement nodeType) {
332                 String subcategoryName = nodeType.getCategories().get(0).getSubcategories().get(0).getName();
333                 String categoryName = nodeType.getCategories().get(0).getName();
334                 Either<GraphVertex, StorageOperationStatus> getCategoryVertex = getResourceCategoryVertex(nodeType.getUniqueId(), subcategoryName, categoryName);
335
336                 if (getCategoryVertex.isRight()) {
337                         return getCategoryVertex.right().value();
338                 }
339
340                 GraphVertex subCategoryV = getCategoryVertex.left().value();
341
342                 TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, subCategoryV, EdgeLabelEnum.CATEGORY, new HashMap<>());
343                 if (createEdge != TitanOperationStatus.OK) {
344                         log.trace("Failed to associate resource {} to category {} with id {}", nodeType.getUniqueId(), subcategoryName, subCategoryV.getUniqueId());
345                         return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
346                 }
347                 return StorageOperationStatus.OK;
348         }
349
350         protected Either<GraphVertex, StorageOperationStatus> getResourceCategoryVertex(String elementId, String subcategoryName, String categoryName) {
351                 Either<GraphVertex, StorageOperationStatus> category = categoryOperation.getCategory(categoryName, VertexTypeEnum.RESOURCE_CATEGORY);
352                 if (category.isRight()) {
353                         log.trace("Failed to fetch category {} for resource {} error {}", categoryName, elementId, category.right().value());
354                         return Either.right(category.right().value());
355                 }
356                 GraphVertex categoryV = category.left().value();
357
358                 if (subcategoryName != null) {
359                         Either<GraphVertex, StorageOperationStatus> subCategory = categoryOperation.getSubCategoryForCategory(categoryV, subcategoryName);
360                         if (subCategory.isRight()) {
361                                 log.trace("Failed to fetch subcategory {} of category for resource {} error {}", subcategoryName, categoryName, elementId, subCategory.right().value());
362                                 return Either.right(subCategory.right().value());
363                         }
364
365                         GraphVertex subCategoryV = subCategory.left().value();
366                         return Either.left(subCategoryV);
367                 }
368                 return Either.left(categoryV);
369         }
370
371         private StorageOperationStatus associateArtifactsToResource(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
372                 Map<String, ArtifactDataDefinition> artifacts = toscaElement.getArtifacts();
373                 Either<GraphVertex, StorageOperationStatus> status;
374                 if (artifacts != null) {
375                         artifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
376                                 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
377                                 a.setUniqueId(uniqueId);
378                         });
379                         status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ARTIFACTS, EdgeLabelEnum.ARTIFACTS, artifacts);
380                         if (status.isRight()) {
381                                 return status.right().value();
382                         }
383                 }
384                 Map<String, ArtifactDataDefinition> toscaArtifacts = toscaElement.getToscaArtifacts();
385                 if (toscaArtifacts != null) {
386                         toscaArtifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
387                                 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
388                                 a.setUniqueId(uniqueId);
389                         });
390                         status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.TOSCA_ARTIFACTS, EdgeLabelEnum.TOSCA_ARTIFACTS, toscaArtifacts);
391                         if (status.isRight()) {
392                                 return status.right().value();
393                         }
394                 }
395                 Map<String, ArtifactDataDefinition> deploymentArtifacts = toscaElement.getDeploymentArtifacts();
396                 if (deploymentArtifacts != null) {
397                         deploymentArtifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
398                                 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
399                                 a.setUniqueId(uniqueId);
400                         });
401                         status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.DEPLOYMENT_ARTIFACTS, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS, deploymentArtifacts);
402                         if (status.isRight()) {
403                                 return status.right().value();
404                         }
405                 }
406                 return StorageOperationStatus.OK;
407         }
408
409         protected TitanOperationStatus disassociateAndDeleteCommonElements(GraphVertex toscaElementVertex) {
410                 TitanOperationStatus status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ARTIFACTS);
411                 if (status != TitanOperationStatus.OK) {
412                         log.debug("Failed to disaccociate artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
413                         return status;
414                 }
415                 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.TOSCA_ARTIFACTS);
416                 if (status != TitanOperationStatus.OK) {
417                         log.debug("Failed to disaccociate tosca artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
418                         return status;
419                 }
420                 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
421                 if (status != TitanOperationStatus.OK) {
422                         log.debug("Failed to deployment artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
423                         return status;
424                 }
425                 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.PROPERTIES);
426                 if (status != TitanOperationStatus.OK) {
427                         log.debug("Failed to disaccociate properties for {} error {}", toscaElementVertex.getUniqueId(), status);
428                         return status;
429                 }
430                 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
431                 if (status != TitanOperationStatus.OK) {
432                         log.debug("Failed to disaccociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
433                         return status;
434                 }
435                 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ADDITIONAL_INFORMATION);
436                 if (status != TitanOperationStatus.OK) {
437                         log.debug("Failed to disaccociate additional information for {} error {}", toscaElementVertex.getUniqueId(), status);
438                         return status;
439                 }
440                 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
441                 if (status != TitanOperationStatus.OK) {
442                         log.debug("Failed to disaccociate capabilities for {} error {}", toscaElementVertex.getUniqueId(), status);
443                         return status;
444                 }
445                 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
446                 if (status != TitanOperationStatus.OK) {
447                         log.debug("Failed to disaccociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
448                         return status;
449                 }
450                 return TitanOperationStatus.OK;
451         }
452
453         protected StorageOperationStatus assosiateCommonForToscaElement(GraphVertex nodeTypeVertex, ToscaElement toscaElement, List<GraphVertex> derivedResources) {
454
455                 StorageOperationStatus associateUsers = assosiateToUsers(nodeTypeVertex, toscaElement);
456                 if (associateUsers != StorageOperationStatus.OK) {
457                         return associateUsers;
458                 }
459                 StorageOperationStatus associateArtifacts = associateArtifactsToResource(nodeTypeVertex, toscaElement);
460                 if (associateArtifacts != StorageOperationStatus.OK) {
461                         return associateArtifacts;
462                 }
463                 StorageOperationStatus associateProperties = associatePropertiesToResource(nodeTypeVertex, toscaElement, derivedResources);
464                 if (associateProperties != StorageOperationStatus.OK) {
465                         return associateProperties;
466                 }
467                 StorageOperationStatus associateAdditionaInfo = associateAdditionalInfoToResource(nodeTypeVertex, toscaElement);
468                 if (associateAdditionaInfo != StorageOperationStatus.OK) {
469                         return associateAdditionaInfo;
470                 }
471
472                 return StorageOperationStatus.OK;
473         }
474
475         private StorageOperationStatus associatePropertiesToResource(GraphVertex nodeTypeVertex, ToscaElement nodeType, List<GraphVertex> derivedResources) {
476                 // Note : currently only one derived supported!!!!
477                 Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, PropertyDataDefinition.class, EdgeLabelEnum.PROPERTIES);
478                 if (dataFromDerived.isRight()) {
479                         return dataFromDerived.right().value();
480                 }
481                 Map<String, PropertyDataDefinition> propertiesAll = dataFromDerived.left().value();
482
483                 Map<String, PropertyDataDefinition> properties = nodeType.getProperties();
484
485                 if (properties != null) {
486                         properties.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
487                                 String uid = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId(), p.getName());
488                                 p.setUniqueId(uid);
489                         });
490
491                         Either<Map<String, PropertyDataDefinition>, String> eitherMerged = PropertyDataDefinition.mergeProperties(propertiesAll, properties, false);
492                         if (eitherMerged.isRight()) {
493                                 // TODO re-factor error handling - moving BL to operation resulted in loss of info about the invalid property
494                                 log.debug("property {} cannot be overriden", eitherMerged.right().value());
495                                 return StorageOperationStatus.INVALID_PROPERTY;
496                         }
497
498                 }
499                 if (!propertiesAll.isEmpty()) {
500                         Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.PROPERTIES, EdgeLabelEnum.PROPERTIES, propertiesAll);
501                         if (assosiateElementToData.isRight()) {
502                                 return assosiateElementToData.right().value();
503                         }
504                 }
505                 return StorageOperationStatus.OK;
506         }
507
508         private StorageOperationStatus associateAdditionalInfoToResource(GraphVertex nodeTypeVertex, ToscaElement nodeType) {
509                 Map<String, AdditionalInfoParameterDataDefinition> additionalInformation = nodeType.getAdditionalInformation();
510                 if (additionalInformation != null) {
511                         Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, additionalInformation);
512                         if (assosiateElementToData.isRight()) {
513                                 return assosiateElementToData.right().value();
514                         }
515                 }
516                 return StorageOperationStatus.OK;
517         }
518
519         protected <T extends ToscaDataDefinition> Either<Map<String, T>, StorageOperationStatus> getDataFromDerived(List<GraphVertex> derivedResources, Class<T> clazz, EdgeLabelEnum edge) {
520                 Map<String, T> propertiesAll = new HashMap<>();
521
522                 if (derivedResources != null && !derivedResources.isEmpty()) {
523                         for (GraphVertex derived : derivedResources) {
524                                 Either<List<GraphVertex>, TitanOperationStatus> derivedProperties = titanDao.getChildrenVertecies(derived, edge, JsonParseFlagEnum.ParseJson);
525                                 if (derivedProperties.isRight()) {
526                                         if (derivedProperties.right().value() != TitanOperationStatus.NOT_FOUND) {
527                                                 log.debug("Failed to get properties for derived from {} error {}", derived.getUniqueId(), derivedProperties.right().value());
528                                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(derivedProperties.right().value()));
529                                         } else {
530                                                 continue;
531                                         }
532                                 }
533                                 List<GraphVertex> propList = derivedProperties.left().value();
534                                 for (GraphVertex propV : propList) {
535                                         Map<String, T> propertiesFromDerived = (Map<String, T>) propV.getJson();
536                                         if (propertiesFromDerived != null) {
537                                                 propertiesFromDerived.entrySet().forEach(x -> x.getValue().setOwnerIdIfEmpty(derived.getUniqueId()));
538                                                 propertiesAll.putAll(propertiesFromDerived);
539                                         }
540                                 }
541                         }
542                 }
543                 return Either.left(propertiesAll);
544         }
545
546         protected TitanOperationStatus setArtifactsFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
547                 Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ARTIFACTS);
548                 if (result.isLeft()) {
549                         toscaElement.setArtifacts(result.left().value());
550                 } else {
551                         if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
552                                 return result.right().value();
553                         }
554                 }
555                 result = getDataFromGraph(componentV, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
556                 if (result.isLeft()) {
557                         toscaElement.setDeploymentArtifacts(result.left().value());
558                 } else {
559                         if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
560                                 return result.right().value();
561                         }
562                 }
563                 result = getDataFromGraph(componentV, EdgeLabelEnum.TOSCA_ARTIFACTS);
564                 if (result.isLeft()) {
565                         toscaElement.setToscaArtifacts(result.left().value());
566                 } else {
567                         if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
568                                 return result.right().value();
569                         }
570                 }
571                 return TitanOperationStatus.OK;
572         }
573
574         protected TitanOperationStatus setAllVersions(GraphVertex componentV, ToscaElement toscaElement) {
575                 Map<String, String> allVersion = new HashMap<>();
576
577                 allVersion.put((String) componentV.getMetadataProperty(GraphPropertyEnum.VERSION), componentV.getUniqueId());
578                 Either<GraphVertex, TitanOperationStatus> childResourceRes = titanDao.getChildVertex(componentV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
579                 while (childResourceRes.isLeft()) {
580                         GraphVertex child = childResourceRes.left().value();
581                         allVersion.put((String) child.getMetadataProperty(GraphPropertyEnum.VERSION), child.getUniqueId());
582                         childResourceRes = titanDao.getChildVertex(child, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
583                 }
584                 TitanOperationStatus operationStatus = childResourceRes.right().value();
585
586                 if (operationStatus != TitanOperationStatus.NOT_FOUND) {
587                         return operationStatus;
588                 } else {
589                         Either<GraphVertex, TitanOperationStatus> parentResourceRes = titanDao.getParentVertex(componentV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
590                         while (parentResourceRes.isLeft()) {
591                                 GraphVertex parent = parentResourceRes.left().value();
592                                 allVersion.put((String) parent.getMetadataProperty(GraphPropertyEnum.VERSION), parent.getUniqueId());
593                                 parentResourceRes = titanDao.getParentVertex(parent, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
594                         }
595                         operationStatus = parentResourceRes.right().value();
596                         if (operationStatus != TitanOperationStatus.NOT_FOUND) {
597                                 return operationStatus;
598                         } else {
599                                 toscaElement.setAllVersions(allVersion);
600                                 return TitanOperationStatus.OK;
601                         }
602                 }
603         }
604
605         protected <T extends ToscaElement> Either<List<T>, StorageOperationStatus> getFollowedComponent(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, ComponentTypeEnum neededType) {
606
607                 Either<List<T>, StorageOperationStatus> result = null;
608
609                 Map<GraphPropertyEnum, Object> props = null;
610
611                 if (userId != null) {
612                         props = new HashMap<>();
613                         // for Designer retrieve specific user
614                         props.put(GraphPropertyEnum.USERID, userId);
615                 }
616                 // in case of user id == null -> get all users by label
617                 // for Tester and Admin retrieve all users
618                 Either<List<GraphVertex>, TitanOperationStatus> usersByCriteria = titanDao.getByCriteria(VertexTypeEnum.USER, props, JsonParseFlagEnum.NoParse);
619                 if (usersByCriteria.isRight()) {
620                         log.debug("Failed to fetch users by criteria {} error {}", props, usersByCriteria.right().value());
621                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(usersByCriteria.right().value()));
622                 }
623                 List<GraphVertex> users = usersByCriteria.left().value();
624
625                 List<T> components = new ArrayList<>();
626                 List<T> componentsPerUser;
627                 for (GraphVertex userV : users) {
628
629                         HashSet<String> ids = new HashSet<String>();
630                         Either<List<GraphVertex>, TitanOperationStatus> childrenVertecies = titanDao.getChildrenVertecies(userV, EdgeLabelEnum.STATE, JsonParseFlagEnum.NoParse);
631                         if (childrenVertecies.isRight() && childrenVertecies.right().value() != TitanOperationStatus.NOT_FOUND) {
632                                 log.debug("Failed to fetch children vertices for user {} by edge {} error {}", userV.getMetadataProperty(GraphPropertyEnum.USERID), EdgeLabelEnum.STATE, childrenVertecies.right().value());
633                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
634                         }
635
636                         // get all resource with current state
637                         if (childrenVertecies.isLeft()) {
638                                 componentsPerUser = fetchComponents(lifecycleStates, childrenVertecies.left().value(), neededType, EdgeLabelEnum.STATE);
639
640                                 if (componentsPerUser != null) {
641                                         for (T comp : componentsPerUser) {
642                                                 ids.add(comp.getUniqueId());
643                                                 components.add(comp);
644                                         }
645                                 }
646                         }
647                         if (lastStateStates != null && !lastStateStates.isEmpty()) {
648                                 // get all resource with last state
649                                 childrenVertecies = titanDao.getChildrenVertecies(userV, EdgeLabelEnum.LAST_STATE, JsonParseFlagEnum.NoParse);
650                                 if (childrenVertecies.isRight() && childrenVertecies.right().value() != TitanOperationStatus.NOT_FOUND) {
651                                         log.debug("Failed to fetch children vertices for user {} by edge {} error {}", userV.getMetadataProperty(GraphPropertyEnum.USERID), EdgeLabelEnum.LAST_STATE, childrenVertecies.right().value());
652                                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
653                                 }
654                                 if (childrenVertecies.isLeft()) {
655                                         boolean isFirst;
656                                         componentsPerUser = fetchComponents(lastStateStates, childrenVertecies.left().value(), neededType, EdgeLabelEnum.LAST_STATE);
657                                         if (componentsPerUser != null) {
658                                                 for (T comp : componentsPerUser) {
659                                                         isFirst = true;
660
661                                                         if (ids.contains(comp.getUniqueId())) {
662                                                                 isFirst = false;
663                                                         }
664                                                         if (isFirst == true) {
665                                                                 components.add(comp);
666                                                         }
667
668                                                 }
669                                         }
670                                 }
671                         }
672
673                 } // whlile users
674                 ;
675                 result = Either.left(components);
676                 return result;
677
678         }
679
680         private <T extends ToscaElement> List<T> fetchComponents(Set<LifecycleStateEnum> lifecycleStates, List<GraphVertex> vertices, ComponentTypeEnum neededType, EdgeLabelEnum edgelabel) {
681                 List<T> components = new ArrayList<>();
682                 for (GraphVertex node : vertices) {
683
684                         Iterator<Edge> edges = node.getVertex().edges(Direction.IN, edgelabel.name());
685                         while (edges.hasNext()) {
686                                 Edge edge = edges.next();
687                                 String stateStr = (String) titanDao.getProperty(edge, EdgePropertyEnum.STATE);
688
689                                 LifecycleStateEnum nodeState = LifecycleStateEnum.findState(stateStr);
690                                 if (nodeState == null) {
691                                         log.debug("no supported STATE {} for element  {}", stateStr, node.getUniqueId());
692                                         continue;
693                                 }
694                                 if (lifecycleStates != null && lifecycleStates.contains(nodeState)) {
695
696                                         Boolean isDeleted = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
697                                         if (isDeleted != null && isDeleted) {
698                                                 log.trace("Deleted element  {}, discard", node.getUniqueId());
699                                                 continue;
700                                         }
701
702                                         Boolean isHighest = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
703                                         if (isHighest) {
704
705                                                 ComponentTypeEnum componentType = node.getType();
706                                                 // get only latest versions
707
708                                                 if (componentType == null) {
709                                                         log.debug("No supported type {} for vertex {}", componentType, node.getUniqueId());
710                                                         continue;
711                                                 }
712                                                 if (neededType == componentType) {
713                                                         switch (componentType) {
714                                                         case SERVICE:
715                                                         case PRODUCT:
716                                                                 handleNode(components, node, componentType);
717                                                                 break;
718                                                         case RESOURCE:
719                                                                 Boolean isAbtract = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
720                                                                 if (isAbtract == null || false == isAbtract) {
721                                                                         handleNode(components, node, componentType);
722                                                                 } // if not abstract
723                                                                 break;
724                                                         default:
725                                                                 log.debug("not supported node type {}", componentType);
726                                                                 break;
727                                                         }// case
728                                                 } // needed type
729                                         }
730                                 } // if
731                         } // while edges
732                 } // while resources
733                 return components;
734         }
735
736         protected <T extends ToscaElement> void handleNode(List<T> components, GraphVertex vertexComponent, ComponentTypeEnum nodeType) {
737
738                 Either<T, StorageOperationStatus> component = getLightComponent(vertexComponent, nodeType, new ComponentParametersView(true));
739                 if (component.isRight()) {
740                         log.debug("Failed to get component for id =  {}  error : {} skip resource", vertexComponent.getUniqueId(), component.right().value());
741                 } else {
742                         components.add(component.left().value());
743                 }
744         }
745
746         protected <T extends ToscaElement> Either<T, StorageOperationStatus> getLightComponent(String componentUid, ComponentTypeEnum nodeType, ComponentParametersView parametersFilter) {
747                 Either<GraphVertex, TitanOperationStatus> getVertexRes = titanDao.getVertexById(componentUid);
748                 if (getVertexRes.isRight()) {
749                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexRes.right().value()));
750                 }
751                 return getLightComponent(getVertexRes.left().value(), nodeType, parametersFilter);
752         }
753
754         protected <T extends ToscaElement> Either<T, StorageOperationStatus> getLightComponent(GraphVertex vertexComponent, ComponentTypeEnum nodeType, ComponentParametersView parametersFilter) {
755
756                 log.trace("Starting to build light component of type {}, id {}", nodeType, vertexComponent.getUniqueId());
757
758                 titanDao.parseVertexProperties(vertexComponent, JsonParseFlagEnum.ParseMetadata);
759
760                 T toscaElement = convertToComponent(vertexComponent);
761
762                 TitanOperationStatus status = setCreatorFromGraph(vertexComponent, toscaElement);
763                 if (status != TitanOperationStatus.OK) {
764                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
765                 }
766
767                 status = setLastModifierFromGraph(vertexComponent, toscaElement);
768                 if (status != TitanOperationStatus.OK) {
769                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
770                 }
771                 status = setCategoriesFromGraph(vertexComponent, toscaElement);
772                 if (status != TitanOperationStatus.OK) {
773                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
774                 }
775                 if (!parametersFilter.isIgnoreAllVersions()) {
776                         status = setAllVersions(vertexComponent, toscaElement);
777                         if (status != TitanOperationStatus.OK) {
778                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
779                         }
780                 }
781                 if (!parametersFilter.isIgnoreCapabilities()) {
782                         status = setCapabilitiesFromGraph(vertexComponent, toscaElement);
783                         if (status != TitanOperationStatus.OK) {
784                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
785                         }
786                 }
787                 if (!parametersFilter.isIgnoreRequirements()) {
788                         status = setRequirementsFromGraph(vertexComponent, toscaElement);
789                         if (status != TitanOperationStatus.OK) {
790                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
791                         }
792                 }
793                 log.debug("Ended to build light component of type {}, id {}", nodeType, vertexComponent.getUniqueId());
794                 return Either.left(toscaElement);
795         }
796
797         @SuppressWarnings("unchecked")
798         protected <T extends ToscaElement> T convertToComponent(GraphVertex componentV) {
799                 ToscaElement toscaElement = null;
800                 VertexTypeEnum label = componentV.getLabel();
801                 switch (label) {
802                 case NODE_TYPE:
803                         toscaElement = new NodeType();
804                         break;
805                 case TOPOLOGY_TEMPLATE:
806                         toscaElement = new TopologyTemplate();
807                         break;
808                 default:
809                         log.debug("Not supported tosca type {}", label);
810                         break;
811                 }
812
813                 Map<String, Object> jsonMetada = componentV.getMetadataJson();
814                 if (toscaElement != null) {
815                         toscaElement.setMetadata(jsonMetada);
816                 }
817                 return (T) toscaElement;
818         }
819
820         protected TitanOperationStatus setResourceCategoryFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
821                 List<CategoryDefinition> categories = new ArrayList<>();
822                 SubCategoryDefinition subcategory;
823
824                 Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(componentV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
825                 if (childVertex.isRight()) {
826                         log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, componentV.getUniqueId(), childVertex.right().value());
827                         return childVertex.right().value();
828                 }
829                 GraphVertex subCategoryV = childVertex.left().value();
830                 Map<GraphPropertyEnum, Object> metadataProperties = subCategoryV.getMetadataProperties();
831                 subcategory = new SubCategoryDefinition();
832                 subcategory.setUniqueId(subCategoryV.getUniqueId());
833                 subcategory.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
834                 subcategory.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
835
836                 Type listTypeSubcat = new TypeToken<List<String>>() {
837                 }.getType();
838                 List<String> iconsfromJsonSubcat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS), listTypeSubcat);
839                 subcategory.setIcons(iconsfromJsonSubcat);
840
841                 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
842                 if (parentVertex.isRight()) {
843                         log.debug("failed to fetch {} for category with id {}, error {}", EdgeLabelEnum.SUB_CATEGORY, subCategoryV.getUniqueId(), parentVertex.right().value());
844                         return childVertex.right().value();
845                 }
846                 GraphVertex categoryV = parentVertex.left().value();
847                 metadataProperties = categoryV.getMetadataProperties();
848
849                 CategoryDefinition category = new CategoryDefinition();
850                 category.setUniqueId(categoryV.getUniqueId());
851                 category.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
852                 category.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
853
854                 Type listTypeCat = new TypeToken<List<String>>() {
855                 }.getType();
856                 List<String> iconsfromJsonCat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS), listTypeCat);
857                 category.setIcons(iconsfromJsonCat);
858
859                 category.addSubCategory(subcategory);
860                 categories.add(category);
861                 toscaElement.setCategories(categories);
862
863                 return TitanOperationStatus.OK;
864         }
865
866         public <T extends ToscaElement> Either<T, StorageOperationStatus> updateToscaElement(T toscaElementToUpdate, GraphVertex elementV, ComponentParametersView filterResult) {
867                 Either<T, StorageOperationStatus> result = null;
868
869                 log.debug("In updateToscaElement. received component uid = {}", (toscaElementToUpdate == null ? null : toscaElementToUpdate.getUniqueId()));
870                 if (toscaElementToUpdate == null) {
871                         log.error("Service object is null");
872                         result = Either.right(StorageOperationStatus.BAD_REQUEST);
873                         return result;
874                 }
875
876                 String modifierUserId = toscaElementToUpdate.getLastUpdaterUserId();
877                 if (modifierUserId == null || modifierUserId.isEmpty()) {
878                         log.error("UserId is missing in the request.");
879                         result = Either.right(StorageOperationStatus.BAD_REQUEST);
880                         return result;
881                 }
882                 Either<GraphVertex, TitanOperationStatus> findUser = findUserVertex(modifierUserId);
883
884                 if (findUser.isRight()) {
885                         TitanOperationStatus status = findUser.right().value();
886                         log.error("Cannot find user {} in the graph. status is {}", modifierUserId, status);
887                         return result;
888                 }
889
890                 GraphVertex modifierV = findUser.left().value();
891                 // UserData modifierUserData = findUser.left().value();
892                 String toscaElementId = toscaElementToUpdate.getUniqueId();
893
894                 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(elementV, EdgeLabelEnum.LAST_MODIFIER, JsonParseFlagEnum.NoParse);
895                 if (parentVertex.isRight()) {
896                         log.debug("Failed to fetch last modifier for tosca element with id {} error {}", toscaElementId, parentVertex.right().value());
897                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentVertex.right().value()));
898                 }
899                 GraphVertex userV = parentVertex.left().value();
900                 String currentModifier = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
901
902                 String prevSystemName = (String) elementV.getMetadataProperty(GraphPropertyEnum.SYSTEM_NAME);
903
904                 if (currentModifier.equals(modifierUserId)) {
905                         log.debug("Graph LAST MODIFIER edge should not be changed since the modifier is the same as the last modifier.");
906                 } else {
907                         log.debug("Going to update the last modifier user of the resource from {} to {}", currentModifier, modifierUserId);
908                         StorageOperationStatus status = moveLastModifierEdge(elementV, modifierV);
909                         log.debug("Finish to update the last modifier user of the resource from {} to {}. status is {}", currentModifier, modifierUserId, status);
910                         if (status != StorageOperationStatus.OK) {
911                                 result = Either.right(status);
912                                 return result;
913                         }
914                 }
915
916                 final long currentTimeMillis = System.currentTimeMillis();
917                 log.debug("Going to update the last Update Date of the resource from {} to {}", elementV.getJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE), currentTimeMillis);
918                 elementV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currentTimeMillis);
919
920                 StorageOperationStatus checkCategories = validateCategories(toscaElementToUpdate, elementV);
921                 if (checkCategories != StorageOperationStatus.OK) {
922                         result = Either.right(checkCategories);
923                         return result;
924                 }
925
926                 // update all data on vertex
927                 fillToscaElementVertexData(elementV, toscaElementToUpdate, JsonParseFlagEnum.ParseMetadata);
928
929                 Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(elementV);
930
931                 if (updateElement.isRight()) {
932                         log.error("Failed to update resource {}. status is {}", toscaElementId, updateElement.right().value());
933                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
934                         return result;
935                 }
936                 GraphVertex updateElementV = updateElement.left().value();
937
938                 // DE230195 in case resource name changed update TOSCA artifacts
939                 // file names accordingly
940                 String newSystemName = (String) updateElementV.getMetadataProperty(GraphPropertyEnum.SYSTEM_NAME);
941                 if (newSystemName != null && !newSystemName.equals(prevSystemName)) {
942                         Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> resultToscaArt = getDataFromGraph(updateElementV, EdgeLabelEnum.TOSCA_ARTIFACTS);
943                         if (resultToscaArt.isRight()) {
944                                 log.debug("Failed to get  tosca artifact from graph for tosca element {} error {}", toscaElementId, resultToscaArt.right().value());
945                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resultToscaArt.right().value()));
946                         }
947
948                         Map<String, ArtifactDataDefinition> toscaArtifacts = resultToscaArt.left().value();
949                         if (toscaArtifacts != null) {
950                                 for (Entry<String, ArtifactDataDefinition> artifact : toscaArtifacts.entrySet()) {
951                                         generateNewToscaFileName(toscaElementToUpdate.getComponentType().getValue().toLowerCase(), newSystemName, artifact.getValue());
952                                 }
953                                 // TODO call to new Artifact operation in order to update list of artifacts
954
955                         }
956                         // US833308 VLI in service - specific network_role property value logic
957                         if (ComponentTypeEnum.SERVICE == toscaElementToUpdate.getComponentType()) {
958                                 // update method logs success/error and returns boolean (true if nothing fails)
959                                 // TODO!!!!
960                                 // updateServiceNameInVLIsNetworkRolePropertyValues(component, prevSystemName, newSystemName);
961                         }
962                 }
963
964                 if (toscaElementToUpdate.getComponentType() == ComponentTypeEnum.RESOURCE) {
965                         StorageOperationStatus resultDerived = updateDerived(toscaElementToUpdate, updateElementV);
966                         if (resultDerived != StorageOperationStatus.OK) {
967                                 log.debug("Failed to update from derived data for element {} error {}", toscaElementId, resultDerived);
968                                 return Either.right(resultDerived);
969                         }
970                 }
971
972                 Either<T, StorageOperationStatus> updatedResource = getToscaElement(updateElementV, filterResult);
973                 if (updatedResource.isRight()) {
974                         log.error("Failed to fetch tosca element {} after update , error {}", toscaElementId, updatedResource.right().value());
975                         result = Either.right(StorageOperationStatus.BAD_REQUEST);
976                         return result;
977                 }
978
979                 T updatedResourceValue = updatedResource.left().value();
980                 result = Either.left(updatedResourceValue);
981
982                 return result;
983         }
984
985         protected StorageOperationStatus moveLastModifierEdge(GraphVertex elementV, GraphVertex modifierV) {
986                 return DaoStatusConverter.convertTitanStatusToStorageStatus(titanDao.moveEdge(elementV, modifierV, EdgeLabelEnum.LAST_MODIFIER, Direction.IN));
987         }
988
989         protected StorageOperationStatus moveCategoryEdge(GraphVertex elementV, GraphVertex categoryV) {
990                 return DaoStatusConverter.convertTitanStatusToStorageStatus(titanDao.moveEdge(elementV, categoryV, EdgeLabelEnum.CATEGORY, Direction.OUT));
991         }
992
993         private void generateNewToscaFileName(String componentType, String componentName, ArtifactDataDefinition artifactInfo) {
994                 Map<String, Object> getConfig = (Map<String, Object>) ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts().entrySet().stream().filter(p -> p.getKey().equalsIgnoreCase(artifactInfo.getArtifactLabel()))
995                                 .findAny().get().getValue();
996                 artifactInfo.setArtifactName(componentType + "-" + componentName + getConfig.get("artifactName"));
997         }
998
999         protected <T extends ToscaElement> StorageOperationStatus validateResourceCategory(T toscaElementToUpdate, GraphVertex elementV) {
1000                 StorageOperationStatus status = StorageOperationStatus.OK;
1001                 List<CategoryDefinition> newCategoryList = toscaElementToUpdate.getCategories();
1002                 CategoryDefinition newCategory = newCategoryList.get(0);
1003
1004                 Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(elementV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
1005                 if (childVertex.isRight()) {
1006                         log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, elementV.getUniqueId(), childVertex.right().value());
1007                         return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
1008                 }
1009                 GraphVertex subCategoryV = childVertex.left().value();
1010                 Map<GraphPropertyEnum, Object> metadataProperties = subCategoryV.getMetadataProperties();
1011                 String subCategoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
1012
1013                 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
1014                 if (parentVertex.isRight()) {
1015                         log.debug("failed to fetch {} for category with id {}, error {}", EdgeLabelEnum.SUB_CATEGORY, subCategoryV.getUniqueId(), parentVertex.right().value());
1016                         return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
1017                 }
1018                 GraphVertex categoryV = parentVertex.left().value();
1019                 metadataProperties = categoryV.getMetadataProperties();
1020                 String categoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
1021
1022                 boolean categoryWasChanged = false;
1023
1024                 String newCategoryName = newCategory.getName();
1025                 SubCategoryDefinition newSubcategory = newCategory.getSubcategories().get(0);
1026                 String newSubCategoryName = newSubcategory.getName();
1027                 if (newCategoryName != null && false == newCategoryName.equals(categoryNameCurrent)) {
1028                         // the category was changed
1029                         categoryWasChanged = true;
1030                 } else {
1031                         // the sub-category was changed
1032                         if (newSubCategoryName != null && false == newSubCategoryName.equals(subCategoryNameCurrent)) {
1033                                 log.debug("Going to update the category of the resource from {} to {}", categoryNameCurrent, newCategory);
1034                                 categoryWasChanged = true;
1035                         }
1036                 }
1037                 if (categoryWasChanged) {
1038                         Either<GraphVertex, StorageOperationStatus> getCategoryVertex = getResourceCategoryVertex(elementV.getUniqueId(), newSubCategoryName, newCategoryName);
1039
1040                         if (getCategoryVertex.isRight()) {
1041                                 return getCategoryVertex.right().value();
1042                         }
1043                         GraphVertex newCategoryV = getCategoryVertex.left().value();
1044                         status = moveCategoryEdge(elementV, newCategoryV);
1045                         log.debug("Going to update the category of the resource from {} to {}. status is {}", categoryNameCurrent, newCategory, status);
1046                 }
1047                 return status;
1048         }
1049
1050         
1051         public <T extends ToscaElement> Either<List<T>, StorageOperationStatus> getElementCatalogData(ComponentTypeEnum componentType , ToscaElementTypeEnum toscaElement) {
1052                 Either<List<GraphVertex>, TitanOperationStatus> listOfHighestAndAllCertifiedComponents = this.getListOfHighestAndAllCertifiedComponents(componentType , toscaElement);
1053                 if (listOfHighestAndAllCertifiedComponents.isRight() && listOfHighestAndAllCertifiedComponents.right().value() != TitanOperationStatus.NOT_FOUND) {
1054                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(listOfHighestAndAllCertifiedComponents.right().value()));
1055                 }
1056                 List<GraphVertex> highestAndAllCertified = listOfHighestAndAllCertifiedComponents.left().value();
1057                 List<T> result = new ArrayList<>();
1058                 if (highestAndAllCertified != null && false == highestAndAllCertified.isEmpty()) {
1059                         for (GraphVertex vertexComponent : highestAndAllCertified) {
1060                                 Either<T, StorageOperationStatus> component = getLightComponent(vertexComponent, componentType, new ComponentParametersView(true));
1061                                 if (component.isRight()) {
1062                                         log.debug("Failed to fetch ligth element for {} error {}", vertexComponent.getUniqueId(), component.right().value());
1063                                         return Either.right(component.right().value());
1064                                 } else {
1065                                         result.add(component.left().value());
1066                                 }
1067                         }
1068                 }
1069                 return Either.left(result);
1070         }
1071         
1072
1073 public Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestAndAllCertifiedComponents(ComponentTypeEnum componentType , ToscaElementTypeEnum toscaElement) {
1074         long startFetchAllStates = System.currentTimeMillis();
1075         Map<GraphPropertyEnum, Object> propertiesToMatchCertified = new HashMap<>();
1076         propertiesToMatchCertified.put(GraphPropertyEnum.STATE , LifecycleStateEnum.CERTIFIED.name());
1077         propertiesToMatchCertified.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1078         if (componentType == ComponentTypeEnum.RESOURCE ){
1079                 propertiesToMatchCertified.put(GraphPropertyEnum.IS_ABSTRACT, false);
1080         }
1081
1082         Map<GraphPropertyEnum, Object> propertiesHasNotToMatchCertified = new HashMap<>();
1083         propertiesHasNotToMatchCertified.put(GraphPropertyEnum.IS_DELETED, true);
1084         
1085         
1086         Either<List<GraphVertex>, TitanOperationStatus> certifiedNodes = titanDao.getByCriteria(ToscaElementTypeEnum.getVertexTypeByToscaType(toscaElement) , propertiesToMatchCertified, propertiesHasNotToMatchCertified, JsonParseFlagEnum.ParseMetadata);
1087         if (certifiedNodes.isRight() && certifiedNodes.right().value() != TitanOperationStatus.NOT_FOUND) {
1088                 return Either.right(certifiedNodes.right().value());
1089         }
1090         
1091         Map<GraphPropertyEnum, Object> propertiesToMatchHighest = new HashMap<>();
1092         propertiesToMatchHighest.put(GraphPropertyEnum.IS_HIGHEST_VERSION , true);
1093         propertiesToMatchHighest.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1094         if (componentType == ComponentTypeEnum.RESOURCE ){
1095                 propertiesToMatchHighest.put(GraphPropertyEnum.IS_ABSTRACT, false);
1096         }
1097
1098
1099         Map<GraphPropertyEnum, Object> propertiesHasNotToMatchHighest = new HashMap<>();
1100         propertiesHasNotToMatchHighest.put(GraphPropertyEnum.IS_DELETED, true);
1101         propertiesHasNotToMatchHighest.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1102         
1103         
1104         Either<List<GraphVertex>, TitanOperationStatus> highestNode = titanDao.getByCriteria(ToscaElementTypeEnum.getVertexTypeByToscaType(toscaElement) , propertiesToMatchHighest, propertiesHasNotToMatchHighest, JsonParseFlagEnum.ParseMetadata);
1105         if (highestNode.isRight() && highestNode.right().value() != TitanOperationStatus.NOT_FOUND) {
1106                 return Either.right(highestNode.right().value());
1107         }
1108         
1109         long endFetchAllStates = System.currentTimeMillis();
1110
1111         
1112         List<GraphVertex> allNodes = new ArrayList<>();
1113         
1114         if (certifiedNodes.isLeft()) {
1115                 allNodes.addAll(certifiedNodes.left().value());
1116         } 
1117         if (highestNode.isLeft()){
1118                 allNodes.addAll(highestNode.left().value());
1119         }
1120         
1121         int certifiedSize;
1122         int nonCertifiedSize;
1123         
1124         if (certifiedNodes.isRight()){
1125                 certifiedSize = 0;
1126         } else {
1127                 certifiedSize =  certifiedNodes.left().value().size();
1128         }
1129         
1130         if (highestNode.isRight()){
1131                 nonCertifiedSize = 0;
1132         } else {
1133                 nonCertifiedSize =  highestNode.left().value().size();
1134         }
1135         
1136         
1137         log.debug("Fetch catalog {}s all states: certified {}, noncertified {}", componentType, certifiedSize , nonCertifiedSize );
1138         log.debug("Fetch catalog {}s all states from graph took {} ms", componentType, endFetchAllStates - startFetchAllStates);
1139         return Either.left(allNodes);
1140 }
1141
1142
1143         protected Either<List<GraphVertex>, StorageOperationStatus> getAllComponentsMarkedForDeletion(ComponentTypeEnum componentType) {
1144
1145                 // get all components marked for delete
1146                 Map<GraphPropertyEnum, Object> props = new HashMap<GraphPropertyEnum, Object>();
1147                 props.put(GraphPropertyEnum.IS_DELETED, true);
1148                 props.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1149
1150                 Either<List<GraphVertex>, TitanOperationStatus> componentsToDelete = titanDao.getByCriteria(null, props, JsonParseFlagEnum.NoParse);
1151
1152                 if (componentsToDelete.isRight()) {
1153                         TitanOperationStatus error = componentsToDelete.right().value();
1154                         if (error.equals(TitanOperationStatus.NOT_FOUND)) {
1155                                 log.trace("no components to delete");
1156                                 return Either.left(new ArrayList<>());
1157                         } else {
1158                                 log.info("failed to find components to delete. error : {}", error.name());
1159                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1160                         }
1161                 }
1162                 return Either.left(componentsToDelete.left().value());
1163         }
1164
1165         protected TitanOperationStatus setAdditionalInformationFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
1166                 Either<Map<String, AdditionalInfoParameterDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ADDITIONAL_INFORMATION);
1167                 if (result.isLeft()) {
1168                         toscaElement.setAdditionalInformation(result.left().value());
1169                 } else {
1170                         if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
1171                                 return result.right().value();
1172                         }
1173                 }
1174                 return TitanOperationStatus.OK;
1175         }
1176
1177         // --------------------------------------------
1178         public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView);
1179
1180         public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(GraphVertex toscaElementVertex, ComponentParametersView componentParametersView);
1181
1182         public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex);
1183
1184         public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> createToscaElement(ToscaElement toscaElement);
1185
1186         protected abstract <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement);
1187
1188         protected abstract <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement);
1189
1190         protected abstract <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement);
1191
1192         protected abstract <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV);
1193
1194         protected abstract <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex updateElementV);
1195
1196         public abstract <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag);
1197
1198 }