2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.be.model.operations.impl;
23 import com.thinkaurelius.titan.graphdb.query.TitanPredicate;
24 import fj.data.Either;
25 import org.openecomp.sdc.be.config.BeEcompErrorManager;
26 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
27 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
28 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
29 import org.openecomp.sdc.be.datatypes.elements.PolicyTypeDataDefinition;
30 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
31 import org.openecomp.sdc.be.model.PolicyTypeDefinition;
32 import org.openecomp.sdc.be.model.PropertyDefinition;
33 import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
34 import org.openecomp.sdc.be.model.operations.api.IPolicyTypeOperation;
35 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
36 import org.openecomp.sdc.be.resources.data.PolicyTypeData;
37 import org.openecomp.sdc.be.resources.data.PropertyData;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.springframework.beans.factory.annotation.Autowired;
41 import org.springframework.stereotype.Component;
43 import java.util.ArrayList;
44 import java.util.HashMap;
45 import java.util.List;
48 import java.util.stream.Collectors;
50 import static org.openecomp.sdc.be.dao.titan.TitanUtils.buildNotInPredicate;
52 @Component("policy-type-operation")
53 public class PolicyTypeOperation extends AbstractOperation implements IPolicyTypeOperation {
55 private static final Logger log = LoggerFactory.getLogger(PolicyTypeOperation.class.getName());
56 private static final String CREATE_FLOW_CONTEXT = "CreatePolicyType";
57 private static final String GET_FLOW_CONTEXT = "GetPolicyType";
60 private PropertyOperation propertyOperation;
62 private DerivedFromOperation derivedFromOperation;
65 public Either<PolicyTypeDefinition, StorageOperationStatus> getLatestPolicyTypeByType(String type) {
66 Map<String, Object> mapCriteria = new HashMap<>();
67 mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type);
68 mapCriteria.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true);
69 return getPolicyTypeByCriteria(type, mapCriteria);
73 public Either<PolicyTypeDefinition, StorageOperationStatus> addPolicyType(PolicyTypeDefinition policyTypeDef) {
74 Either<PolicyTypeDefinition, StorageOperationStatus> result;
75 Either<PolicyTypeData, StorageOperationStatus> eitherStatus = addPolicyTypeToGraph(policyTypeDef);
76 if (eitherStatus.isRight()) {
77 BeEcompErrorManager.getInstance().logBeFailedCreateNodeError(CREATE_FLOW_CONTEXT, policyTypeDef.getType(), eitherStatus.right().value().name());
78 result = Either.right(eitherStatus.right().value());
80 PolicyTypeData policyTypeData = eitherStatus.left().value();
81 String uniqueId = policyTypeData.getUniqueId();
82 Either<PolicyTypeDefinition, StorageOperationStatus> policyTypeRes = this.getPolicyTypeByUid(uniqueId);
84 if (policyTypeRes.isRight()) {
85 BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError(GET_FLOW_CONTEXT, policyTypeDef.getType(), eitherStatus.right().value().name());
87 result = policyTypeRes;
93 public Either<PolicyTypeDefinition, StorageOperationStatus> updatePolicyType(PolicyTypeDefinition updatedPolicyType, PolicyTypeDefinition currPolicyType) {
94 log.debug("updating policy type {}", updatedPolicyType.getType());
95 updatePolicyTypeData(updatedPolicyType, currPolicyType);
96 return updatePolicyTypeOnGraph(updatedPolicyType, currPolicyType);
100 public Either<List<PolicyTypeDefinition>, StorageOperationStatus> getAllPolicyTypes(Set<String> excludedPolicyTypes) {
101 Map<String, Map.Entry<TitanPredicate, Object>> predicateCriteria = buildNotInPredicate(GraphPropertiesDictionary.TYPE.getProperty(), excludedPolicyTypes);
102 return titanGenericDao.getByCriteriaWithPredicate(NodeTypeEnum.PolicyType, predicateCriteria, PolicyTypeData.class)
104 .map(this::convertPolicyTypesToDefinition)
106 .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
109 private List<PolicyTypeDefinition> convertPolicyTypesToDefinition(List<PolicyTypeData> policiesTypes) {
110 return policiesTypes.stream().map(type -> new PolicyTypeDefinition(type.getPolicyTypeDataDefinition())).collect(Collectors.toList());
114 private Either<PolicyTypeData, StorageOperationStatus> addPolicyTypeToGraph(PolicyTypeDefinition policyTypeDef) {
115 log.debug("Got policy type {}", policyTypeDef);
117 String ptUniqueId = UniqueIdBuilder.buildPolicyTypeUid(policyTypeDef.getType(), policyTypeDef.getVersion());
118 PolicyTypeData policyTypeData = buildPolicyTypeData(policyTypeDef, ptUniqueId);
119 log.debug("Before adding policy type to graph. policyTypeData = {}", policyTypeData);
120 Either<PolicyTypeData, TitanOperationStatus> eitherPolicyTypeData = titanGenericDao.createNode(policyTypeData, PolicyTypeData.class);
121 log.debug("After adding policy type to graph. status is = {}", eitherPolicyTypeData);
122 if (eitherPolicyTypeData.isRight()) {
123 TitanOperationStatus operationStatus = eitherPolicyTypeData.right().value();
124 log.error("Failed to add policy type {} to graph. status is {}", policyTypeDef.getType(), operationStatus);
125 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus));
127 List<PropertyDefinition> properties = policyTypeDef.getProperties();
128 Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToPolicyType = propertyOperation.addPropertiesToElementType(ptUniqueId, NodeTypeEnum.PolicyType, properties);
129 if (addPropertiesToPolicyType.isRight()) {
130 log.error("Failed add properties {} to policy {}", properties, policyTypeDef.getType());
131 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertiesToPolicyType.right().value()));
133 return addDerivedFromRelation(policyTypeDef, ptUniqueId)
135 .map(updatedDerivedFrom -> eitherPolicyTypeData.left().value());
138 private Either<PolicyTypeDefinition, StorageOperationStatus> getPolicyTypeByCriteria(String type, Map<String, Object> properties) {
139 Either<PolicyTypeDefinition, StorageOperationStatus> result;
140 if (type == null || type.isEmpty()) {
141 log.error("type is empty");
142 result = Either.right(StorageOperationStatus.INVALID_ID);
146 Either<List<PolicyTypeData>, TitanOperationStatus> eitherPolicyData = titanGenericDao.getByCriteria(NodeTypeEnum.PolicyType, properties, PolicyTypeData.class);
147 if (eitherPolicyData.isRight()) {
148 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherPolicyData.right().value()));
150 PolicyTypeDataDefinition dataDefinition = eitherPolicyData.left().value().stream().map(PolicyTypeData::getPolicyTypeDataDefinition).findFirst().get();
151 result = getPolicyTypeByUid(dataDefinition.getUniqueId());
157 private Either<PolicyTypeDefinition, StorageOperationStatus> getPolicyTypeByUid(String uniqueId) {
158 log.debug("#getPolicyTypeByUid - fetching policy type with id {}", uniqueId);
159 return titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PolicyType), uniqueId, PolicyTypeData.class)
161 .map(DaoStatusConverter::convertTitanStatusToStorageStatus)
163 .bind(policyType -> createPolicyTypeDefinition(uniqueId, policyType));
166 private Either<PolicyTypeDefinition, StorageOperationStatus> createPolicyTypeDefinition(String uniqueId, PolicyTypeData policyTypeNode) {
167 PolicyTypeDefinition policyType = new PolicyTypeDefinition(policyTypeNode.getPolicyTypeDataDefinition());
168 return fillDerivedFrom(uniqueId, policyType)
170 .map(derivedFrom -> fillProperties(uniqueId, policyType, derivedFrom))
172 .map(props -> policyType);
175 private Either<List<PropertyDefinition>, StorageOperationStatus> fillProperties(String uniqueId, PolicyTypeDefinition policyType, PolicyTypeData derivedFromNode) {
176 log.debug("#fillProperties - fetching all properties for policy type {}", policyType.getType());
177 return propertyOperation.findPropertiesOfNode(NodeTypeEnum.PolicyType, uniqueId)
179 .bind(this::handlePolicyTypeHasNoProperties)
181 .bind(propsMap -> fillDerivedFromProperties(policyType, derivedFromNode, new ArrayList<>(propsMap.values())));
184 private Either<List<PropertyDefinition>, StorageOperationStatus> fillDerivedFromProperties(PolicyTypeDefinition policyType, PolicyTypeData derivedFromNode, List<PropertyDefinition> policyTypeDirectProperties) {
185 if (derivedFromNode == null) {
186 policyType.setProperties(policyTypeDirectProperties);
187 return Either.left(policyTypeDirectProperties);
189 log.debug("#fillDerivedFromProperties - fetching all properties of derived from chain for policy type {}", policyType.getType());
190 return propertyOperation.getAllPropertiesRec(derivedFromNode.getUniqueId(), NodeTypeEnum.PolicyType, PolicyTypeData.class)
192 .map(derivedFromProps -> {policyTypeDirectProperties.addAll(derivedFromProps); return policyTypeDirectProperties;})
194 .map(allProps -> {policyType.setProperties(allProps);return allProps;});
197 private Either<PolicyTypeData, StorageOperationStatus> fillDerivedFrom(String uniqueId, PolicyTypeDefinition policyType) {
198 log.debug("#fillDerivedFrom - fetching policy type {} derived node", policyType.getType());
199 return derivedFromOperation.getDerivedFromChild(uniqueId, NodeTypeEnum.PolicyType, PolicyTypeData.class)
201 .bind(this::handleDerivedFromNotExist)
203 .map(derivedFrom -> setDerivedFrom(policyType, derivedFrom));
207 private Either<PolicyTypeData, StorageOperationStatus> handleDerivedFromNotExist(StorageOperationStatus err) {
208 if (err == StorageOperationStatus.NOT_FOUND) {
209 return Either.left(null);
211 return Either.right(err);
214 Either<Map<String, PropertyDefinition>, StorageOperationStatus> handlePolicyTypeHasNoProperties(TitanOperationStatus err) {
215 if (err == TitanOperationStatus.NOT_FOUND) {
216 return Either.left(new HashMap<>());
218 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(err));
221 private PolicyTypeData setDerivedFrom(PolicyTypeDefinition policyTypeDefinition, PolicyTypeData derivedFrom) {
222 if (derivedFrom != null) {
223 policyTypeDefinition.setDerivedFrom(derivedFrom.getPolicyTypeDataDefinition().getType());
228 private PolicyTypeData buildPolicyTypeData(PolicyTypeDefinition policyTypeDefinition, String ptUniqueId) {
230 PolicyTypeData policyTypeData = new PolicyTypeData(policyTypeDefinition);
232 policyTypeData.getPolicyTypeDataDefinition().setUniqueId(ptUniqueId);
233 Long creationDate = policyTypeData.getPolicyTypeDataDefinition().getCreationTime();
234 if (creationDate == null) {
235 creationDate = System.currentTimeMillis();
238 policyTypeData.getPolicyTypeDataDefinition().setCreationTime(creationDate);
239 policyTypeData.getPolicyTypeDataDefinition().setModificationTime(creationDate);
240 return policyTypeData;
243 private Either<PolicyTypeDefinition, StorageOperationStatus> updatePolicyTypeOnGraph(PolicyTypeDefinition updatedPolicyType, PolicyTypeDefinition currPolicyType) {
244 updatePolicyTypeData(updatedPolicyType, currPolicyType);
245 return titanGenericDao.updateNode(new PolicyTypeData(updatedPolicyType), PolicyTypeData.class)
247 .map(DaoStatusConverter::convertTitanStatusToStorageStatus)
249 .bind(updatedNode -> updatePolicyProperties(updatedPolicyType.getUniqueId(), updatedPolicyType.getProperties()))
251 .bind(updatedProperties -> updatePolicyDerivedFrom(updatedPolicyType, currPolicyType.getDerivedFrom()))
253 .map(updatedDerivedFrom -> updatedPolicyType);
256 private Either<Map<String, PropertyData>, StorageOperationStatus> updatePolicyProperties(String policyId, List<PropertyDefinition> properties) {
257 log.debug("#updatePolicyProperties - updating policy type properties for policy type with id {}", policyId);
258 return propertyOperation.deletePropertiesAssociatedToNode(NodeTypeEnum.PolicyType, policyId)
260 .bind(deleteProps -> addPropertiesToPolicy(policyId, properties));
263 private Either<GraphRelation, StorageOperationStatus> updatePolicyDerivedFrom(PolicyTypeDefinition updatedPolicyType, String currDerivedFromPolicyType) {
264 String policyTypeId = updatedPolicyType.getUniqueId();
265 log.debug("#updatePolicyDerivedFrom - updating policy derived from relation for policy type with id {}. old derived type {}. new derived type {}", policyTypeId, currDerivedFromPolicyType, updatedPolicyType.getDerivedFrom());
266 StorageOperationStatus deleteDerivedRelationStatus = deleteDerivedFromPolicyType(policyTypeId, currDerivedFromPolicyType);
267 if (deleteDerivedRelationStatus != StorageOperationStatus.OK) {
268 return Either.right(deleteDerivedRelationStatus);
270 return addDerivedFromRelation(updatedPolicyType, policyTypeId);
273 private Either<GraphRelation, StorageOperationStatus> addDerivedFromRelation(PolicyTypeDataDefinition policyTypeDef, String ptUniqueId) {
274 String derivedFrom = policyTypeDef.getDerivedFrom();
275 if (derivedFrom == null) {
276 return Either.left(null);
278 log.debug("#addDerivedFromRelationBefore - adding derived from relation between policy type {} to its parent {}", policyTypeDef.getType(), derivedFrom);
279 return this.getLatestPolicyTypeByType(derivedFrom)
281 .bind(derivedFromPolicy -> derivedFromOperation.addDerivedFromRelation(ptUniqueId, derivedFromPolicy.getUniqueId(), NodeTypeEnum.PolicyType));
284 private StorageOperationStatus deleteDerivedFromPolicyType(String policyTypeId, String derivedFromType) {
285 if (derivedFromType == null) {
286 return StorageOperationStatus.OK;
288 log.debug("#deleteDerivedFromPolicyType - deleting derivedFrom relation for policy type with id {} and its derived type {}", policyTypeId, derivedFromType);
289 return getLatestPolicyTypeByType(derivedFromType)
290 .either(derivedFromNode -> derivedFromOperation.removeDerivedFromRelation(policyTypeId, derivedFromNode.getUniqueId(), NodeTypeEnum.PolicyType),
294 private Either<Map<String, PropertyData>, StorageOperationStatus> addPropertiesToPolicy(String policyTypeId, List<PropertyDefinition> properties) {
295 log.debug("#addPropertiesToPolicy - adding policy type properties for policy type with id {}", policyTypeId);
296 return propertyOperation.addPropertiesToElementType(policyTypeId, NodeTypeEnum.PolicyType, properties)
298 .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
301 private void updatePolicyTypeData(PolicyTypeDefinition updatedTypeDefinition, PolicyTypeDefinition currTypeDefinition) {
302 updatedTypeDefinition.setUniqueId(currTypeDefinition.getUniqueId());
303 updatedTypeDefinition.setCreationTime(currTypeDefinition.getCreationTime());
304 updatedTypeDefinition.setModificationTime(System.currentTimeMillis());