re base code
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / operations / impl / ElementOperation.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.model.operations.impl;
22
23 import com.thinkaurelius.titan.core.TitanGraph;
24 import com.thinkaurelius.titan.core.TitanVertex;
25 import fj.data.Either;
26 import org.apache.commons.lang3.tuple.ImmutablePair;
27 import org.apache.tinkerpop.gremlin.structure.Vertex;
28 import org.openecomp.sdc.be.config.Configuration.ArtifactTypeConfig;
29 import org.openecomp.sdc.be.config.ConfigurationManager;
30 import org.openecomp.sdc.be.dao.api.ActionStatus;
31 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
32 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
33 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
34 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
35 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
36 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
37 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
38 import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition;
39 import org.openecomp.sdc.be.datatypes.category.GroupingDataDefinition;
40 import org.openecomp.sdc.be.datatypes.category.SubCategoryDataDefinition;
41 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
42 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
43 import org.openecomp.sdc.be.model.ArtifactType;
44 import org.openecomp.sdc.be.model.PropertyScope;
45 import org.openecomp.sdc.be.model.Tag;
46 import org.openecomp.sdc.be.model.category.CategoryDefinition;
47 import org.openecomp.sdc.be.model.category.GroupingDefinition;
48 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
49 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
50 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
51 import org.openecomp.sdc.be.resources.data.TagData;
52 import org.openecomp.sdc.be.resources.data.category.CategoryData;
53 import org.openecomp.sdc.be.resources.data.category.GroupingData;
54 import org.openecomp.sdc.be.resources.data.category.SubCategoryData;
55 import org.openecomp.sdc.common.log.wrappers.Logger;
56 import org.openecomp.sdc.common.util.ValidationUtils;
57 import org.springframework.beans.factory.annotation.Qualifier;
58 import org.springframework.stereotype.Component;
59
60 import java.util.*;
61
62 @Component("element-operation")
63 public class ElementOperation implements IElementOperation {
64
65     private static final String COULDN_T_FETCH_TITAN_GRAPH = "Couldn't fetch titan graph";
66         private static final String UNKNOWN_CATEGORY_TYPE = "Unknown category type {}";
67         private TitanGenericDao titanGenericDao;
68
69     public ElementOperation(@Qualifier("titan-generic-dao") TitanGenericDao titanGenericDao) {
70         super();
71         this.titanGenericDao = titanGenericDao;
72     }
73
74     private static final Logger log = Logger.getLogger(ElementOperation.class.getName());
75
76     /*
77      * Old flow
78      */
79     @Override
80     public Either<List<CategoryDefinition>, ActionStatus> getAllServiceCategories() {
81         return getAllCategories(NodeTypeEnum.ServiceNewCategory, false);
82     }
83
84     @Override
85     public Either<List<CategoryDefinition>, ActionStatus> getAllResourceCategories() {
86         return getAllCategories(NodeTypeEnum.ResourceNewCategory, false);
87     }
88
89     @Override
90     public Either<List<CategoryDefinition>, ActionStatus> getAllProductCategories() {
91         return getAllCategories(NodeTypeEnum.ProductCategory, false);
92     }
93     /*
94      *
95      */
96
97     /*
98      * New flow
99      */
100     @Override
101     public Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType) {
102         return createCategory(category, nodeType, false);
103     }
104
105     @Override
106     public Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType, boolean inTransaction) {
107         Either<CategoryDefinition, ActionStatus> result = null;
108         category.setUniqueId(UniqueIdBuilder.buildCategoryUid(category.getNormalizedName(), nodeType));
109         CategoryData categoryData = new CategoryData(nodeType, category);
110
111         try {
112             Either<CategoryData, TitanOperationStatus> createNode = titanGenericDao.createNode(categoryData, CategoryData.class);
113             if (createNode.isRight()) {
114                 TitanOperationStatus value = createNode.right().value();
115                 ActionStatus actionStatus = ActionStatus.GENERAL_ERROR;
116                 log.debug("Problem while creating category, reason {}", value);
117                 if (value == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) {
118                     actionStatus = ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS;
119                 }
120                 result = Either.right(actionStatus);
121                 return result;
122             }
123             CategoryDefinition created = new CategoryDefinition(createNode.left().value().getCategoryDataDefinition());
124             result = Either.left(created);
125             return result;
126         } finally {
127             if (!inTransaction) {
128                 if (result != null && result.isLeft()) {
129                     titanGenericDao.commit();
130                 } else {
131                     titanGenericDao.rollback();
132                 }
133             }
134         }
135     }
136
137     @Override
138     public Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, SubCategoryDefinition subCategory, NodeTypeEnum nodeType) {
139         return createSubCategory(categoryId, subCategory, nodeType, false);
140     }
141
142     @Override
143     public Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, SubCategoryDefinition subCategory, NodeTypeEnum nodeType, boolean inTransaction) {
144
145         Either<SubCategoryDefinition, ActionStatus> result = null;
146
147         try {
148             // create edge from category to sub-category
149             Either<CategoryData, TitanOperationStatus> categoryNode = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class);
150             ActionStatus actionStatus = ActionStatus.GENERAL_ERROR;
151             if (categoryNode.isRight()) {
152                 TitanOperationStatus titanOperationStatus = categoryNode.right().value();
153                 log.debug("Problem while fetching category, reason {}", titanOperationStatus);
154                 if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
155                     actionStatus = ActionStatus.COMPONENT_CATEGORY_NOT_FOUND;
156                 }
157                 result = Either.right(actionStatus);
158                 return result;
159             }
160
161             CategoryDataDefinition categoryDataDefinition = categoryNode.left().value().getCategoryDataDefinition();
162             subCategory.setUniqueId(UniqueIdBuilder.buildSubCategoryUid(categoryDataDefinition.getUniqueId(), subCategory.getNormalizedName()));
163             SubCategoryData subCategoryData = new SubCategoryData(nodeType, subCategory);
164
165             Either<SubCategoryData, TitanOperationStatus> subCategoryNode = titanGenericDao.createNode(subCategoryData, SubCategoryData.class);
166             if (subCategoryNode.isRight()) {
167                 TitanOperationStatus titanOperationStatus = subCategoryNode.right().value();
168                 log.debug("Problem while creating category, reason {}", titanOperationStatus);
169                 if (titanOperationStatus == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) {
170                     actionStatus = ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY;
171                 }
172                 result = Either.right(actionStatus);
173                 return result;
174             }
175
176             Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.createRelation(categoryNode.left().value(), subCategoryNode.left().value(), GraphEdgeLabels.SUB_CATEGORY, null);
177             if (relation.isRight()) {
178                 log.debug("Problem while create relation between category and sub-category ", relation.right().value());
179                 result = Either.right(actionStatus);
180                 return result;
181             }
182             SubCategoryDefinition subCategoryCreated = new SubCategoryDefinition(subCategoryNode.left().value().getSubCategoryDataDefinition());
183             result = Either.left(subCategoryCreated);
184             return result;
185         } finally {
186             if (!inTransaction) {
187                 if (result != null && result.isLeft()) {
188                     titanGenericDao.commit();
189                 } else {
190                     titanGenericDao.rollback();
191                 }
192             }
193         }
194     }
195
196     @Override
197     public Either<GroupingDefinition, ActionStatus> createGrouping(String subCategoryId, GroupingDefinition grouping, NodeTypeEnum nodeType) {
198
199         Either<GroupingDefinition, ActionStatus> result = null;
200
201         try {
202             // create edge from sub-category to grouping
203             Either<SubCategoryData, TitanOperationStatus> subCategoryNode = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class);
204             ActionStatus actionStatus = ActionStatus.GENERAL_ERROR;
205             if (subCategoryNode.isRight()) {
206                 TitanOperationStatus titanOperationStatus = subCategoryNode.right().value();
207                 log.debug("Problem while fetching category, reason {}", titanOperationStatus);
208                 if (titanOperationStatus == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) {
209                     actionStatus = ActionStatus.COMPONENT_CATEGORY_NOT_FOUND;
210                 }
211                 result = Either.right(actionStatus);
212                 return result;
213             }
214
215             SubCategoryDataDefinition subCatData = subCategoryNode.left().value().getSubCategoryDataDefinition();
216             grouping.setUniqueId(UniqueIdBuilder.buildGroupingUid(subCatData.getUniqueId(), grouping.getNormalizedName()));
217             GroupingData groupingData = new GroupingData(nodeType, grouping);
218
219             Either<GroupingData, TitanOperationStatus> groupingNode = titanGenericDao.createNode(groupingData, GroupingData.class);
220             if (groupingNode.isRight()) {
221                 TitanOperationStatus titanOperationStatus = groupingNode.right().value();
222                 log.debug("Problem while creating grouping, reason {}", titanOperationStatus);
223                 if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
224                     actionStatus = ActionStatus.COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY;
225                 }
226                 result = Either.right(actionStatus);
227                 return result;
228             }
229
230             Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.createRelation(subCategoryNode.left().value(), groupingNode.left().value(), GraphEdgeLabels.GROUPING, null);
231             if (relation.isRight()) {
232                 log.debug("Problem while create relation between sub-category and grouping", relation.right().value());
233                 result = Either.right(actionStatus);
234                 return result;
235             }
236             GroupingDefinition groupingCreated = new GroupingDefinition(groupingNode.left().value().getGroupingDataDefinition());
237             result = Either.left(groupingCreated);
238             return result;
239         } finally {
240             if (result != null && result.isLeft()) {
241                 titanGenericDao.commit();
242             } else {
243                 titanGenericDao.rollback();
244             }
245         }
246     }
247
248     @Override
249     public Either<List<CategoryDefinition>, ActionStatus> getAllCategories(NodeTypeEnum nodeType, boolean inTransaction) {
250         try {
251             if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory && nodeType != NodeTypeEnum.ProductCategory) {
252                 log.debug(UNKNOWN_CATEGORY_TYPE, nodeType.name());
253                 return Either.right(ActionStatus.GENERAL_ERROR);
254             }
255
256             Either<List<org.openecomp.sdc.be.resources.data.category.CategoryData>, TitanOperationStatus> either = titanGenericDao.getAll(nodeType, org.openecomp.sdc.be.resources.data.category.CategoryData.class);
257             if (either.isRight() && (either.right().value() != TitanOperationStatus.NOT_FOUND)) {
258                 log.debug("Problem while get all categories. reason - {}", either.right().value());
259                 return Either.right(ActionStatus.GENERAL_ERROR);
260             }
261             List<CategoryData> categoryDataList = either.isLeft() ? either.left().value() : null;
262             List<CategoryDefinition> categoryList = new ArrayList<>();
263             if (categoryDataList != null) {
264                 for (CategoryData elem : categoryDataList) {
265                     CategoryDataDefinition categoryDataDefinition = elem.getCategoryDataDefinition();
266
267                     CategoryDefinition categoryDefinition = new CategoryDefinition(categoryDataDefinition);
268                     String categoryName = categoryDataDefinition.getName();
269                     log.trace("Found category {}, category type {}", categoryName, nodeType);
270                     TitanOperationStatus setSubCategories = setSubCategories(nodeType, categoryDefinition);
271                     if (setSubCategories != TitanOperationStatus.OK) {
272                         log.debug("Failed to set sub-categories for category {}, category type {}, error {}", categoryName, nodeType, setSubCategories);
273                         return Either.right(ActionStatus.GENERAL_ERROR);
274                     }
275                     categoryList.add(categoryDefinition);
276                 }
277             }
278             return Either.left(categoryList);
279         } finally {
280             if (!inTransaction) {
281                 titanGenericDao.commit();
282             }
283         }
284     }
285
286     private TitanOperationStatus setSubCategories(NodeTypeEnum parentNodeType, CategoryDefinition parentCategory) {
287         NodeTypeEnum childNodeType = getChildNodeType(parentNodeType);
288         if (childNodeType != null) {
289             String categoryName = parentCategory.getName();
290             log.trace("Getting sub-categories for category {}, category type {}", categoryName, parentNodeType);
291             Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, TitanOperationStatus> parentNode = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentCategory.getUniqueId(), GraphEdgeLabels.SUB_CATEGORY,
292                     childNodeType, SubCategoryData.class);
293             if (parentNode.isRight()) {
294                 TitanOperationStatus titanOperationStatus = parentNode.right().value();
295                 if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
296                     log.trace("Didn't find subcategories for category {}, category type {}", categoryName, parentNodeType);
297                     titanOperationStatus = TitanOperationStatus.OK;
298                 }
299                 return titanOperationStatus;
300             }
301             List<ImmutablePair<SubCategoryData, GraphEdge>> subsCategoriesData = parentNode.left().value();
302             List<SubCategoryDefinition> subCategoriesDefinitions = new ArrayList<>();
303             for (ImmutablePair<SubCategoryData, GraphEdge> subCatPair : subsCategoriesData) {
304                 SubCategoryDataDefinition subCategoryDataDefinition = subCatPair.getLeft().getSubCategoryDataDefinition();
305                 SubCategoryDefinition subCategoryDefinition = new SubCategoryDefinition(subCategoryDataDefinition);
306
307                 log.trace("Found sub-category {} for category {}, category type {}", subCategoryDataDefinition.getName(), categoryName, parentNodeType);
308                 TitanOperationStatus setGroupings = setGroupings(childNodeType, subCategoryDefinition);
309                 if (setGroupings != TitanOperationStatus.OK) {
310                     log.debug("Failed to set groupings for sub-category {}, sub-category type {}, error {}", subCategoryDataDefinition.getName(), childNodeType, setGroupings);
311                     return TitanOperationStatus.GENERAL_ERROR;
312                 }
313                 subCategoriesDefinitions.add(subCategoryDefinition);
314             }
315             parentCategory.setSubcategories(subCategoriesDefinitions);
316         }
317         return TitanOperationStatus.OK;
318     }
319
320     private TitanOperationStatus setGroupings(NodeTypeEnum parentNodeType, SubCategoryDefinition parentSubCategory) {
321         NodeTypeEnum childNodeType = getChildNodeType(parentNodeType);
322         if (childNodeType != null) {
323             String subCategoryName = parentSubCategory.getName();
324             log.trace("Getting groupings for subcategory {}, subcategory type {}", subCategoryName, parentNodeType);
325             Either<List<ImmutablePair<GroupingData, GraphEdge>>, TitanOperationStatus> parentNode = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentSubCategory.getUniqueId(), GraphEdgeLabels.GROUPING,
326                     childNodeType, GroupingData.class);
327             if (parentNode.isRight()) {
328                 TitanOperationStatus titanOperationStatus = parentNode.right().value();
329                 if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
330                     log.trace("Didn't find groupings for subcategory {}, subcategory type {}", subCategoryName, parentNodeType);
331                     titanOperationStatus = TitanOperationStatus.OK;
332                 }
333                 return titanOperationStatus;
334             }
335             List<ImmutablePair<GroupingData, GraphEdge>> groupingData = parentNode.left().value();
336             List<GroupingDefinition> groupingDefinitions = new ArrayList<>();
337             for (ImmutablePair<GroupingData, GraphEdge> groupPair : groupingData) {
338                 GroupingDataDefinition groupingDataDefinition = groupPair.getLeft().getGroupingDataDefinition();
339                 log.trace("Found grouping {} for sub-category {}, sub-category type {}", groupingDataDefinition.getName(), subCategoryName, parentNodeType);
340                 groupingDefinitions.add(new GroupingDefinition(groupingDataDefinition));
341             }
342             parentSubCategory.setGroupings(groupingDefinitions);
343         }
344         return TitanOperationStatus.OK;
345     }
346
347     private static NodeTypeEnum getChildNodeType(NodeTypeEnum parentTypeEnum) {
348         NodeTypeEnum res = null;
349         switch (parentTypeEnum) {
350         case ResourceNewCategory:
351             res = NodeTypeEnum.ResourceSubcategory;
352             break;
353         case ProductCategory:
354             res = NodeTypeEnum.ProductSubcategory;
355             break;
356         case ProductSubcategory:
357             res = NodeTypeEnum.ProductGrouping;
358             break;
359         default:
360             break;
361         }
362         return res;
363     }
364
365     @Override
366     public Either<CategoryDefinition, ActionStatus> getCategory(NodeTypeEnum nodeType, String categoryId) {
367         try {
368             if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory && nodeType != NodeTypeEnum.ProductCategory) {
369                 log.debug(UNKNOWN_CATEGORY_TYPE, nodeType.name());
370                 return Either.right(ActionStatus.GENERAL_ERROR);
371             }
372
373             Either<CategoryData, TitanOperationStatus> categoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class);
374             if (categoryDataEither.isRight()) {
375                 TitanOperationStatus titanOperationStatus = categoryDataEither.right().value();
376                 log.debug("Problem while get category by id {}. reason {}", categoryId, titanOperationStatus);
377                 if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
378                     return Either.right(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND);
379                 }
380                 return Either.right(ActionStatus.GENERAL_ERROR);
381             }
382             CategoryDataDefinition categoryDataDefinition = categoryDataEither.left().value().getCategoryDataDefinition();
383             return Either.left(new CategoryDefinition(categoryDataDefinition));
384         } finally {
385             titanGenericDao.commit();
386         }
387     }
388
389     @Override
390     public Either<SubCategoryDefinition, ActionStatus> getSubCategory(NodeTypeEnum nodeType, String subCategoryId) {
391         try {
392             if (nodeType != NodeTypeEnum.ResourceSubcategory && nodeType != NodeTypeEnum.ProductSubcategory) {
393                 log.debug("Unknown sub-category type {}", nodeType.name());
394                 return Either.right(ActionStatus.GENERAL_ERROR);
395             }
396
397             Either<SubCategoryData, TitanOperationStatus> subCategoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class);
398             if (subCategoryDataEither.isRight()) {
399                 TitanOperationStatus titanOperationStatus = subCategoryDataEither.right().value();
400                 log.debug("Problem while get sub-category by id {}. reason {}", subCategoryId, titanOperationStatus);
401                 if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
402                     return Either.right(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND);
403                 }
404                 return Either.right(ActionStatus.GENERAL_ERROR);
405             }
406             SubCategoryDataDefinition subCategoryDataDefinition = subCategoryDataEither.left().value().getSubCategoryDataDefinition();
407             return Either.left(new SubCategoryDefinition(subCategoryDataDefinition));
408         } finally {
409             titanGenericDao.commit();
410         }
411     }
412
413     @Override
414     public Either<CategoryDefinition, ActionStatus> deleteCategory(NodeTypeEnum nodeType, String categoryId) {
415         Either<CategoryDefinition, ActionStatus> result = null;
416         try {
417             if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory && nodeType != NodeTypeEnum.ProductCategory) {
418                 log.debug(UNKNOWN_CATEGORY_TYPE, nodeType.name());
419                 result = Either.right(ActionStatus.GENERAL_ERROR);
420                 return result;
421             }
422             Either<CategoryData, TitanOperationStatus> categoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class);
423             if (categoryDataEither.isRight()) {
424                 log.debug("Failed to retrieve  category for id {} ", categoryId);
425                 result = Either.right(ActionStatus.GENERAL_ERROR);
426                 return result;
427             }
428
429             Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
430             if (graph.isRight()) {
431                 log.debug(COULDN_T_FETCH_TITAN_GRAPH);
432                 result = Either.right(ActionStatus.GENERAL_ERROR);
433                 return result;
434             }
435
436             TitanGraph tGraph = graph.left().value();
437
438             Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId).vertices();
439             Iterator<TitanVertex> iterator = verticesArtifact.iterator();
440             if (!iterator.hasNext()) {
441                 log.debug("No category node for id = {}", categoryId);
442                 result = Either.right(ActionStatus.GENERAL_ERROR);
443                 return result;
444             }
445             Vertex artifactV = iterator.next();
446             artifactV.remove();
447             CategoryDefinition deleted = new CategoryDefinition(categoryDataEither.left().value().getCategoryDataDefinition());
448             result = Either.left(deleted);
449             return result;
450         } finally {
451             if (result != null && result.isLeft()) {
452                 titanGenericDao.commit();
453             } else {
454                 titanGenericDao.rollback();
455             }
456         }
457     }
458
459     @Override
460     public Either<SubCategoryDefinition, ActionStatus> deleteSubCategory(NodeTypeEnum nodeType, String subCategoryId) {
461         Either<SubCategoryDefinition, ActionStatus> result = null;
462         try {
463             if (nodeType != NodeTypeEnum.ResourceSubcategory && nodeType != NodeTypeEnum.ProductSubcategory) {
464                 log.debug("Unknown sub-category type {}", nodeType.name());
465                 result = Either.right(ActionStatus.GENERAL_ERROR);
466                 return result;
467             }
468             Either<SubCategoryData, TitanOperationStatus> subCategoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class);
469             if (subCategoryDataEither.isRight()) {
470                 log.debug("Failed to retrieve  sub-category for id {}", subCategoryId);
471                 result = Either.right(ActionStatus.GENERAL_ERROR);
472                 return result;
473             }
474
475             Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
476             if (graph.isRight()) {
477                 log.debug(COULDN_T_FETCH_TITAN_GRAPH);
478                 result = Either.right(ActionStatus.GENERAL_ERROR);
479                 return result;
480             }
481
482             TitanGraph tGraph = graph.left().value();
483
484             Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId).vertices();
485             Iterator<TitanVertex> iterator = verticesArtifact.iterator();
486             if (!iterator.hasNext()) {
487                 log.debug("No sub-category node for id {}", subCategoryId);
488                 result = Either.right(ActionStatus.GENERAL_ERROR);
489                 return result;
490             }
491             Vertex artifactV = iterator.next();
492             artifactV.remove();
493             ;
494             SubCategoryDefinition deleted = new SubCategoryDefinition(subCategoryDataEither.left().value().getSubCategoryDataDefinition());
495             result = Either.left(deleted);
496             return result;
497         } finally {
498             if (result != null && result.isLeft()) {
499                 titanGenericDao.commit();
500             } else {
501                 titanGenericDao.rollback();
502             }
503         }
504
505     }
506
507     @Override
508     public Either<GroupingDefinition, ActionStatus> deleteGrouping(NodeTypeEnum nodeType, String groupingId) {
509         Either<GroupingDefinition, ActionStatus> result = null;
510         try {
511             if (nodeType != NodeTypeEnum.ProductGrouping) {
512                 log.debug("Unknown grouping type {}", nodeType.name());
513                 result = Either.right(ActionStatus.GENERAL_ERROR);
514                 return result;
515             }
516             Either<GroupingData, TitanOperationStatus> groupingDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId, GroupingData.class);
517             if (groupingDataEither.isRight()) {
518                 log.debug("Failed to retrieve  grouping for id {}", groupingId);
519                 result = Either.right(ActionStatus.GENERAL_ERROR);
520                 return result;
521             }
522
523             Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
524             if (graph.isRight()) {
525                 log.debug(COULDN_T_FETCH_TITAN_GRAPH);
526                 result = Either.right(ActionStatus.GENERAL_ERROR);
527                 return result;
528             }
529
530             TitanGraph tGraph = graph.left().value();
531
532             Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId).vertices();
533             Iterator<TitanVertex> iterator = verticesArtifact.iterator();
534             if (!iterator.hasNext()) {
535                 log.debug("No grouping node for id {}", groupingId);
536                 result = Either.right(ActionStatus.GENERAL_ERROR);
537                 return result;
538             }
539             Vertex artifactV = iterator.next();
540             artifactV.remove();
541             ;
542             GroupingDefinition deleted = new GroupingDefinition(groupingDataEither.left().value().getGroupingDataDefinition());
543             result = Either.left(deleted);
544             return result;
545         } finally {
546             if (result != null && result.isLeft()) {
547                 titanGenericDao.commit();
548             } else {
549                 titanGenericDao.rollback();
550             }
551         }
552     }
553
554     @Override
555     public Either<Boolean, ActionStatus> isCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName) {
556
557         Map<String, Object> properties = new HashMap<>();
558         properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName);
559         try {
560             Either<List<CategoryData>, TitanOperationStatus> categoryEither = titanGenericDao.getByCriteria(nodeType, properties, CategoryData.class);
561             if (categoryEither.isRight() && categoryEither.right().value() != TitanOperationStatus.NOT_FOUND) {
562                 log.debug("Failed to get categories, nodeType {}, normalizedName {}, error {}", nodeType, normalizedName, categoryEither.right().value());
563                 return Either.right(ActionStatus.GENERAL_ERROR);
564             }
565             List<CategoryData> categoryList = (categoryEither.isLeft() ? categoryEither.left().value() : null);
566             if (categoryList != null && categoryList.size() > 0) {
567                 log.debug("Found category for nodeType {} with normalizedName {}", nodeType, normalizedName);
568                 if (categoryList.size() > 1) {
569                     log.debug("Found more than 1 unique categories for nodeType {} with normalizedName", nodeType, normalizedName);
570                     return Either.right(ActionStatus.GENERAL_ERROR);
571                 }
572                 return Either.left(false);
573             } else {
574                 log.debug("Category for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, normalizedName);
575                 return Either.left(true);
576             }
577         } finally {
578             titanGenericDao.commit();
579         }
580     }
581
582     @Override
583     public Either<Boolean, ActionStatus> isSubCategoryUniqueForCategory(NodeTypeEnum nodeType, String subCategoryNormName, String parentCategoryId) {
584
585         String subCategoryId = UniqueIdBuilder.buildSubCategoryUid(parentCategoryId, subCategoryNormName);
586         try {
587             Either<SubCategoryData, TitanOperationStatus> subCategoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class);
588             if (subCategoryDataEither.isRight() && subCategoryDataEither.right().value() != TitanOperationStatus.NOT_FOUND) {
589                 log.debug("Failed to get sub-category with id {}, error {}", subCategoryId, subCategoryDataEither.right().value());
590                 return Either.right(ActionStatus.GENERAL_ERROR);
591             }
592             SubCategoryData subCategoryData = (subCategoryDataEither.isLeft() ? subCategoryDataEither.left().value() : null);
593             if (subCategoryData != null) {
594                 log.debug("Found sub-category with id {}", subCategoryId);
595                 return Either.left(false);
596             } else {
597                 log.debug("Sub-category for id {} doesn't exist in graph", subCategoryId);
598                 return Either.left(true);
599             }
600         } finally {
601             titanGenericDao.commit();
602         }
603     }
604
605     @Override
606     public Either<Boolean, ActionStatus> isGroupingUniqueForSubCategory(NodeTypeEnum nodeType, String groupingNormName, String parentSubCategoryId) {
607
608         String groupingId = UniqueIdBuilder.buildGroupingUid(parentSubCategoryId, groupingNormName);
609         try {
610             Either<GroupingData, TitanOperationStatus> groupingDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId, GroupingData.class);
611             if (groupingDataEither.isRight() && groupingDataEither.right().value() != TitanOperationStatus.NOT_FOUND) {
612                 log.debug("Failed to get grouping with id {}, error {}", groupingId, groupingDataEither.right().value());
613                 return Either.right(ActionStatus.GENERAL_ERROR);
614             }
615             GroupingData groupingData = (groupingDataEither.isLeft() ? groupingDataEither.left().value() : null);
616             if (groupingData != null) {
617                 log.debug("Found grouping with id {}", groupingId);
618                 return Either.left(false);
619             } else {
620                 log.debug("Grouping for id {} doesn't exist in graph", groupingId);
621                 return Either.left(true);
622             }
623         } finally {
624             titanGenericDao.commit();
625         }
626     }
627
628     @Override
629     public Either<SubCategoryDefinition, ActionStatus> getSubCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName) {
630         Map<String, Object> properties = new HashMap<>();
631         properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName);
632         try {
633             Either<List<SubCategoryData>, TitanOperationStatus> subCategoryEither = titanGenericDao.getByCriteria(nodeType, properties, SubCategoryData.class);
634             if (subCategoryEither.isRight() && subCategoryEither.right().value() != TitanOperationStatus.NOT_FOUND) {
635                 log.debug("Failed to get sub-categories, nodeType {}, normalizedName {}, error {}", nodeType, normalizedName, subCategoryEither.right().value());
636                 return Either.right(ActionStatus.GENERAL_ERROR);
637             }
638             List<SubCategoryData> subCategoryList = (subCategoryEither.isLeft() ? subCategoryEither.left().value() : null);
639             if (subCategoryList != null && subCategoryList.size() > 0) {
640                 log.debug("Found sub-category for nodeType {} with normalizedName {}", nodeType, normalizedName);
641                 SubCategoryData subCategoryData = subCategoryList.get(0);
642                 SubCategoryDefinition subCategoryDefinition = new SubCategoryDefinition(subCategoryData.getSubCategoryDataDefinition());
643                 return Either.left(subCategoryDefinition);
644             } else {
645                 log.debug("Sub-category for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, normalizedName);
646                 return Either.left(null);
647             }
648         } finally {
649             titanGenericDao.commit();
650         }
651     }
652
653     @Override
654     public Either<GroupingDefinition, ActionStatus> getGroupingUniqueForType(NodeTypeEnum nodeType, String groupingNormalizedName) {
655         Map<String, Object> properties = new HashMap<>();
656         properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), groupingNormalizedName);
657         try {
658             Either<List<GroupingData>, TitanOperationStatus> groupingEither = titanGenericDao.getByCriteria(nodeType, properties, GroupingData.class);
659             if (groupingEither.isRight() && groupingEither.right().value() != TitanOperationStatus.NOT_FOUND) {
660                 log.debug("Failed to get grouping, nodeType {}, normalizedName {}, error {}", nodeType, groupingNormalizedName, groupingEither.right().value());
661                 return Either.right(ActionStatus.GENERAL_ERROR);
662             }
663             List<GroupingData> groupingList = (groupingEither.isLeft() ? groupingEither.left().value() : null);
664             if (groupingList != null && groupingList.size() > 0) {
665                 log.debug("Found grouping for nodeType {} with normalizedName {}", nodeType, groupingNormalizedName);
666                 GroupingData groupingData = groupingList.get(0);
667                 GroupingDefinition groupingDefinition = new GroupingDefinition(groupingData.getGroupingDataDefinition());
668                 return Either.left(groupingDefinition);
669             } else {
670                 log.debug("Grouping for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, groupingNormalizedName);
671                 return Either.left(null);
672             }
673         } finally {
674             titanGenericDao.commit();
675         }
676     }
677
678     /*
679      *
680      */
681
682     @Override
683     public Either<List<Tag>, ActionStatus> getAllTags() {
684         try {
685             Either<List<TagData>, TitanOperationStatus> either = titanGenericDao.getAll(NodeTypeEnum.Tag, TagData.class);
686             if (either.isRight()) {
687                 log.debug("Problem while get all tags. reason - {}", either.right().value());
688                 return Either.right(ActionStatus.GENERAL_ERROR);
689             }
690             List<TagData> tagDataList = either.left().value();
691             List<Tag> tagList = convertToListOfTag(tagDataList);
692             return Either.left(tagList);
693         } finally {
694             titanGenericDao.commit();
695         }
696     }
697
698     @Override
699     public <T extends GraphNode> Either<org.openecomp.sdc.be.resources.data.CategoryData, StorageOperationStatus> getCategoryData(String name, NodeTypeEnum type, Class<T> clazz) {
700         if (name != null) {
701             String categoryUid = null;
702             if (type == NodeTypeEnum.ResourceCategory) {
703                 String[] categoryFields = name.split("/");
704                 if (categoryFields.length != 2) {
705                     return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
706                 }
707                 categoryUid = UniqueIdBuilder.buildResourceCategoryUid(categoryFields[0], categoryFields[1], type);
708             } else {
709                 categoryUid = UniqueIdBuilder.buildServiceCategoryUid(name, type);
710             }
711             Either<T, TitanOperationStatus> either = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(type), categoryUid, clazz);
712
713             if (either.isRight()) {
714                 TitanOperationStatus titanOperationStatus = either.right().value();
715                 log.debug("Problem while geting category with id {}. reason - {}", categoryUid, titanOperationStatus.name());
716                 if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
717                     return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
718                 } else {
719                     return Either.right(StorageOperationStatus.GENERAL_ERROR);
720                 }
721             }
722             return Either.left((org.openecomp.sdc.be.resources.data.CategoryData) either.left().value());
723         } else {
724             return Either.right(StorageOperationStatus.GENERAL_ERROR);
725         }
726     }
727
728     private List<Tag> convertToListOfTag(List<TagData> tagDataList) {
729         List<Tag> tagList = new ArrayList<>();
730         for (TagData elem : tagDataList) {
731             Tag tag = new Tag();
732             tag.setName(elem.getName());
733             tagList.add(tag);
734         }
735         return tagList;
736     }
737
738     @Override
739     public Either<List<PropertyScope>, ActionStatus> getAllPropertyScopes() {
740         // Mock
741         List<PropertyScope> propertyScopes = new ArrayList<>();
742         PropertyScope propertyScope1 = new PropertyScope();
743         propertyScope1.setName("A&AI");
744         PropertyScope propertyScope2 = new PropertyScope();
745         propertyScope2.setName("Order");
746         PropertyScope propertyScope3 = new PropertyScope();
747         propertyScope3.setName("Runtime");
748         propertyScopes.add(propertyScope1);
749         propertyScopes.add(propertyScope2);
750         propertyScopes.add(propertyScope3);
751         return Either.left(propertyScopes);
752     }
753
754     @Override
755     public Either<List<ArtifactType>, ActionStatus> getAllArtifactTypes() {
756         List<ArtifactType> artifactTypes = new ArrayList<>();
757
758         List<String> artifactTypesList = ConfigurationManager.getConfigurationManager().getConfiguration().getArtifactTypes();
759         for (String artifactType : artifactTypesList) {
760             ArtifactType artifactT = new ArtifactType();
761             artifactT.setName(artifactType);
762             artifactTypes.add(artifactT);
763         }
764         return Either.left(artifactTypes);
765     }
766
767     @Override
768     public Either<Map<String, Object>, ActionStatus> getAllDeploymentArtifactTypes() {
769
770         Map<String, Object> artifactTypes = new HashMap<>();
771         Map<String, ArtifactTypeConfig> artifactResourceTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceDeploymentArtifacts();
772         Map<String, ArtifactTypeConfig> artifactServiceTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceDeploymentArtifacts();
773         Map<String, ArtifactTypeConfig> artifactResourceInstanceTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceInstanceDeploymentArtifacts();
774
775         artifactTypes.put("resourceDeploymentArtifacts", artifactResourceTypes);
776         artifactTypes.put("serviceDeploymentArtifacts", artifactServiceTypes);
777         artifactTypes.put("resourceInstanceDeploymentArtifacts", artifactResourceInstanceTypes);
778
779         return Either.left(artifactTypes);
780
781     }
782
783     @Override
784     public Either<Integer, ActionStatus> getDefaultHeatTimeout() {
785         return Either.left(ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultHeatArtifactTimeoutMinutes());
786     }
787
788     @Override
789     public Either<Map<String, String>, ActionStatus> getResourceTypesMap() {
790         ResourceTypeEnum[] enumConstants = ResourceTypeEnum.class.getEnumConstants();
791         Map<String, String> resourceTypes = new HashMap<>();
792         if (enumConstants != null) {
793             for (int i = 0; i < enumConstants.length; ++i) {
794                 resourceTypes.put(enumConstants[i].name(), enumConstants[i].getValue());
795             }
796
797         }
798         return Either.left(resourceTypes);
799     }
800
801     @Override
802     public <T extends GraphNode> Either<CategoryData, StorageOperationStatus> getNewCategoryData(String name, NodeTypeEnum type, Class<T> clazz) {
803         if (name != null) {
804             String categoryUid = UniqueIdBuilder.buildServiceCategoryUid(name, type);
805             Map props = new HashMap<>();
806             props.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), ValidationUtils.normalizeCategoryName4Uniqueness(name));
807             Either<List<T>, TitanOperationStatus> either = titanGenericDao.getByCriteria(type, props, clazz);
808
809             if (either.isRight()) {
810                 TitanOperationStatus titanOperationStatus = either.right().value();
811                 log.debug("Problem while geting category with id {}. reason - {}", categoryUid, titanOperationStatus.name());
812                 if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
813                     return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
814                 } else {
815                     return Either.right(StorageOperationStatus.GENERAL_ERROR);
816                 }
817             }
818             return Either.left((CategoryData) either.left().value().get(0));
819         } else {
820             return Either.right(StorageOperationStatus.GENERAL_ERROR);
821         }
822     }
823
824 }