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