From 7a4a590fb0ebf8772169625cdda327da43c79c6d Mon Sep 17 00:00:00 2001 From: PatrikBuhr Date: Tue, 14 Jan 2020 09:00:57 +0100 Subject: [PATCH] Added callback to R-APPS invoked after RIC recovery Improved error handling in dashboard Improved error handling in agent NBI Added ?policyTypeId= in the A1 API Added a callback to R-APPS invoked when RIC instances has been deleted or when RIC policy types has changed. Issue-ID: NONRTRIC-84 Change-Id: I04a4b514fce45e249364bd03813a7afb93320a07 Signed-off-by: PatrikBuhr --- .../dashboard/controller/PolicyController.java | 31 +++-- .../dashboard/policyagentapi/PolicyAgentApi.java | 11 +- .../policyagentapi/PolicyAgentApiImpl.java | 42 ++++--- .../config/PolicyControllerMockConfiguration.java | 23 ++-- .../org/oransc/policyagent/clients/A1Client.java | 3 +- .../oransc/policyagent/clients/A1ClientImpl.java | 17 ++- .../policyagent/controllers/PolicyController.java | 2 +- .../policyagent/controllers/ServiceController.java | 2 +- .../controllers/ServiceRegistrationInfo.java | 2 + .../org/oransc/policyagent/repository/Service.java | 9 +- .../oransc/policyagent/repository/Services.java | 3 + .../policyagent/tasks/RepositorySupervision.java | 12 +- .../oransc/policyagent/tasks/RicRecoveryTask.java | 26 +++- .../oransc/policyagent/tasks/StartupService.java | 10 +- .../org/oransc/policyagent/ApplicationTest.java | 49 +------- .../org/oransc/policyagent/MockPolicyAgent.java | 131 ++++----------------- .../policyagent/clients/A1ClientImplTest.java | 46 ++++++-- .../tasks/RepositorySupervisionTest.java | 5 +- .../policyagent/tasks/StartupServiceTest.java | 7 +- .../org/oransc/policyagent/utils/MockA1Client.java | 92 +++++++++++++++ .../policy_types/demo-policy-schema-1.json | 85 ++++++++----- .../policy_types/demo-policy-schema-3.json | 58 ++------- .../resources/test_application_configuration.json | 10 +- 23 files changed, 377 insertions(+), 299 deletions(-) create mode 100644 policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java diff --git a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/PolicyController.java b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/PolicyController.java index 410ad1df..529cd2af 100644 --- a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/PolicyController.java +++ b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/PolicyController.java @@ -41,6 +41,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.security.access.annotation.Secured; import org.springframework.util.Assert; import org.springframework.web.bind.annotation.DeleteMapping; @@ -96,7 +97,7 @@ public class PolicyController { @ApiOperation(value = "Gets the policy types from Near Realtime-RIC") @GetMapping(POLICY_TYPES_METHOD) @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public PolicyTypes getAllPolicyTypes(HttpServletResponse response) { + public ResponseEntity getAllPolicyTypes(HttpServletResponse response) { logger.debug("getAllPolicyTypes"); return this.policyAgentApi.getAllPolicyTypes(); } @@ -104,19 +105,22 @@ public class PolicyController { @ApiOperation(value = "Returns the policy instances for the given policy type.") @GetMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME) @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public String getPolicyInstances(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString) { + public ResponseEntity getPolicyInstances(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString) { logger.debug("getPolicyInstances {}", policyTypeIdString); - PolicyInstances i = this.policyAgentApi.getPolicyInstancesForType(policyTypeIdString); - String json = gson.toJson(i); - return json; + ResponseEntity response = this.policyAgentApi.getPolicyInstancesForType(policyTypeIdString); + if (!response.getStatusCode().is2xxSuccessful()) { + return new ResponseEntity<>(response.getStatusCode()); + } + String json = gson.toJson(response.getBody()); + return new ResponseEntity<>(json, response.getStatusCode()); } @ApiOperation(value = "Returns a policy instance of a type") @GetMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{" + POLICY_INSTANCE_ID_NAME + "}") @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public String getPolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString, + public ResponseEntity getPolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString, @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId) { logger.debug("getPolicyInstance {}:{}", policyTypeIdString, policyInstanceId); return this.policyAgentApi.getPolicyInstance(policyInstanceId); @@ -126,12 +130,12 @@ public class PolicyController { @PutMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{" + POLICY_INSTANCE_ID_NAME + "}") @Secured({ DashboardConstants.ROLE_ADMIN }) - public void putPolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString, + public ResponseEntity putPolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString, @RequestParam(name = "ric", required = true) String ric, @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId, @RequestBody String instance) { logger.debug("putPolicyInstance typeId: {}, instanceId: {}, instance: {}", policyTypeIdString, policyInstanceId, instance); - this.policyAgentApi.putPolicy(policyTypeIdString, policyInstanceId, instance, ric); + return this.policyAgentApi.putPolicy(policyTypeIdString, policyInstanceId, instance, ric); } @ApiOperation(value = "Deletes the policy instances for the given policy type.") @@ -164,13 +168,16 @@ public class PolicyController { @ApiOperation(value = "Returns the rics supporting the given policy type.") @GetMapping("/rics") @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public String getRicsSupportingType( + public ResponseEntity getRicsSupportingType( @RequestParam(name = "policyType", required = true) String supportingPolicyType) { logger.debug("getRicsSupportingType {}", supportingPolicyType); - Collection result = this.policyAgentApi.getRicsSupportingType(supportingPolicyType); - String json = gson.toJson(result); - return json; + ResponseEntity> result = this.policyAgentApi.getRicsSupportingType(supportingPolicyType); + if (!result.getStatusCode().is2xxSuccessful()) { + return new ResponseEntity<>(result.getStatusCode()); + } + String json = gson.toJson(result.getBody()); + return new ResponseEntity<>(json, result.getStatusCode()); } }; diff --git a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApi.java b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApi.java index 144a77a2..47add76a 100644 --- a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApi.java +++ b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApi.java @@ -23,21 +23,22 @@ import java.util.Collection; import org.oransc.ric.portal.dashboard.model.PolicyInstances; import org.oransc.ric.portal.dashboard.model.PolicyTypes; +import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestClientException; public interface PolicyAgentApi { - public PolicyTypes getAllPolicyTypes() throws RestClientException; + public ResponseEntity getAllPolicyTypes() throws RestClientException; - public PolicyInstances getPolicyInstancesForType(String type); + public ResponseEntity getPolicyInstancesForType(String type); - public String getPolicyInstance(String id) throws RestClientException; + public ResponseEntity getPolicyInstance(String id) throws RestClientException; - public void putPolicy(String policyTypeIdString, String policyInstanceId, String json, String ric) + public ResponseEntity putPolicy(String policyTypeIdString, String policyInstanceId, String json, String ric) throws RestClientException; public void deletePolicy(String policyInstanceId) throws RestClientException; - public Collection getRicsSupportingType(String typeName); + public ResponseEntity> getRicsSupportingType(String typeName); } diff --git a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApiImpl.java b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApiImpl.java index d83023b7..eb3f8368 100644 --- a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApiImpl.java +++ b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApiImpl.java @@ -26,7 +26,8 @@ import org.oransc.ric.portal.dashboard.model.PolicyInstances; import org.oransc.ric.portal.dashboard.model.PolicyType; import org.oransc.ric.portal.dashboard.model.PolicyTypes; import org.springframework.beans.factory.annotation.Autowired; - +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; @@ -84,13 +85,16 @@ public class PolicyAgentApiImpl implements PolicyAgentApi { } @Override - public PolicyTypes getAllPolicyTypes() throws RestClientException { + public ResponseEntity getAllPolicyTypes() throws RestClientException { String url = baseUrl() + "/policy_schemas"; - String rsp = this.restTemplate.getForObject(url, String.class); + ResponseEntity rsp = this.restTemplate.getForEntity(url, String.class); + if (!rsp.getStatusCode().is2xxSuccessful()) { + return new ResponseEntity<>(rsp.getStatusCode()); + } PolicyTypes result = new PolicyTypes(); JsonParser jsonParser = new JsonParser(); - JsonArray schemas = jsonParser.parse(rsp).getAsJsonArray(); + JsonArray schemas = jsonParser.parse(rsp.getBody()).getAsJsonArray(); for (JsonElement schema : schemas) { JsonObject schemaObj = schema.getAsJsonObject(); String title = schemaObj.get("title").getAsString(); @@ -98,36 +102,39 @@ public class PolicyAgentApiImpl implements PolicyAgentApi { PolicyType pt = new PolicyType(title, schemaAsStr); result.add(pt); } - return result; + return new ResponseEntity<>(result, rsp.getStatusCode()); } @Override - public PolicyInstances getPolicyInstancesForType(String type) { + public ResponseEntity getPolicyInstancesForType(String type) { String url = baseUrl() + "/policies?type={type}"; Map uriVariables = Map.of("type", type); - String rsp = this.restTemplate.getForObject(url, String.class, uriVariables); + ResponseEntity rsp = this.restTemplate.getForEntity(url, String.class, uriVariables); + if (!rsp.getStatusCode().is2xxSuccessful()) { + return new ResponseEntity<>(rsp.getStatusCode()); + } Type listType = new TypeToken>() { }.getType(); - List rspParsed = gson.fromJson(rsp, listType); + List rspParsed = gson.fromJson(rsp.getBody(), listType); PolicyInstances result = new PolicyInstances(); for (PolicyInfo p : rspParsed) { result.add(p); } - return result; + return new ResponseEntity<>(result, rsp.getStatusCode()); } @Override - public String getPolicyInstance(String id) throws RestClientException { + public ResponseEntity getPolicyInstance(String id) throws RestClientException { String url = baseUrl() + "/policy?instance={id}"; Map uriVariables = Map.of("id", id); - return this.restTemplate.getForObject(url, String.class, uriVariables); + return this.restTemplate.getForEntity(url, String.class, uriVariables); } @Override - public void putPolicy(String policyTypeIdString, String policyInstanceId, String json, String ric) + public ResponseEntity putPolicy(String policyTypeIdString, String policyInstanceId, String json, String ric) throws RestClientException { String url = baseUrl() + "/policy?type={type}&instance={instance}&ric={ric}&service={service}"; Map uriVariables = Map.of( // @@ -136,7 +143,12 @@ public class PolicyAgentApiImpl implements PolicyAgentApi { "ric", ric, // "service", "dashboard"); - this.restTemplate.put(url, json, uriVariables); + try { + this.restTemplate.put(url, json, uriVariables); + return new ResponseEntity<>(HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND); + } } @Override @@ -157,7 +169,7 @@ public class PolicyAgentApiImpl implements PolicyAgentApi { } @Override - public Collection getRicsSupportingType(String typeName) { + public ResponseEntity> getRicsSupportingType(String typeName) { String url = baseUrl() + "/rics?policyType={typeName}"; Map uriVariables = Map.of("typeName", typeName); String rsp = this.restTemplate.getForObject(url, String.class, uriVariables); @@ -170,7 +182,7 @@ public class PolicyAgentApiImpl implements PolicyAgentApi { for (RicInfo ric : rspParsed) { result.add(ric.name()); } - return result; + return new ResponseEntity<>(result, HttpStatus.OK); } } diff --git a/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/PolicyControllerMockConfiguration.java b/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/PolicyControllerMockConfiguration.java index 44d0b5c9..e073ef66 100644 --- a/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/PolicyControllerMockConfiguration.java +++ b/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/PolicyControllerMockConfiguration.java @@ -42,6 +42,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestClientException; /** @@ -62,14 +64,15 @@ public class PolicyControllerMockConfiguration { private final Database database = new Database(); @Override - public String getPolicyInstance(String id) throws RestClientException { - return database.getInstance(id); + public ResponseEntity getPolicyInstance(String id) throws RestClientException { + return new ResponseEntity<>(database.getInstance(id), HttpStatus.OK); } @Override - public void putPolicy(String policyTypeIdString, String policyInstanceId, String json, String ric) - throws RestClientException { + public ResponseEntity putPolicy(String policyTypeIdString, String policyInstanceId, String json, + String ric) throws RestClientException { database.putInstance(policyTypeIdString, policyInstanceId, json, ric); + return new ResponseEntity<>(HttpStatus.OK); } @Override @@ -78,27 +81,27 @@ public class PolicyControllerMockConfiguration { } @Override - public PolicyTypes getAllPolicyTypes() throws RestClientException { + public ResponseEntity getAllPolicyTypes() throws RestClientException { PolicyTypes result = new PolicyTypes(); result.addAll(database.getTypes()); - return result; + return new ResponseEntity<>(result, HttpStatus.OK); } @Override - public PolicyInstances getPolicyInstancesForType(String type) { + public ResponseEntity getPolicyInstancesForType(String type) { PolicyInstances result = new PolicyInstances(); List inst = database.getInstances(Optional.of(type)); result.addAll(inst); - return result; + return new ResponseEntity<>(result, HttpStatus.OK); } @Override - public Collection getRicsSupportingType(String typeName) { + public ResponseEntity> getRicsSupportingType(String typeName) { Vector res = new Vector<>(); res.add("ric_1"); res.add("ric_2"); res.add("ric_3"); - return res; + return new ResponseEntity<>(res, HttpStatus.OK); } } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java index bc6d7cda..8d244ee3 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java @@ -22,6 +22,7 @@ package org.oransc.policyagent.clients; import java.util.Collection; +import org.oransc.policyagent.repository.Policy; import reactor.core.publisher.Mono; public interface A1Client { @@ -32,7 +33,7 @@ public interface A1Client { public Mono getPolicyType(String nearRtRicUrl, String policyTypeId); - public Mono putPolicy(String nearRtRicUrl, String policyId, String policyString); + public Mono putPolicy(Policy policy); public Mono deletePolicy(String nearRtRicUrl, String policyId); diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientImpl.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientImpl.java index b3773b8e..e5766385 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientImpl.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientImpl.java @@ -28,6 +28,7 @@ import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.oransc.policyagent.repository.Policy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import reactor.core.publisher.Mono; @@ -39,7 +40,7 @@ public class A1ClientImpl implements A1Client { return nearRtRicUrl + "/A1-P/v1"; } - public AsyncRestClient createClient(final String nearRtRicUrl) { + protected AsyncRestClient createClient(final String nearRtRicUrl) { return new AsyncRestClient(getBaseUrl(nearRtRicUrl)); } @@ -68,11 +69,15 @@ public class A1ClientImpl implements A1Client { } @Override - public Mono putPolicy(String nearRtRicUrl, String policyId, String policyString) { - logger.debug("putPolicy nearRtRicUrl = {}, policyId = {}, policyString = {}", nearRtRicUrl, policyId, - policyString); - AsyncRestClient client = createClient(nearRtRicUrl); - Mono response = client.put("/policies/" + policyId, policyString); + public Mono putPolicy(Policy policy) { + logger.debug("putPolicy nearRtRicUrl = {}, policyId = {}, policyString = {}", // + policy.ric().getConfig().baseUrl(), policy.id(), policy.json()); + AsyncRestClient client = createClient(policy.ric().getConfig().baseUrl()); + // TODO update when simulator is updated to include policy type + // Mono response = client.put("/policies/" + policy.id() + "?policyTypeId=" + policy.type().name(), + // policy.json()); + Mono response = client.put("/policies/" + policy.id(), policy.json()); + return response.flatMap(this::createMono); } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java index 6d849b1b..e33fb7e4 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java @@ -172,7 +172,7 @@ public class PolicyController { .ownerServiceName(service) // .lastModified(getTimeStampUTC()) // .build(); - return a1Client.putPolicy(policy.ric().getConfig().baseUrl(), policy.id(), policy.json()) // + return a1Client.putPolicy(policy) // .doOnNext(notUsed -> policies.put(policy)) // .flatMap(notUsed -> { return Mono.just(new ResponseEntity<>(HttpStatus.CREATED)); diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceController.java index 6831d4ca..ad062311 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceController.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceController.java @@ -86,7 +86,7 @@ public class ServiceController { } private Service toService(ServiceRegistrationInfo s) { - return new Service(s.name(), Duration.ofSeconds(s.keepAliveInterval())); + return new Service(s.name(), Duration.ofSeconds(s.keepAliveInterval()), s.callbackUrl()); } @GetMapping("/services") diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java index 2bc7e9b5..e0d38496 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java @@ -31,4 +31,6 @@ public interface ServiceRegistrationInfo { public long keepAliveInterval(); + public String callbackUrl(); + } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Service.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Service.java index 81ef7ff9..6458dbba 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Service.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/repository/Service.java @@ -27,11 +27,12 @@ public class Service { private final String name; private final Duration keepAliveInterval; private Instant lastPing; - // private final String callbackUrl1; // TBD + private final String callbackUrl; - public Service(String name, Duration keepAliveInterval) { + public Service(String name, Duration keepAliveInterval, String callbackUrl) { this.name = name; this.keepAliveInterval = keepAliveInterval; + this.callbackUrl = callbackUrl; ping(); } @@ -55,4 +56,8 @@ public class Service { return Duration.between(this.lastPing, Instant.now()); } + public synchronized String getCallbackUrl() { + return this.callbackUrl; + } + } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Services.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Services.java index 509b2f51..35cae717 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Services.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/repository/Services.java @@ -50,9 +50,12 @@ public class Services { public synchronized void put(Service service) { logger.debug("Put service: " + service.getName()); + // TODO a threading problem is that this may happend at the same time as someone is iterating (getAll()) + // This is a generic problem services.put(service.getName(), service); } + // TODO the returned value should be unmodifiable if possible public synchronized Collection getAll() { return services.values(); } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RepositorySupervision.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RepositorySupervision.java index 9ac9d705..bfd40e52 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RepositorySupervision.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RepositorySupervision.java @@ -27,6 +27,7 @@ import org.oransc.policyagent.repository.Policies; import org.oransc.policyagent.repository.PolicyTypes; import org.oransc.policyagent.repository.Ric; import org.oransc.policyagent.repository.Rics; +import org.oransc.policyagent.repository.Services; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -49,13 +50,16 @@ public class RepositorySupervision { private final Policies policies; private final PolicyTypes policyTypes; private final A1Client a1Client; + private final Services services; @Autowired - public RepositorySupervision(Rics rics, Policies policies, A1Client a1Client, PolicyTypes policyTypes) { + public RepositorySupervision(Rics rics, Policies policies, A1Client a1Client, PolicyTypes policyTypes, + Services services) { this.rics = rics; this.policies = policies; this.a1Client = a1Client; this.policyTypes = policyTypes; + this.services = services; } /** @@ -81,10 +85,6 @@ public class RepositorySupervision { .flatMap(ricP -> validateInstances(ricP, ric)); } - private Flux junk() { - return Flux.empty(); - } - private Mono validateInstances(Collection ricPolicies, Ric ric) { if (ricPolicies.size() != policies.getForRic(ric.name()).size()) { return startRecovery(ric); @@ -118,7 +118,7 @@ public class RepositorySupervision { } private Mono startRecovery(Ric ric) { - RicRecoveryTask recovery = new RicRecoveryTask(a1Client, policyTypes, policies); + RicRecoveryTask recovery = new RicRecoveryTask(a1Client, policyTypes, policies, services); recovery.run(ric); return Mono.empty(); } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicRecoveryTask.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicRecoveryTask.java index 3883585b..73c94e25 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicRecoveryTask.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicRecoveryTask.java @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.Vector; import org.oransc.policyagent.clients.A1Client; +import org.oransc.policyagent.clients.AsyncRestClient; import org.oransc.policyagent.exceptions.ServiceException; import org.oransc.policyagent.repository.ImmutablePolicyType; import org.oransc.policyagent.repository.Policies; @@ -31,6 +32,8 @@ import org.oransc.policyagent.repository.Policy; import org.oransc.policyagent.repository.PolicyType; import org.oransc.policyagent.repository.PolicyTypes; import org.oransc.policyagent.repository.Ric; +import org.oransc.policyagent.repository.Service; +import org.oransc.policyagent.repository.Services; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,11 +50,13 @@ public class RicRecoveryTask { private final A1Client a1Client; private final PolicyTypes policyTypes; private final Policies policies; + private final Services services; - public RicRecoveryTask(A1Client a1Client, PolicyTypes policyTypes, Policies policies) { + public RicRecoveryTask(A1Client a1Client, PolicyTypes policyTypes, Policies policies, Services services) { this.a1Client = a1Client; this.policyTypes = policyTypes; this.policies = policies; + this.services = services; } public void run(Collection rics) { @@ -81,14 +86,31 @@ public class RicRecoveryTask { private void onComplete(Ric ric) { logger.debug("Recovery completed for:" + ric.name()); ric.setState(Ric.RicState.ACTIVE); + notifyAllServices("Recovery completed for:" + ric.name()); + } + private void notifyAllServices(String body) { + for (Service service : services.getAll()) { + String url = service.getCallbackUrl(); + if (service.getCallbackUrl().length() > 0) { + createClient(url) // + .put("", body) // + .subscribe(rsp -> logger.debug("Service called"), + throwable -> logger.warn("Service called failed", throwable), + () -> logger.debug("Service called complete")); + } + } } private void onError(Ric ric, Throwable t) { - logger.debug("Recovery failed for: {}, reason: {}", ric.name(), t.getMessage()); + logger.warn("Recovery failed for: {}, reason: {}", ric.name(), t.getMessage()); ric.setState(Ric.RicState.NOT_REACHABLE); } + private AsyncRestClient createClient(final String url) { + return new AsyncRestClient(url); + } + private Flux recoverPolicyTypes(Ric ric) { ric.clearSupportedPolicyTypes(); return a1Client.getPolicyTypeIdentities(ric.getConfig().baseUrl()) // diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/StartupService.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/StartupService.java index d2356ea9..251f3437 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/tasks/StartupService.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/tasks/StartupService.java @@ -27,6 +27,7 @@ import org.oransc.policyagent.repository.Policies; import org.oransc.policyagent.repository.PolicyTypes; import org.oransc.policyagent.repository.Ric; import org.oransc.policyagent.repository.Rics; +import org.oransc.policyagent.repository.Services; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -55,13 +56,18 @@ public class StartupService { @Autowired private Policies policies; + @Autowired + private Services services; + + // Only for unittesting StartupService(ApplicationConfig appConfig, Rics rics, PolicyTypes policyTypes, A1Client a1Client, - Policies policies) { + Policies policies, Services services) { this.applicationConfig = appConfig; this.rics = rics; this.policyTypes = policyTypes; this.a1Client = a1Client; this.policies = policies; + this.services = services; } /** @@ -73,7 +79,7 @@ public class StartupService { for (RicConfig ricConfig : applicationConfig.getRicConfigs()) { rics.put(new Ric(ricConfig)); } - RicRecoveryTask recoveryTask = new RicRecoveryTask(a1Client, policyTypes, policies); + RicRecoveryTask recoveryTask = new RicRecoveryTask(a1Client, policyTypes, policies, services); recoveryTask.run(rics.getRics()); // recover all Rics } diff --git a/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java b/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java index 365d418a..e9dcaefc 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java @@ -29,7 +29,6 @@ import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import java.net.URL; -import java.util.Collection; import java.util.List; import java.util.Vector; @@ -52,6 +51,7 @@ import org.oransc.policyagent.repository.PolicyType; import org.oransc.policyagent.repository.PolicyTypes; import org.oransc.policyagent.repository.Ric; import org.oransc.policyagent.repository.Rics; +import org.oransc.policyagent.utils.MockA1Client; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; @@ -63,7 +63,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.web.client.RestTemplate; -import reactor.core.publisher.Mono; @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @@ -92,49 +91,6 @@ public class ApplicationTest { } } - static class A1ClientMock implements A1Client { - private final Policies policies; - private final PolicyTypes policyTypes; - - A1ClientMock(Policies policies, PolicyTypes policyTypes) { - this.policies = policies; - this.policyTypes = policyTypes; - } - - @Override - public Mono> getPolicyTypeIdentities(String nearRtRicUrl) { - Vector result = new Vector<>(); - for (PolicyType p : this.policyTypes.getAll()) { - result.add(p.name()); - } - return Mono.just(result); - } - - @Override - public Mono getPolicyType(String nearRtRicUrl, String policyTypeId) { - try { - return Mono.just(this.policies.get(policyTypeId).json()); - } catch (Exception e) { - return Mono.error(e); - } - } - - @Override - public Mono putPolicy(String nearRtRicUrl, String policyId, String policyString) { - return Mono.just("OK"); - } - - @Override - public Mono deletePolicy(String nearRtRicUrl, String policyId) { - return Mono.just("OK"); - } - - @Override - public Mono> getPolicyIdentities(String nearRtRicUrl) { - return Mono.empty(); // problem is that a recovery will start - } - } - /** * Overrides the BeanFactory. */ @@ -151,7 +107,7 @@ public class ApplicationTest { @Bean A1Client getA1Client() { - return new A1ClientMock(this.policies, this.policyTypes); + return new MockA1Client(this.policyTypes); } @Bean @@ -397,6 +353,7 @@ public class ApplicationTest { ServiceRegistrationInfo service = ImmutableServiceRegistrationInfo.builder() // .keepAliveInterval(1) // .name(name) // + .callbackUrl("callbackUrl") // .build(); String json = gson.toJson(service); return json; diff --git a/policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java b/policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java index dd57710c..420c8f7e 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java @@ -27,10 +27,6 @@ import java.io.File; import java.io.IOException; import java.net.URL; import java.nio.file.Files; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Vector; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -41,28 +37,18 @@ import org.oransc.policyagent.repository.Policies; import org.oransc.policyagent.repository.PolicyType; import org.oransc.policyagent.repository.PolicyTypes; import org.oransc.policyagent.repository.Rics; -import org.springframework.beans.factory.annotation.Autowired; +import org.oransc.policyagent.utils.MockA1Client; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.annotation.Bean; import org.springframework.test.context.junit.jupiter.SpringExtension; -import reactor.core.publisher.Mono; @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) public class MockPolicyAgent { - @Autowired - private Rics rics; - - @Autowired - private Policies policies; - - @Autowired - private PolicyTypes policyTypes; - static class MockApplicationConfig extends ApplicationConfig { @Override @@ -72,72 +58,42 @@ public class MockPolicyAgent { } } - private static class RicPolicyDatabase { - private Map> policies = new HashMap<>(); - - public void putPolicy(String nearRtRicUrl, String policyId, String policyString) { - getPolicies(nearRtRicUrl).put(policyId, policyString); - } - - public Collection getPolicyIdentities(String nearRtRicUrl) { - return getPolicies(nearRtRicUrl).keySet(); - } - - public void deletePolicy(String nearRtRicUrl, String policyId) { - getPolicies(nearRtRicUrl).remove(policyId); - } - - private Map getPolicies(String nearRtRicUrl) { - if (!policies.containsKey(nearRtRicUrl)) { - policies.put(nearRtRicUrl, new HashMap<>()); - } - return policies.get(nearRtRicUrl); - } - } - - static class A1ClientMock implements A1Client { + /** + * overrides the BeanFactory + */ + @TestConfiguration + static class TestBeanFactory { - private final RicPolicyDatabase policies = new RicPolicyDatabase(); + private final Rics rics = new Rics(); + private final Policies policies = new Policies(); private final PolicyTypes policyTypes = new PolicyTypes(); - A1ClientMock() { - loadTypes(this.policyTypes); - } - - @Override - public Mono> getPolicyTypeIdentities(String nearRtRicUrl) { - Vector result = new Vector<>(); - for (PolicyType p : this.policyTypes.getAll()) { - result.add(p.name()); - } - return Mono.just(result); + @Bean + public ApplicationConfig getApplicationConfig() { + return new MockApplicationConfig(); } - @Override - public Mono> getPolicyIdentities(String nearRtRicUrl) { - Collection result = policies.getPolicyIdentities(nearRtRicUrl); - return Mono.just(result); + @Bean + public A1Client getA1Client() { + PolicyTypes ricTypes = new PolicyTypes(); + loadTypes(ricTypes); + A1Client client = new MockA1Client(ricTypes); + return client; } - @Override - public Mono getPolicyType(String nearRtRicUrl, String policyTypeId) { - try { - return Mono.just(this.policyTypes.getType(policyTypeId).schema()); - } catch (Exception e) { - return Mono.error(e); - } + @Bean + public Policies getPolicies() { + return this.policies; } - @Override - public Mono putPolicy(String nearRtRicUrl, String policyId, String policyString) { - policies.putPolicy(nearRtRicUrl, policyId, policyString); - return Mono.just("OK"); + @Bean + public PolicyTypes getPolicyTypes() { + return this.policyTypes; } - @Override - public Mono deletePolicy(String nearRtRicUrl, String policyId) { - policies.deletePolicy(nearRtRicUrl, policyId); - return Mono.just("OK"); + @Bean + public Rics getRics() { + return this.rics; } private static File[] getResourceFolderFiles(String folder) { @@ -164,42 +120,7 @@ public class MockPolicyAgent { } } } - } - - /** - * overrides the BeanFactory - */ - @TestConfiguration - static class TestBeanFactory { - - private final Rics rics = new Rics(); - private final Policies policies = new Policies(); - private final PolicyTypes policyTypes = new PolicyTypes(); - - @Bean - public ApplicationConfig getApplicationConfig() { - return new MockApplicationConfig(); - } - - @Bean - A1Client getA1Client() { - return new A1ClientMock(); - } - - @Bean - public Policies getPolicies() { - return this.policies; - } - @Bean - public PolicyTypes getPolicyTypes() { - return this.policyTypes; - } - - @Bean - public Rics getRics() { - return this.rics; - } } @LocalServerPort diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientImplTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientImplTest.java index f9a93c8c..b3b5f48c 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientImplTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientImplTest.java @@ -20,11 +20,13 @@ package org.oransc.policyagent.clients; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Arrays; +import java.util.Vector; import org.json.JSONException; import org.junit.jupiter.api.BeforeEach; @@ -35,6 +37,13 @@ import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.jupiter.MockitoExtension; +import org.oransc.policyagent.configuration.ImmutableRicConfig; +import org.oransc.policyagent.configuration.RicConfig; +import org.oransc.policyagent.repository.ImmutablePolicy; +import org.oransc.policyagent.repository.ImmutablePolicyType; +import org.oransc.policyagent.repository.Policy; +import org.oransc.policyagent.repository.PolicyType; +import org.oransc.policyagent.repository.Ric; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -56,6 +65,7 @@ public class A1ClientImplTest { private static final String POLICY_2_ID = "policy2"; private static final String POLICY_JSON_VALID = "{\"policyId\":\"policy1\"}"; private static final String POLICY_JSON_INVALID = "\"policyId\":\"policy1\"}"; + private static final String POLICY_TYPE = "typeName"; @Spy A1ClientImpl a1Client; @@ -111,24 +121,46 @@ public class A1ClientImplTest { @Test public void testPutPolicyValidResponse() { - when(asyncRestClientMock.put(POLICIES_URL + POLICY_1_ID, POLICY_JSON_VALID)) - .thenReturn(Mono.just(POLICY_JSON_VALID)); + when(asyncRestClientMock.put(anyString(), anyString())).thenReturn(Mono.just(POLICY_JSON_VALID)); - Mono policyMono = a1Client.putPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON_VALID); + Mono policyMono = + a1Client.putPolicy(createPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE)); verify(asyncRestClientMock).put(POLICIES_URL + POLICY_1_ID, POLICY_JSON_VALID); StepVerifier.create(policyMono).expectNext(POLICY_JSON_VALID).expectComplete().verify(); } @Test public void testPutPolicyInvalidResponse() { - when(asyncRestClientMock.put(POLICIES_URL + POLICY_1_ID, POLICY_JSON_VALID)) - .thenReturn(Mono.just(POLICY_JSON_INVALID)); + when(asyncRestClientMock.put(anyString(), anyString())).thenReturn(Mono.just(POLICY_JSON_INVALID)); - Mono policyMono = a1Client.putPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON_VALID); - verify(asyncRestClientMock).put(POLICIES_URL + POLICY_1_ID, POLICY_JSON_VALID); + Mono policyMono = + a1Client.putPolicy(createPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE)); StepVerifier.create(policyMono).expectErrorMatches(throwable -> throwable instanceof JSONException).verify(); } + private Policy createPolicy(String nearRtRicUrl, String policyId, String json, String type) { + return ImmutablePolicy.builder() // + .id(policyId) // + .json(json) // + .ownerServiceName("service") // + .ric(createRic(nearRtRicUrl)) // + .type(createPolicyType(type)) // + .lastModified("now") // + .build(); + } + + private PolicyType createPolicyType(String name) { + return ImmutablePolicyType.builder().name(name).schema("schema").build(); + } + + private Ric createRic(String url) { + RicConfig cfg = ImmutableRicConfig.builder().name("ric") // + .baseUrl(url) // + .managedElementIds(new Vector(Arrays.asList("kista_1", "kista_2"))) // + .build(); + return new Ric(cfg); + } + @Test public void testDeletePolicy() { when(asyncRestClientMock.delete(POLICIES_URL + POLICY_1_ID)).thenReturn(Mono.empty()); diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RepositorySupervisionTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/RepositorySupervisionTest.java index 791acee2..418680e3 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RepositorySupervisionTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/tasks/RepositorySupervisionTest.java @@ -47,6 +47,7 @@ import org.oransc.policyagent.repository.PolicyTypes; import org.oransc.policyagent.repository.Ric; import org.oransc.policyagent.repository.Ric.RicState; import org.oransc.policyagent.repository.Rics; +import org.oransc.policyagent.repository.Services; import reactor.core.publisher.Mono; @ExtendWith(MockitoExtension.class) @@ -94,8 +95,10 @@ public class RepositorySupervisionTest { Policies policies = new Policies(); policies.put(policy1); PolicyTypes types = new PolicyTypes(); + Services services = new Services(); - RepositorySupervision supervisorUnderTest = new RepositorySupervision(rics, policies, a1ClientMock, types); + RepositorySupervision supervisorUnderTest = + new RepositorySupervision(rics, policies, a1ClientMock, types, services); Mono> policyIds = Mono.just(Arrays.asList("policyId1", "policyId2")); when(a1ClientMock.getPolicyIdentities(anyString())).thenReturn(policyIds); diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/StartupServiceTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/StartupServiceTest.java index 0c254d59..2ee175da 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/tasks/StartupServiceTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/tasks/StartupServiceTest.java @@ -50,6 +50,7 @@ import org.oransc.policyagent.repository.Policies; import org.oransc.policyagent.repository.PolicyTypes; import org.oransc.policyagent.repository.Ric; import org.oransc.policyagent.repository.Rics; +import org.oransc.policyagent.repository.Services; import reactor.core.publisher.Mono; @ExtendWith(MockitoExtension.class) @@ -92,7 +93,7 @@ public class StartupServiceTest { Rics rics = new Rics(); PolicyTypes policyTypes = new PolicyTypes(); StartupService serviceUnderTest = - new StartupService(appConfigMock, rics, policyTypes, a1ClientMock, new Policies()); + new StartupService(appConfigMock, rics, policyTypes, a1ClientMock, new Policies(), new Services()); serviceUnderTest.startup(); @@ -157,7 +158,7 @@ public class StartupServiceTest { Rics rics = new Rics(); PolicyTypes policyTypes = new PolicyTypes(); StartupService serviceUnderTest = - new StartupService(appConfigMock, rics, policyTypes, a1ClientMock, new Policies()); + new StartupService(appConfigMock, rics, policyTypes, a1ClientMock, new Policies(), new Services()); serviceUnderTest.startup(); @@ -188,7 +189,7 @@ public class StartupServiceTest { Rics rics = new Rics(); PolicyTypes policyTypes = new PolicyTypes(); StartupService serviceUnderTest = - new StartupService(appConfigMock, rics, policyTypes, a1ClientMock, new Policies()); + new StartupService(appConfigMock, rics, policyTypes, a1ClientMock, new Policies(), new Services()); serviceUnderTest.startup(); diff --git a/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java b/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java new file mode 100644 index 00000000..1a93b4d1 --- /dev/null +++ b/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java @@ -0,0 +1,92 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * Copyright (C) 2019 Nordix Foundation + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ + +package org.oransc.policyagent.utils; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; + +import org.oransc.policyagent.clients.A1Client; +import org.oransc.policyagent.repository.Policies; +import org.oransc.policyagent.repository.Policy; +import org.oransc.policyagent.repository.PolicyType; +import org.oransc.policyagent.repository.PolicyTypes; +import reactor.core.publisher.Mono; + +public class MockA1Client implements A1Client { + private final Map policies = new HashMap<>(); + private final PolicyTypes policyTypes; + + public MockA1Client(PolicyTypes policyTypes) { + this.policyTypes = policyTypes; + } + + @Override + public Mono> getPolicyTypeIdentities(String nearRtRicUrl) { + Vector result = new Vector<>(); + for (PolicyType p : this.policyTypes.getAll()) { + result.add(p.name()); + } + return Mono.just(result); + } + + @Override + public Mono> getPolicyIdentities(String nearRtRicUrl) { + Vector result = new Vector<>(); + for (Policy policy : getPolicies(nearRtRicUrl).getAll()) { + if (policy.ric().getConfig().baseUrl().equals(nearRtRicUrl)) { + result.add(policy.id()); + } + } + + return Mono.just(result); + } + + @Override + public Mono getPolicyType(String nearRtRicUrl, String policyTypeId) { + try { + return Mono.just(this.policyTypes.getType(policyTypeId).schema()); + } catch (Exception e) { + return Mono.error(e); + } + } + + @Override + public Mono putPolicy(Policy p) { + getPolicies(p.ric().getConfig().baseUrl()).put(p); + return Mono.just("OK"); + } + + @Override + public Mono deletePolicy(String nearRtRicUrl, String policyId) { + getPolicies(nearRtRicUrl).removeId(policyId); + return Mono.just("OK"); + } + + private Policies getPolicies(String url) { + if (!policies.containsKey(url)) { + policies.put(url, new Policies()); + } + return policies.get(url); + } + +} diff --git a/policy-agent/src/test/resources/policy_types/demo-policy-schema-1.json b/policy-agent/src/test/resources/policy_types/demo-policy-schema-1.json index fa7410fb..02bc8645 100644 --- a/policy-agent/src/test/resources/policy_types/demo-policy-schema-1.json +++ b/policy-agent/src/test/resources/policy_types/demo-policy-schema-1.json @@ -1,42 +1,71 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Example_QoSTarget_1.0.0", - "description": "Example QoS Target policy type", + "title": "STD_PolicyModelUnconstrained_0.2.0", + "description": "Standard model of a policy with unconstrained scope id combinations", "type": "object", "properties": { "scope": { "type": "object", "properties": { - "qosId": { - "type": "string" - }, - "cellId": { - "type": "string" - } + "ueId": {"type": "string"}, + "groupId": {"type": "string"}, + "sliceId": {"type": "string"}, + "qosId": {"type": "string"}, + "cellId": {"type": "string"} }, - "additionalProperties": false, - "required": [ - "qosId" - ] + "minProperties": 1, + "additionalProperties": false }, - "statement": { + "qosObjectives": { "type": "object", "properties": { - "gfbr": { - "type": "number" - }, - "mfbr": { - "type": "number" - }, - "priorityLevel": { - "type": "number" - }, - "pdb": { - "type": "number" - } + "gfbr": {"type": "number"}, + "mfbr": {"type": "number"}, + "priorityLevel": {"type": "number"}, + "pdb": {"type": "number"} }, - "minProperties": 1, "additionalProperties": false + }, + "qoeObjectives": { + "type": "object", + "properties": { + "qoeScore": {"type": "number"}, + "initialBuffering": {"type": "number"}, + "reBuffFreq": {"type": "number"}, + "stallRatio": {"type": "number"} + }, + "additionalProperties": false + }, + "resources": { + "type": "array", + "items": { + "type": "object", + "properties": { + "cellIdList": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "type": "string" + } + }, + "preference": { + "type": "string", + "enum": [ + "SHALL", + "PREFER", + "AVOID", + "FORBID" + ] + }, + "primary": {"type": "boolean"} + }, + "additionalProperties": false, + "required": ["cellIdList", "preference"] + } } - } -} \ No newline at end of file + }, + "minProperties": 2, + "additionalProperties": false, + "required": ["scope"] +} diff --git a/policy-agent/src/test/resources/policy_types/demo-policy-schema-3.json b/policy-agent/src/test/resources/policy_types/demo-policy-schema-3.json index 695514cd..a73dd590 100644 --- a/policy-agent/src/test/resources/policy_types/demo-policy-schema-3.json +++ b/policy-agent/src/test/resources/policy_types/demo-policy-schema-3.json @@ -1,59 +1,27 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Example_TrafficSteeringPreference_1.0.0", - "description": "Example QoE Target policy type", + "title": "ERIC_QoSNudging_0.2.0", + "description": "QoS nudging policy type with priorityLevel and ueId and qosId as scope", "type": "object", "properties": { "scope": { "type": "object", "properties": { - "ueId": { - "type": "string" - }, - "sliceId": { - "type": "string" - }, - "qosId": { - "type": "string" - }, - "cellId": { - "type": "string" - } + "ueId": {"type": "string"}, + "qosId": {"type": "string"} }, "additionalProperties": false, - "required": [ - "ueId" - ] + "required": ["ueId", "qosId"] }, - "statement": { + "qosObjectives": { "type": "object", "properties": { - "cellIdList": { - "type": "array", - "minItems": 1, - "uniqueItems": true, - "items": { - "type": "string" - } - }, - "preference": { - "type": "string", - "enum": [ - "SHALL", - "PREFER", - "AVOID", - "FORBID" - ] - }, - "primary": { - "type": "boolean" - } + "priorityLevel": {"type": "number"} }, - "required": [ - "cellIdList", - "preference" - ], - "additionalProperties": false + "additionalProperties": false, + "required": ["priorityLevel"] } - } -} \ No newline at end of file + }, + "additionalProperties": false, + "required": ["scope", "qosObjectives"] +} diff --git a/policy-agent/src/test/resources/test_application_configuration.json b/policy-agent/src/test/resources/test_application_configuration.json index 7033c4aa..924b1dd0 100644 --- a/policy-agent/src/test/resources/test_application_configuration.json +++ b/policy-agent/src/test/resources/test_application_configuration.json @@ -9,7 +9,15 @@ "kista_1", "kista_2" ] + }, + { + "name": "ric2", + "baseUrl": "http://localhost:8081/", + "managedElementIds": [ + "kista_3", + "kista_4" + ] } ] } -} \ No newline at end of file +} -- 2.16.6