Merge "Handle non transient policy deletion"
diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java
index 53cf62a..630be49 100644
--- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java
+++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java
@@ -126,7 +126,6 @@
return Mono.just(new ResponseEntity<>(toPolicyTypeIdsJson(types), HttpStatus.OK));
}
-
@Override
public Mono<ResponseEntity<PolicyInfo>> getPolicy(String policyId, final ServerWebExchange exchange)
throws EntityNotFoundException {
@@ -142,6 +141,7 @@
Policy policy = policies.getPolicy(policyId);
keepServiceAlive(policy.getOwnerServiceId());
+ logger.trace("Policy to be deleted: {}", policy.getId());
return authorization.doAccessControl(exchange.getRequest().getHeaders().toSingleValueMap(), policy, AccessType.WRITE)
.flatMap(x -> policy.getRic().getLock().lock(Lock.LockType.SHARED, "deletePolicy"))
.flatMap(grant -> deletePolicy(grant, policy))
@@ -162,13 +162,11 @@
public Mono<ResponseEntity<Object>> putPolicy(final Mono<PolicyInfo> policyInfo, final ServerWebExchange exchange) {
return policyInfo.flatMap(policyInfoValue -> {
- String jsonString = gson.toJson(policyInfoValue.getPolicyData());
- return Mono.zip(
- Mono.justOrEmpty(rics.get(policyInfoValue.getRicId()))
+ String jsonString = gson.toJson(policyInfoValue.getPolicyData());
+ return Mono.zip(Mono.justOrEmpty(rics.get(policyInfoValue.getRicId()))
.switchIfEmpty(Mono.error(new EntityNotFoundException("Near-RT RIC not found"))),
Mono.justOrEmpty(policyTypes.get(policyInfoValue.getPolicytypeId()))
- .switchIfEmpty(Mono.error(new EntityNotFoundException("policy type not found")))
- )
+ .switchIfEmpty(Mono.error(new EntityNotFoundException("policy type not found"))))
.flatMap(tuple -> {
Ric ric = tuple.getT1();
PolicyType type = tuple.getT2();
@@ -187,13 +185,10 @@
return authorization.doAccessControl(exchange.getRequest().getHeaders().toSingleValueMap(), policy, AccessType.WRITE)
.flatMap(x -> ric.getLock().lock(Lock.LockType.SHARED, "putPolicy"))
.flatMap(grant -> putPolicy(grant, policy));
- })
- .onErrorResume(this::handleException);
+ }).onErrorResume(this::handleException);
});
}
-
-
private Mono<ResponseEntity<Object>> putPolicy(Lock.Grant grant, Policy policy) {
final boolean isCreate = this.policies.get(policy.getId()) == null;
final Ric ric = policy.getRic();
@@ -328,32 +323,31 @@
}
private PolicyInfo toPolicyInfo(Policy policy) {
- try {
- PolicyInfo policyInfo = new PolicyInfo()
- .policyId(policy.getId())
- .policyData(objectMapper.readTree(policy.getJson()))
- .ricId(policy.getRic().id())
- .policytypeId(policy.getType().getId())
- .serviceId(policy.getOwnerServiceId())
- ._transient(policy.isTransient());
- if (!policy.getStatusNotificationUri().isEmpty()) {
- policyInfo.setStatusNotificationUri(policy.getStatusNotificationUri());
- }
- return policyInfo;
- } catch (JsonProcessingException ex) {
- throw new RuntimeException(ex);
- }
+ try {
+ PolicyInfo policyInfo = new PolicyInfo()
+ .policyId(policy.getId())
+ .policyData(objectMapper.readTree(policy.getJson()))
+ .ricId(policy.getRic().id())
+ .policytypeId(policy.getType().getId())
+ .serviceId(policy.getOwnerServiceId())
+ ._transient(policy.isTransient());
+ if (!policy.getStatusNotificationUri().isEmpty()) {
+ policyInfo.setStatusNotificationUri(policy.getStatusNotificationUri());
+ }
+ return policyInfo;
+ } catch (JsonProcessingException ex) {
+ throw new RuntimeException(ex);
+ }
}
private PolicyInfoList policiesToJson(Collection<Policy> policies) {
-
- List<PolicyInfo> policiesList = new ArrayList<>(policies.size());
- PolicyInfoList policyInfoList = new PolicyInfoList();
- for (Policy policy : policies) {
- policiesList.add(toPolicyInfo(policy));
- }
- policyInfoList.setPolicies(policiesList);
- return policyInfoList;
+ List<PolicyInfo> policiesList = new ArrayList<>(policies.size());
+ PolicyInfoList policyInfoList = new PolicyInfoList();
+ for (Policy policy : policies) {
+ policiesList.add(toPolicyInfo(policy));
+ }
+ policyInfoList.setPolicies(policiesList);
+ return policyInfoList;
}
private Object fromJson(String jsonStr) {
@@ -373,12 +367,12 @@
private PolicyIdList toPolicyIdsJson(Collection<Policy> policies) {
- List<String> policyIds = new ArrayList<>(policies.size());
- PolicyIdList idList = new PolicyIdList();
- for (Policy policy : policies) {
- policyIds.add(policy.getId());
- }
- idList.setPolicyIds(policyIds);
- return idList;
+ List<String> policyIds = new ArrayList<>(policies.size());
+ PolicyIdList idList = new PolicyIdList();
+ for (Policy policy : policies) {
+ policyIds.add(policy.getId());
+ }
+ idList.setPolicyIds(policyIds);
+ return idList;
}
}
diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceController.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceController.java
index 5c92b54..09dfe44 100644
--- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceController.java
+++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceController.java
@@ -20,9 +20,6 @@
package org.onap.ccsdk.oran.a1policymanagementservice.controllers.v2;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.onap.ccsdk.oran.a1policymanagementservice.controllers.api.v2.ServiceRegistryAndSupervisionApi;
import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException;
@@ -33,13 +30,17 @@
import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policy;
import org.onap.ccsdk.oran.a1policymanagementservice.repository.Service;
import org.onap.ccsdk.oran.a1policymanagementservice.repository.Services;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebExchange;
+
import reactor.core.publisher.Mono;
+import java.lang.invoke.MethodHandles;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
@@ -61,10 +62,10 @@
private final Services services;
private final Policies policies;
- @Autowired
- private ObjectMapper objectMapper;
+ private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- private static Gson gson = new GsonBuilder().create();
+ @Autowired
+ private PolicyController policyController;
ServiceController(Services services, Policies policies) {
this.services = services;
@@ -118,50 +119,66 @@
+ "Policies can be created even if the service is not registerred. This is a feature which it is optional to use.";
@Override
- public Mono<ResponseEntity<Object>> putService(
- final Mono<ServiceRegistrationInfo> registrationInfo, final ServerWebExchange exchange) {
- return registrationInfo.flatMap(info -> {
- try {
- validateRegistrationInfo(info);
- } catch(Exception e) {
- return ErrorResponse.createMono(e, HttpStatus.BAD_REQUEST);
- }
- final boolean isCreate = this.services.get(info.getServiceId()) == null;
- this.services.put(toService(info));
- return Mono.just(new ResponseEntity<>(isCreate ? HttpStatus.CREATED : HttpStatus.OK));
- }).onErrorResume(Exception.class, e -> ErrorResponse.createMono(e, HttpStatus.BAD_REQUEST));
+ public Mono<ResponseEntity<Object>> putService(final Mono<ServiceRegistrationInfo> registrationInfo, final ServerWebExchange exchange) {
+ return registrationInfo.flatMap(info -> {
+ try {
+ validateRegistrationInfo(info);
+ } catch (Exception e) {
+ return ErrorResponse.createMono(e, HttpStatus.BAD_REQUEST);
+ }
+ final boolean isCreate = this.services.get(info.getServiceId()) == null;
+ this.services.put(toService(info));
+ return Mono.just(new ResponseEntity<>(isCreate ? HttpStatus.CREATED : HttpStatus.OK));
+ }).onErrorResume(Exception.class, e -> ErrorResponse.createMono(e, HttpStatus.BAD_REQUEST));
}
@Override
public Mono<ResponseEntity<Object>> deleteService(final String serviceId, final ServerWebExchange exchange) {
try {
Service service = removeService(serviceId);
- // Remove the policies from the repo and let the consistency monitoring
- // do the rest.
- removePolicies(service);
+ removePolicies(service, exchange);
return Mono.just(new ResponseEntity<>(HttpStatus.NO_CONTENT));
- } catch (ServiceException e) {
+ } catch (ServiceException | NullPointerException e) {
+ logger.warn("Exception caught during service deletion while deleting service {}: {}", serviceId,
+ e.getMessage());
return ErrorResponse.createMono(e, HttpStatus.NOT_FOUND);
}
}
@Override
public Mono<ResponseEntity<Object>> keepAliveService(final String serviceId, final ServerWebExchange exchange) throws ServiceException {
-
- services.getService(serviceId).keepAlive();
- return Mono.just(new ResponseEntity<>(HttpStatus.OK));
+ services.getService(serviceId).keepAlive();
+ return Mono.just(new ResponseEntity<>(HttpStatus.OK));
}
private Service removeService(String name) throws ServiceException {
Service service = this.services.getService(name); // Just to verify that it exists
+ logger.trace("Service name to be deleted: {}", service.getName());
this.services.remove(service.getName());
return service;
}
- private void removePolicies(Service service) {
+ private void removePolicies(Service service, ServerWebExchange exchange) {
Collection<Policy> policyList = this.policies.getForService(service.getName());
+ logger.trace("Policies to be deleted: {}", policyList);
for (Policy policy : policyList) {
- this.policies.remove(policy);
+ try {
+ policyController.deletePolicy(policy.getId(), exchange).doOnNext(resp -> {
+ if (resp.getStatusCode().is2xxSuccessful()) {
+ logger.trace("Deleting Policy '{}' when deleting Service '{}'", policy.getId(),
+ service.getName());
+ } else {
+ logger.warn("Possible problem deleting Policy '{}' when deleting Service '{}'. Continuing, "
+ + "but might trigger a re-sync with affected ric '{}'. Repsonse: \"{}\"",
+ policy.getId(), service.getName(), policy.getRic().getConfig().getRicId(),
+ resp.toString());
+ }
+ }).subscribe();
+ } catch (Exception e) {
+ logger.warn("Problem deleting Policy '{}' when deleting Service '{}'."
+ + " Continuing, but might trigger a re-sync with affected ric '{}'. Problem: \"{}\"",
+ policy.getId(), service.getName(), policy.getRic().getConfig().getRicId(), e.getMessage());
+ }
}
}
diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java
index f11e30f..ed6139e 100644
--- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java
+++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java
@@ -166,6 +166,7 @@
}
private Mono<RicData> validateInstances(Collection<String> ricPolicies, RicData ric) {
+ logger.trace("Policies to be validated: {} , against: {} , in ric: {}", ricPolicies, ric.ric.getManagedElementIds(), ric.ric.id());
synchronized (this.policies) {
if (ricPolicies.size() != policies.getForRic(ric.ric.id()).size()) {
logger.debug("RicSupervision, starting ric: {} synchronization (noOfPolicices == {}, expected == {})",