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=========================================================
20 package org.openecomp.sdc.be.model.operations.impl;
22 import static org.openecomp.sdc.be.dao.janusgraph.JanusGraphUtils.buildNotInPredicate;
24 import fj.data.Either;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
30 import java.util.stream.Collectors;
31 import org.janusgraph.graphdb.query.JanusGraphPredicate;
32 import org.openecomp.sdc.be.config.BeEcompErrorManager;
33 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
34 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
35 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
36 import org.openecomp.sdc.be.datatypes.elements.PolicyTypeDataDefinition;
37 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
38 import org.openecomp.sdc.be.model.PolicyTypeDefinition;
39 import org.openecomp.sdc.be.model.PropertyDefinition;
40 import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
41 import org.openecomp.sdc.be.model.operations.api.IPolicyTypeOperation;
42 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
43 import org.openecomp.sdc.be.resources.data.PolicyTypeData;
44 import org.openecomp.sdc.be.resources.data.PropertyData;
45 import org.openecomp.sdc.common.log.wrappers.Logger;
46 import org.springframework.beans.factory.annotation.Autowired;
47 import org.springframework.stereotype.Component;
49 @Component("policy-type-operation")
50 public class PolicyTypeOperation extends AbstractOperation implements IPolicyTypeOperation {
52 private static final Logger log = Logger.getLogger(PolicyTypeOperation.class.getName());
53 private static final String CREATE_FLOW_CONTEXT = "CreatePolicyType";
54 private static final String GET_FLOW_CONTEXT = "GetPolicyType";
56 private PropertyOperation propertyOperation;
58 private DerivedFromOperation derivedFromOperation;
60 private OperationUtils operationUtils;
63 public Either<PolicyTypeDefinition, StorageOperationStatus> getLatestPolicyTypeByType(String type) {
64 Map<String, Object> mapCriteria = new HashMap<>();
65 mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type);
66 mapCriteria.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true);
67 return getPolicyTypeByCriteria(type, mapCriteria);
71 public Either<PolicyTypeDefinition, StorageOperationStatus> addPolicyType(PolicyTypeDefinition policyTypeDef) {
72 Either<PolicyTypeDefinition, StorageOperationStatus> result;
73 Either<PolicyTypeData, StorageOperationStatus> eitherStatus = addPolicyTypeToGraph(policyTypeDef);
74 if (eitherStatus.isRight()) {
75 BeEcompErrorManager.getInstance()
76 .logBeFailedCreateNodeError(CREATE_FLOW_CONTEXT, policyTypeDef.getType(), eitherStatus.right().value().name());
77 result = Either.right(eitherStatus.right().value());
79 PolicyTypeData policyTypeData = eitherStatus.left().value();
80 String uniqueId = policyTypeData.getUniqueId();
81 Either<PolicyTypeDefinition, StorageOperationStatus> policyTypeRes = this.getPolicyTypeByUid(uniqueId);
82 if (policyTypeRes.isRight()) {
83 BeEcompErrorManager.getInstance()
84 .logBeFailedRetrieveNodeError(GET_FLOW_CONTEXT, policyTypeDef.getType(), eitherStatus.right().value().name());
86 result = policyTypeRes;
92 public Either<PolicyTypeDefinition, StorageOperationStatus> updatePolicyType(PolicyTypeDefinition updatedPolicyType,
93 PolicyTypeDefinition currPolicyType) {
94 log.debug("updating policy type {}", updatedPolicyType.getType());
95 return updatePolicyTypeOnGraph(updatedPolicyType, currPolicyType);
99 public List<PolicyTypeDefinition> getAllPolicyTypes(Set<String> excludedPolicyTypes) {
100 Map<String, Map.Entry<JanusGraphPredicate, Object>> predicateCriteria = buildNotInPredicate(GraphPropertiesDictionary.TYPE.getProperty(),
101 excludedPolicyTypes);
102 return janusGraphGenericDao.getByCriteriaWithPredicate(NodeTypeEnum.PolicyType, predicateCriteria, PolicyTypeData.class).left()
103 .map(this::convertPolicyTypesToDefinition).left().on(operationUtils::onJanusGraphOperationFailure);
106 private List<PolicyTypeDefinition> convertPolicyTypesToDefinition(List<PolicyTypeData> policiesTypes) {
107 return policiesTypes.stream().map(type -> new PolicyTypeDefinition(type.getPolicyTypeDataDefinition())).collect(Collectors.toList());
110 private Either<PolicyTypeData, StorageOperationStatus> addPolicyTypeToGraph(PolicyTypeDefinition policyTypeDef) {
111 log.debug("Got policy type {}", policyTypeDef);
112 String ptUniqueId = UniqueIdBuilder.buildPolicyTypeUid(policyTypeDef.getType(), policyTypeDef.getVersion(), "policytype");
113 PolicyTypeData policyTypeData = buildPolicyTypeData(policyTypeDef, ptUniqueId);
114 log.debug("Before adding policy type to graph. policyTypeData = {}", policyTypeData);
115 Either<PolicyTypeData, JanusGraphOperationStatus> eitherPolicyTypeData = janusGraphGenericDao
116 .createNode(policyTypeData, PolicyTypeData.class);
117 log.debug("After adding policy type to graph. status is = {}", eitherPolicyTypeData);
118 if (eitherPolicyTypeData.isRight()) {
119 JanusGraphOperationStatus operationStatus = eitherPolicyTypeData.right().value();
120 log.error("Failed to add policy type {} to graph. status is {}", policyTypeDef.getType(), operationStatus);
121 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(operationStatus));
123 List<PropertyDefinition> properties = policyTypeDef.getProperties();
124 Either<Map<String, PropertyData>, JanusGraphOperationStatus> addPropertiesToPolicyType = propertyOperation
125 .addPropertiesToElementType(ptUniqueId, NodeTypeEnum.PolicyType, properties);
126 if (addPropertiesToPolicyType.isRight()) {
127 log.error("Failed add properties {} to policy {}", properties, policyTypeDef.getType());
128 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(addPropertiesToPolicyType.right().value()));
130 return addDerivedFromRelation(policyTypeDef, ptUniqueId).left().map(updatedDerivedFrom -> eitherPolicyTypeData.left().value());
133 private Either<PolicyTypeDefinition, StorageOperationStatus> getPolicyTypeByCriteria(String type, Map<String, Object> properties) {
134 Either<PolicyTypeDefinition, StorageOperationStatus> result;
135 if (type == null || type.isEmpty()) {
136 log.error("type is empty");
137 result = Either.right(StorageOperationStatus.INVALID_ID);
140 Either<List<PolicyTypeData>, JanusGraphOperationStatus> eitherPolicyData = janusGraphGenericDao
141 .getByCriteria(NodeTypeEnum.PolicyType, properties, PolicyTypeData.class);
142 if (eitherPolicyData.isRight()) {
143 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(eitherPolicyData.right().value()));
145 PolicyTypeDataDefinition dataDefinition = eitherPolicyData.left().value().stream().map(PolicyTypeData::getPolicyTypeDataDefinition)
147 result = getPolicyTypeByUid(dataDefinition.getUniqueId());
152 private Either<PolicyTypeDefinition, StorageOperationStatus> getPolicyTypeByUid(String uniqueId) {
153 log.debug("#getPolicyTypeByUid - fetching policy type with id {}", uniqueId);
154 return janusGraphGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PolicyType), uniqueId, PolicyTypeData.class).right()
155 .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus).left()
156 .bind(policyType -> createPolicyTypeDefinition(uniqueId, policyType));
159 private Either<PolicyTypeDefinition, StorageOperationStatus> createPolicyTypeDefinition(String uniqueId, PolicyTypeData policyTypeNode) {
160 PolicyTypeDefinition policyType = new PolicyTypeDefinition(policyTypeNode.getPolicyTypeDataDefinition());
161 return fillDerivedFrom(uniqueId, policyType).left().map(derivedFrom -> fillProperties(uniqueId, policyType, derivedFrom)).left()
162 .map(props -> policyType);
165 private Either<List<PropertyDefinition>, StorageOperationStatus> fillProperties(String uniqueId, PolicyTypeDefinition policyType,
166 PolicyTypeData derivedFromNode) {
167 log.debug("#fillProperties - fetching all properties for policy type {}", policyType.getType());
168 return propertyOperation.findPropertiesOfNode(NodeTypeEnum.PolicyType, uniqueId).right().bind(this::handlePolicyTypeHasNoProperties).left()
169 .bind(propsMap -> fillDerivedFromProperties(policyType, derivedFromNode, new ArrayList<>(propsMap.values())));
172 private Either<List<PropertyDefinition>, StorageOperationStatus> fillDerivedFromProperties(PolicyTypeDefinition policyType,
173 PolicyTypeData derivedFromNode,
174 List<PropertyDefinition> policyTypeDirectProperties) {
175 if (derivedFromNode == null) {
176 policyType.setProperties(policyTypeDirectProperties);
177 return Either.left(policyTypeDirectProperties);
179 log.debug("#fillDerivedFromProperties - fetching all properties of derived from chain for policy type {}", policyType.getType());
180 return propertyOperation.getAllPropertiesRec(derivedFromNode.getUniqueId(), NodeTypeEnum.PolicyType, PolicyTypeData.class).left()
181 .map(derivedFromProps -> {
182 policyTypeDirectProperties.addAll(derivedFromProps);
183 return policyTypeDirectProperties;
184 }).left().map(allProps -> {
185 policyType.setProperties(allProps);
190 private Either<PolicyTypeData, StorageOperationStatus> fillDerivedFrom(String uniqueId, PolicyTypeDefinition policyType) {
191 log.debug("#fillDerivedFrom - fetching policy type {} derived node", policyType.getType());
192 return derivedFromOperation.getDerivedFromChild(uniqueId, NodeTypeEnum.PolicyType, PolicyTypeData.class).right()
193 .bind(this::handleDerivedFromNotExist).left().map(derivedFrom -> setDerivedFrom(policyType, derivedFrom));
196 private Either<PolicyTypeData, StorageOperationStatus> handleDerivedFromNotExist(StorageOperationStatus err) {
197 if (err == StorageOperationStatus.NOT_FOUND) {
198 return Either.left(null);
200 return Either.right(err);
203 Either<Map<String, PropertyDefinition>, StorageOperationStatus> handlePolicyTypeHasNoProperties(JanusGraphOperationStatus err) {
204 if (err == JanusGraphOperationStatus.NOT_FOUND) {
205 return Either.left(new HashMap<>());
207 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(err));
210 private PolicyTypeData setDerivedFrom(PolicyTypeDefinition policyTypeDefinition, PolicyTypeData derivedFrom) {
211 if (derivedFrom != null) {
212 policyTypeDefinition.setDerivedFrom(derivedFrom.getPolicyTypeDataDefinition().getType());
217 private PolicyTypeData buildPolicyTypeData(PolicyTypeDefinition policyTypeDefinition, String ptUniqueId) {
218 PolicyTypeData policyTypeData = new PolicyTypeData(policyTypeDefinition);
219 policyTypeData.getPolicyTypeDataDefinition().setUniqueId(ptUniqueId);
220 Long creationDate = policyTypeData.getPolicyTypeDataDefinition().getCreationTime();
221 if (creationDate == null) {
222 creationDate = System.currentTimeMillis();
224 policyTypeData.getPolicyTypeDataDefinition().setCreationTime(creationDate);
225 policyTypeData.getPolicyTypeDataDefinition().setModificationTime(creationDate);
226 return policyTypeData;
229 private Either<PolicyTypeDefinition, StorageOperationStatus> updatePolicyTypeOnGraph(PolicyTypeDefinition updatedPolicyType,
230 PolicyTypeDefinition currPolicyType) {
231 updatePolicyTypeData(updatedPolicyType, currPolicyType);
232 return janusGraphGenericDao.updateNode(new PolicyTypeData(updatedPolicyType), PolicyTypeData.class).right()
233 .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus).left()
234 .bind(updatedNode -> updatePolicyProperties(updatedPolicyType.getUniqueId(), updatedPolicyType.getProperties())).left()
235 .bind(updatedProperties -> updatePolicyDerivedFrom(updatedPolicyType, currPolicyType.getDerivedFrom())).left()
236 .map(updatedDerivedFrom -> updatedPolicyType);
239 private Either<Map<String, PropertyData>, StorageOperationStatus> updatePolicyProperties(String policyId, List<PropertyDefinition> properties) {
240 log.debug("#updatePolicyProperties - updating policy type properties for policy type with id {}", policyId);
241 return propertyOperation.deletePropertiesAssociatedToNode(NodeTypeEnum.PolicyType, policyId).left()
242 .bind(deleteProps -> addPropertiesToPolicy(policyId, properties));
245 private Either<GraphRelation, StorageOperationStatus> updatePolicyDerivedFrom(PolicyTypeDefinition updatedPolicyType,
246 String currDerivedFromPolicyType) {
247 String policyTypeId = updatedPolicyType.getUniqueId();
249 "#updatePolicyDerivedFrom - updating policy derived from relation for policy type with id {}. old derived type {}. new derived type {}",
250 policyTypeId, currDerivedFromPolicyType, updatedPolicyType.getDerivedFrom());
251 StorageOperationStatus deleteDerivedRelationStatus = deleteDerivedFromPolicyType(policyTypeId, currDerivedFromPolicyType);
252 if (deleteDerivedRelationStatus != StorageOperationStatus.OK) {
253 return Either.right(deleteDerivedRelationStatus);
255 return addDerivedFromRelation(updatedPolicyType, policyTypeId);
258 private Either<GraphRelation, StorageOperationStatus> addDerivedFromRelation(PolicyTypeDataDefinition policyTypeDef, String ptUniqueId) {
259 String derivedFrom = policyTypeDef.getDerivedFrom();
260 if (derivedFrom == null) {
261 return Either.left(null);
263 log.debug("#addDerivedFromRelationBefore - adding derived from relation between policy type {} to its parent {}", policyTypeDef.getType(),
265 return this.getLatestPolicyTypeByType(derivedFrom).left().bind(
266 derivedFromPolicy -> derivedFromOperation.addDerivedFromRelation(ptUniqueId, derivedFromPolicy.getUniqueId(), NodeTypeEnum.PolicyType));
269 private StorageOperationStatus deleteDerivedFromPolicyType(String policyTypeId, String derivedFromType) {
270 if (derivedFromType == null) {
271 return StorageOperationStatus.OK;
273 log.debug("#deleteDerivedFromPolicyType - deleting derivedFrom relation for policy type with id {} and its derived type {}", policyTypeId,
275 return getLatestPolicyTypeByType(derivedFromType).either(
276 derivedFromNode -> derivedFromOperation.removeDerivedFromRelation(policyTypeId, derivedFromNode.getUniqueId(), NodeTypeEnum.PolicyType),
280 private Either<Map<String, PropertyData>, StorageOperationStatus> addPropertiesToPolicy(String policyTypeId,
281 List<PropertyDefinition> properties) {
282 log.debug("#addPropertiesToPolicy - adding policy type properties for policy type with id {}", policyTypeId);
283 return propertyOperation.addPropertiesToElementType(policyTypeId, NodeTypeEnum.PolicyType, properties).right()
284 .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
287 private void updatePolicyTypeData(PolicyTypeDefinition updatedTypeDefinition, PolicyTypeDefinition currTypeDefinition) {
288 updatedTypeDefinition.setUniqueId(currTypeDefinition.getUniqueId());
289 updatedTypeDefinition.setCreationTime(currTypeDefinition.getCreationTime());
290 updatedTypeDefinition.setModificationTime(System.currentTimeMillis());