2 * ========================LICENSE_START=================================
4 * ======================================================================
5 * Copyright (C) 2024 OpenInfra Foundation Europe. 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.onap.ccsdk.oran.a1policymanagementservice.service.v3;
23 import com.google.gson.Gson;
24 import lombok.RequiredArgsConstructor;
25 import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory;
26 import org.onap.ccsdk.oran.a1policymanagementservice.controllers.authorization.PolicyAuthorizationRequest.Input.AccessType;
27 import org.onap.ccsdk.oran.a1policymanagementservice.controllers.v2.Consts;
28 import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.EntityNotFoundException;
29 import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException;
30 import org.onap.ccsdk.oran.a1policymanagementservice.models.v3.PolicyInformation;
31 import org.onap.ccsdk.oran.a1policymanagementservice.models.v3.PolicyObjectInformation;
32 import org.onap.ccsdk.oran.a1policymanagementservice.models.v3.PolicyTypeInformation;
33 import org.onap.ccsdk.oran.a1policymanagementservice.repository.*;
34 import org.onap.ccsdk.oran.a1policymanagementservice.util.v3.Helper;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37 import org.springframework.http.HttpStatus;
38 import org.springframework.http.ResponseEntity;
39 import org.springframework.stereotype.Service;
40 import org.springframework.web.server.ServerWebExchange;
41 import reactor.core.publisher.Flux;
42 import reactor.core.publisher.Mono;
44 import java.lang.invoke.MethodHandles;
45 import java.util.ArrayList;
46 import java.util.Collection;
50 @RequiredArgsConstructor
51 public class PolicyService {
53 private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
54 private final Helper helper;
55 private final Rics rics;
56 private final PolicyTypes policyTypes;
57 private final Policies policies;
58 private final AuthorizationService authorizationService;
59 private final A1ClientFactory a1ClientFactory;
60 private final ErrorHandlingService errorHandlingService;
61 private final Gson gson;
63 public Mono<ResponseEntity<PolicyObjectInformation>> createPolicyService
64 (PolicyObjectInformation policyObjectInfo, ServerWebExchange serverWebExchange) {
66 if (Boolean.FALSE.equals(helper.jsonSchemaValidation(gson.toJson(policyObjectInfo.getPolicyObject(), Map.class))))
67 return Mono.error(new ServiceException("Schema validation failed", HttpStatus.BAD_REQUEST));
68 Ric ric = rics.getRic(policyObjectInfo.getNearRtRicId());
69 PolicyType policyType = policyTypes.getType(policyObjectInfo.getPolicyTypeId());
70 Policy policy = helper.buildPolicy(policyObjectInfo, policyType, ric, helper.policyIdGeneration(policyObjectInfo));
71 return helper.isPolicyAlreadyCreated(policy,policies)
72 .doOnError(errorHandlingService::handleError)
73 .flatMap(policyBuilt -> authorizationService.authCheck(serverWebExchange, policy, AccessType.WRITE)
74 .doOnError(errorHandlingService::handleError)
75 .flatMap(policyNotUsed -> ric.getLock().lock(Lock.LockType.SHARED, "createPolicy"))
76 .flatMap(grant -> postPolicy(policy, grant))
77 .map(locationHeaderValue ->
78 new ResponseEntity<PolicyObjectInformation>(policyObjectInfo,helper.createHttpHeaders(
79 "location",helper.buildURI(policy.getId(), serverWebExchange)), HttpStatus.CREATED))
80 .doOnError(errorHandlingService::handleError));
81 } catch (Exception ex) {
82 return Mono.error(ex);
87 private Mono<String> postPolicy(Policy policy, Lock.Grant grant) {
88 return helper.checkRicStateIdle(policy.getRic())
89 .doOnError(errorHandlingService::handleError)
90 .flatMap(ric -> helper.checkSupportedType(ric, policy.getType()))
91 .doOnError(errorHandlingService::handleError)
92 .flatMap(a1ClientFactory::createA1Client)
93 .flatMap(a1Client -> a1Client.putPolicy(policy))
94 .doOnError(errorHandlingService::handleError)
95 .doOnNext(policyString -> policies.put(policy))
96 .doFinally(releaseLock -> grant.unlockBlocking())
97 .doOnError(errorHandlingService::handleError);
100 public Mono<ResponseEntity<Object>> putPolicyService(String policyId, Object body, ServerWebExchange exchange) {
102 Policy existingPolicy = policies.getPolicy(policyId);
103 PolicyObjectInformation pos =
104 new PolicyObjectInformation(existingPolicy.getRic().getConfig().getRicId(), body, existingPolicy.getType().getId());
105 Policy updatedPolicy = helper.buildPolicy(pos, existingPolicy.getType(), existingPolicy.getRic(), policyId);
106 Ric ric = existingPolicy.getRic();
107 return authorizationService.authCheck(exchange, updatedPolicy, AccessType.WRITE)
108 .doOnError(errorHandlingService::handleError)
109 .flatMap(policy -> ric.getLock().lock(Lock.LockType.SHARED, "updatePolicy"))
110 .doOnError(errorHandlingService::handleError)
111 .flatMap(grant -> postPolicy(updatedPolicy, grant))
112 .map(header -> new ResponseEntity<Object>(policies.get(updatedPolicy.getId()).getJson(), HttpStatus.OK))
113 .doOnError(errorHandlingService::handleError);
114 } catch(Exception ex) {
115 return Mono.error(ex);
119 public Mono<ResponseEntity<Flux<PolicyTypeInformation>>> getPolicyTypesService(String nearRtRicId, String typeName,
120 String compatibleWithVersion) throws ServiceException {
121 if (compatibleWithVersion != null && typeName == null) {
122 throw new ServiceException("Parameter " + Consts.COMPATIBLE_WITH_VERSION_PARAM + " can only be used when "
123 + Consts.TYPE_NAME_PARAM + " is given", HttpStatus.BAD_REQUEST);
125 Collection<PolicyTypeInformation> listOfPolicyTypes = new ArrayList<>();
126 if (nearRtRicId == null || nearRtRicId.isEmpty() || nearRtRicId.isBlank()) {
127 for(Ric ric : rics.getRics()) {
128 Collection<PolicyType> filteredPolicyTypes = PolicyTypes.filterTypes(ric.getSupportedPolicyTypes(), typeName,
129 compatibleWithVersion);
130 listOfPolicyTypes.addAll(helper.toPolicyTypeInfoCollection(filteredPolicyTypes, ric));
133 Ric ric = rics.get(nearRtRicId);
135 throw new EntityNotFoundException("Near-RT RIC not Found using ID: " +nearRtRicId);
136 Collection<PolicyType> filteredPolicyTypes = PolicyTypes.filterTypes(ric.getSupportedPolicyTypes(), typeName,
137 compatibleWithVersion);
138 listOfPolicyTypes.addAll(helper.toPolicyTypeInfoCollection(filteredPolicyTypes, ric));
140 return Mono.just(new ResponseEntity<>(Flux.fromIterable(listOfPolicyTypes), HttpStatus.OK));
143 public Mono<ResponseEntity<Flux<PolicyInformation>>> getPolicyIdsService(String policyTypeId, String nearRtRicId,
144 String serviceId, String typeName,
145 ServerWebExchange exchange) throws EntityNotFoundException {
146 if ((policyTypeId != null && this.policyTypes.get(policyTypeId) == null))
147 throw new EntityNotFoundException("Policy type not found using ID: " +policyTypeId);
148 if ((nearRtRicId != null && this.rics.get(nearRtRicId) == null))
149 throw new EntityNotFoundException("Near-RT RIC not found using ID: " +nearRtRicId);
151 Collection<Policy> filtered = policies.filterPolicies(policyTypeId, nearRtRicId, serviceId, typeName);
152 return Flux.fromIterable(filtered)
153 .flatMap(policy -> authorizationService.authCheck(exchange, policy, AccessType.READ))
154 .onErrorContinue((error,item) -> logger.warn("Error occurred during authorization check for " +
155 "policy {}: {}", item, error.getMessage()))
157 .map(authPolicies -> new ResponseEntity<>(helper.toFluxPolicyInformation(authPolicies), HttpStatus.OK))
158 .doOnError(error -> logger.error(error.getMessage()));
161 public Mono<ResponseEntity<Object>> getPolicyService(String policyId, ServerWebExchange serverWebExchange)
162 throws EntityNotFoundException{
163 Policy policy = policies.getPolicy(policyId);
164 return authorizationService.authCheck(serverWebExchange, policy, AccessType.READ)
165 .map(x -> new ResponseEntity<Object>(policy.getJson(), HttpStatus.OK))
166 .doOnError(errorHandlingService::handleError);
169 public Mono<ResponseEntity<Object>> getPolicyTypeDefinitionService(String policyTypeId)
170 throws EntityNotFoundException{
171 PolicyType singlePolicyType = policyTypes.get(policyTypeId);
172 if (singlePolicyType == null)
173 throw new EntityNotFoundException("PolicyType not found with ID: " + policyTypeId);
174 return Mono.just(new ResponseEntity<Object>(singlePolicyType.getSchema(), HttpStatus.OK));
177 public Mono<ResponseEntity<Void>> deletePolicyService(String policyId, ServerWebExchange serverWebExchange)
178 throws EntityNotFoundException {
179 Policy singlePolicy = policies.getPolicy(policyId);
180 return authorizationService.authCheck(serverWebExchange, singlePolicy, AccessType.WRITE)
181 .doOnError(errorHandlingService::handleError)
182 .flatMap(policy -> policy.getRic().getLock().lock(Lock.LockType.SHARED, "deletePolicy"))
183 .flatMap(grant -> deletePolicy(singlePolicy, grant))
184 .doOnError(errorHandlingService::handleError);
187 private Mono<ResponseEntity<Void>> deletePolicy(Policy policy, Lock.Grant grant) {
188 return helper.checkRicStateIdle(policy.getRic())
189 .doOnError(errorHandlingService::handleError)
190 .flatMap(ric -> helper.checkSupportedType(ric, policy.getType()))
191 .doOnError(errorHandlingService::handleError)
192 .flatMap(a1ClientFactory::createA1Client)
193 .doOnError(errorHandlingService::handleError)
194 .flatMap(a1Client -> a1Client.deletePolicy(policy))
195 .doOnError(errorHandlingService::handleError)
196 .doOnNext(policyString -> policies.remove(policy))
197 .doFinally(releaseLock -> grant.unlockBlocking())
198 .map(successResponse -> new ResponseEntity<Void>(HttpStatus.NO_CONTENT))
199 .doOnError(errorHandlingService::handleError);