Support TOSCA functions in Node Filters
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsonjanusgraph / operations / NodeFilterOperation.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
21
22 import fj.data.Either;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Optional;
26 import java.util.Set;
27 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
28 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
29 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
30 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
31 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
32 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
33 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
34 import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition;
35 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
36 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
37 import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType;
38 import org.openecomp.sdc.be.model.Component;
39 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
40 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
41 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
42 import org.openecomp.sdc.common.log.wrappers.Logger;
43
44 @org.springframework.stereotype.Component("node-filter-operations")
45 public class NodeFilterOperation extends BaseOperation {
46
47     private static Logger logger = Logger.getLogger(NodeFilterOperation.class);
48
49     public Either<Set<String>, StorageOperationStatus> deleteNodeFilters(final Component component, final Set<String> componentInstanceIds) {
50         final Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex;
51         final Either<GraphVertex, JanusGraphOperationStatus> getNodeFilterVertex;
52         StorageOperationStatus status;
53         getComponentVertex = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
54         if (getComponentVertex.isRight()) {
55             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
56         }
57         getNodeFilterVertex = janusGraphDao
58             .getChildVertex(getComponentVertex.left().value(), EdgeLabelEnum.NODE_FILTER_TEMPLATE, JsonParseFlagEnum.NoParse);
59         if (getNodeFilterVertex.isLeft()) {
60             status = deleteToscaDataElements(component.getUniqueId(), EdgeLabelEnum.NODE_FILTER_TEMPLATE, new ArrayList<>(componentInstanceIds));
61             if (status != StorageOperationStatus.OK) {
62                 return Either.right(status);
63             }
64         }
65         return Either.left(componentInstanceIds);
66     }
67
68     public Either<String, StorageOperationStatus> deleteNodeFilter(final Component component, final String componentInstanceId) {
69         final Either<Set<String>, StorageOperationStatus> listStorageOperationStatusEither = deleteNodeFilters(component,
70             Set.of(componentInstanceId));
71         if (listStorageOperationStatusEither.isRight()) {
72             return Either.right(listStorageOperationStatusEither.right().value());
73         }
74         return Either.left(componentInstanceId);
75     }
76
77     public Either<CINodeFilterDataDefinition, StorageOperationStatus> createNodeFilter(final String componentId, final String componentInstanceId) {
78         CINodeFilterDataDefinition nodeFilterDataDefinition = new CINodeFilterDataDefinition();
79         return addOrUpdateNodeFilter(false, componentId, componentInstanceId, nodeFilterDataDefinition);
80     }
81
82     public Either<CINodeFilterDataDefinition, StorageOperationStatus> deleteConstraint(final String serviceId, final String componentInstanceId,
83                                                                                        final CINodeFilterDataDefinition nodeFilterDataDefinition,
84                                                                                        final int propertyIndex,
85                                                                                        final NodeFilterConstraintType nodeFilterConstraintType) {
86         if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) {
87             final ListDataDefinition<PropertyFilterDataDefinition> properties = nodeFilterDataDefinition.getProperties();
88             properties.getListToscaDataDefinition().remove(propertyIndex);
89             nodeFilterDataDefinition.setProperties(properties);
90         } else if (NodeFilterConstraintType.CAPABILITIES.equals(nodeFilterConstraintType)) {
91             final ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> capabilities = nodeFilterDataDefinition.getCapabilities();
92             capabilities.getListToscaDataDefinition().remove(propertyIndex);
93             nodeFilterDataDefinition.setCapabilities(capabilities);
94         }
95         return addOrUpdateNodeFilter(true, serviceId, componentInstanceId, nodeFilterDataDefinition);
96     }
97
98     public Either<CINodeFilterDataDefinition, StorageOperationStatus> addPropertyFilter(final String componentId, final String componentInstanceId,
99                                                                                         final CINodeFilterDataDefinition nodeFilterDataDefinition,
100                                                                                         final PropertyFilterDataDefinition propertyFilterDataDefinition) {
101         ListDataDefinition<PropertyFilterDataDefinition> properties = nodeFilterDataDefinition.getProperties();
102         if (properties == null) {
103             properties = new ListDataDefinition<>();
104             nodeFilterDataDefinition.setProperties(properties);
105         }
106         properties.getListToscaDataDefinition().add(propertyFilterDataDefinition);
107         nodeFilterDataDefinition.setProperties(properties);
108         return addOrUpdateNodeFilter(true, componentId, componentInstanceId, nodeFilterDataDefinition);
109     }
110
111     public Either<CINodeFilterDataDefinition, StorageOperationStatus> addCapabilities(final String componentId, final String componentInstanceId,
112                                                                                       final CINodeFilterDataDefinition nodeFilterDataDefinition,
113                                                                                       final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition) {
114         ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> capabilities = nodeFilterDataDefinition.getCapabilities();
115         if (capabilities == null) {
116             capabilities = new ListDataDefinition<>();
117             nodeFilterDataDefinition.setCapabilities(capabilities);
118         }
119         
120         final Optional<RequirementNodeFilterCapabilityDataDefinition> existingCap = capabilities
121                 .getListToscaDataDefinition().stream()
122                 .filter(def -> def.getName().equals(requirementNodeFilterCapabilityDataDefinition.getName())).findAny();
123         
124         if (existingCap.isPresent()) {
125             final ListDataDefinition<PropertyFilterDataDefinition> newProperties  = requirementNodeFilterCapabilityDataDefinition.getProperties();
126             final ListDataDefinition<PropertyFilterDataDefinition> existingProperties = existingCap.get().getProperties();
127             newProperties.getListToscaDataDefinition().forEach((existingProperties::add)) ;
128         } else {
129             capabilities.getListToscaDataDefinition().add(requirementNodeFilterCapabilityDataDefinition);
130         }
131         nodeFilterDataDefinition.setCapabilities(capabilities);
132         return addOrUpdateNodeFilter(true, componentId, componentInstanceId, nodeFilterDataDefinition);
133     }
134
135     public Either<CINodeFilterDataDefinition, StorageOperationStatus> updateNodeFilter(final String serviceId, final String componentInstanceId,
136                                                                                        final CINodeFilterDataDefinition ciNodeFilterDataDefinition) {
137         return addOrUpdateNodeFilter(true, serviceId, componentInstanceId, ciNodeFilterDataDefinition);
138     }
139
140     public Either<CINodeFilterDataDefinition, StorageOperationStatus> addNodeFilterData(
141             final String componentId,
142             final String componentInstanceId,
143             final CINodeFilterDataDefinition nodeFilterDataDefinition) {
144         return addOrUpdateNodeFilter(false, componentId, componentInstanceId, nodeFilterDataDefinition);
145     }
146
147     private Either<CINodeFilterDataDefinition, StorageOperationStatus> addOrUpdateNodeFilter(final boolean isUpdateAction, final String componentId,
148                                                                                              final String componentInstanceId,
149                                                                                              final CINodeFilterDataDefinition ciNodeFilterDataDefinition) {
150
151         final Either<GraphVertex, JanusGraphOperationStatus> serviceVertexEither =
152             janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
153         if (serviceVertexEither.isRight()) {
154             JanusGraphOperationStatus status = serviceVertexEither.right().value();
155             CommonUtility
156                 .addRecordToLog(logger, CommonUtility.LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ",
157                     componentId, status);
158             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
159         }
160         final GraphVertex serviceVertex = serviceVertexEither.left().value();
161         ciNodeFilterDataDefinition.setID(componentInstanceId);
162         final StorageOperationStatus statusRes = performUpdateToscaAction(isUpdateAction, serviceVertex, List.of(ciNodeFilterDataDefinition));
163         if (!statusRes.equals(StorageOperationStatus.OK)) {
164             janusGraphDao.rollback();
165             logger.error(" Failed to perform tosca update for node filter in service {} , component instance {}. status is {}", componentId,
166                 componentInstanceId, statusRes);
167             return Either.right(statusRes);
168         }
169         janusGraphDao.commit();
170         return Either.left(ciNodeFilterDataDefinition);
171     }
172
173     private StorageOperationStatus performUpdateToscaAction(final boolean isUpdate, final GraphVertex graphVertex,
174                                                             final List<CINodeFilterDataDefinition> toscaDataList) {
175         if (isUpdate) {
176             return updateToscaDataOfToscaElement(graphVertex, EdgeLabelEnum.NODE_FILTER_TEMPLATE, VertexTypeEnum.NODE_FILTER_TEMPLATE, toscaDataList,
177                 JsonPresentationFields.UNIQUE_ID);
178         } else {
179             return addToscaDataToToscaElement(graphVertex, EdgeLabelEnum.NODE_FILTER_TEMPLATE, VertexTypeEnum.NODE_FILTER_TEMPLATE, toscaDataList,
180                 JsonPresentationFields.UNIQUE_ID);
181         }
182     }
183 }