From: PatrikBuhr Date: Fri, 6 Dec 2019 09:36:35 +0000 (+0100) Subject: Continue work with PolicyControl X-Git-Tag: 1.0.1~87^2 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=2aa1689637366d03a1252afadf93be937c1ec644;p=nonrtric.git Continue work with PolicyControl Added a Bean factory Change-Id: I6351ab07614a3345393d2415cd3adb4b14a96eca Issue-ID: NONRTRIC-76 Signed-off-by: PatrikBuhr --- diff --git a/policy-agent/config/application.yaml b/policy-agent/config/application.yaml index 73f280a1..ee59a268 100644 --- a/policy-agent/config/application.yaml +++ b/policy-agent/config/application.yaml @@ -1,6 +1,8 @@ spring: profiles: active: prod + main: + allow-bean-definition-overriding: true management: endpoints: web: diff --git a/policy-agent/java-formatter.xml b/policy-agent/java-formatter.xml new file mode 100644 index 00000000..7339434a --- /dev/null +++ b/policy-agent/java-formatter.xml @@ -0,0 +1,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/policy-agent/src/main/java/org/oransc/policyagent/Beans.java b/policy-agent/src/main/java/org/oransc/policyagent/Beans.java new file mode 100644 index 00000000..74477491 --- /dev/null +++ b/policy-agent/src/main/java/org/oransc/policyagent/Beans.java @@ -0,0 +1,46 @@ +/*- + * ========================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; + +import org.oransc.policyagent.configuration.ApplicationConfig; +import org.oransc.policyagent.repository.Policies; +import org.oransc.policyagent.repository.PolicyTypes; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class Beans { + + @Bean + Policies getPolicies() { + return new Policies(); + } + + @Bean + PolicyTypes getPolicyTypes() { + return new PolicyTypes(); + } + + @Bean + ApplicationConfig getApplicationConfig() { + return new ApplicationConfig(); + } + +} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java index 79c82a78..d8da5ee8 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java @@ -47,10 +47,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; -@Component @EnableConfigurationProperties @ConfigurationProperties("app") public class ApplicationConfig { @@ -76,18 +74,26 @@ public class ApplicationConfig { return this.ricConfigs; } - public Optional getRicConfig(String managedElementId) { + public Optional lookupRicConfigForManagedElement(String managedElementId) { for (RicConfig ricConfig : getRicConfigs()) { if (ricConfig.managedElementIds().contains(managedElementId)) { return Optional.of(ricConfig); - } } return Optional.empty(); } + public RicConfig getRic(String ricName) throws ServiceException { + for (RicConfig ricConfig : getRicConfigs()) { + if (ricConfig.name().equals(ricName)) { + return ricConfig; + } + } + throw new ServiceException("Could not find ric: " + ricName); + } + public void initialize() { - loadConfigurationFromFile(); + loadConfigurationFromFile(this.filepath); } Mono getEnvironment(Properties systemEnvironment) { @@ -97,7 +103,7 @@ public class ApplicationConfig { /** * Reads the configuration from file. */ - void loadConfigurationFromFile() { + protected void loadConfigurationFromFile(String filepath) { GsonBuilder gsonBuilder = new GsonBuilder(); ServiceLoader.load(TypeAdapterFactory.class).forEach(gsonBuilder::registerTypeAdapterFactory); diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigLoader.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigLoader.java index 24473f6f..e1eb17a5 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigLoader.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigLoader.java @@ -32,14 +32,14 @@ import javax.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; -@Configuration +@Component @EnableScheduling class ApplicationConfigLoader { 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 a507a2b1..21521b77 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 @@ -19,94 +19,81 @@ */ package org.oransc.policyagent.controllers; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; - -import java.util.Vector; - import org.oransc.policyagent.configuration.ApplicationConfig; -import org.oransc.policyagent.configuration.RicConfig; +import org.oransc.policyagent.exceptions.ServiceException; +import org.oransc.policyagent.repository.ImmutablePolicy; +import org.oransc.policyagent.repository.Policies; +import org.oransc.policyagent.repository.Policy; +import org.oransc.policyagent.repository.PolicyTypes; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import reactor.core.publisher.Mono; @RestController public class PolicyController { private final ApplicationConfig appConfig; - private static Gson gson = new GsonBuilder() // - .serializeNulls() // - .create(); // + private final PolicyTypes types; + private final Policies policies; @Autowired - PolicyController(ApplicationConfig config) { + PolicyController(ApplicationConfig config, PolicyTypes types, Policies policies) { this.appConfig = config; + this.types = types; + this.policies = policies; } // http://localhost:8080/policy?type=type3&instance=xxx @GetMapping("/policy") - public String getPolicy(@RequestParam(name = "type", required = false, defaultValue = "type1") String typeName, + public ResponseEntity getPolicy( // + @RequestParam(name = "type", required = false, defaultValue = "type1") String typeName, // @RequestParam(name = "instance", required = false, defaultValue = "new") String instanceId) { - System.out.println("**** getPolicy " + typeName); - return "policy" + typeName + instanceId; + return new ResponseEntity("policy" + typeName + instanceId, HttpStatus.OK); } - public String getHello() { - return "Howdy"; - } - - @GetMapping("/status") - @ApiOperation(value = "Returns status and statistics of the service") - @ApiResponses( - value = { // - @ApiResponse(code = 200, message = "DATAFILE service is living"), - @ApiResponse(code = 401, message = "You are not authorized to view the resource"), - @ApiResponse(code = 403, message = "Accessing the resource you were trying to reach is forbidden"), - @ApiResponse(code = 404, message = "The resource you were trying to reach is not found") // - }) - public Mono> getStatus() { - Mono> response = Mono.just(new ResponseEntity<>("hunky dory", HttpStatus.OK)); - return response; - } - - // http://localhost:8080/rics?managedElementId=kista_1 - @GetMapping("/rics") - @ApiOperation(value = "Returns defined NearRT RIC:s") - public ResponseEntity getRics( - @RequestParam(name = "managedElementId", required = false, defaultValue = "") String managedElementId) { - Vector result = new Vector(); - Vector config = getRicConfigs(managedElementId); - - for (RicConfig ricConfig : config) { - RicInfo ric = ImmutableRicInfo.builder() // - .managedElementIds(ricConfig.managedElementIds()) // - .name(ricConfig.name()) // + @PutMapping(path = "/policy") + public ResponseEntity putPolicy( // + @RequestParam(name = "type", required = true) String type, // + @RequestParam(name = "instance", required = true) String instanceId, // + @RequestParam(name = "ric", required = true) String ric, // + @RequestParam(name = "service", required = true) String service, // + @RequestBody String jsonBody) { + + System.out.println("*********************** " + jsonBody); + + try { + Policy policy = ImmutablePolicy.builder() // + .id(instanceId) // + .json(jsonBody) // + .type(types.getType(type)) // + .ric(appConfig.getRic(ric)) // + .ownerServiceName(service) // .build(); - result.add(ric); + policies.put(instanceId, policy); + return new ResponseEntity(HttpStatus.OK); + } catch (ServiceException e) { + System.out.println("*********************** " + e.getMessage()); + + return new ResponseEntity(e.getMessage(), HttpStatus.NOT_FOUND); } - return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK); } - private Vector getRicConfigs(String managedElementId) { - if (managedElementId.equals("")) { - return this.appConfig.getRicConfigs(); - } - - Vector result = new Vector(1); - appConfig.getRicConfig(managedElementId).ifPresent((config) -> { - result.add(config); - }); - return result; + @PutMapping(path = "/policyX") + public ResponseEntity putPolicyX( // + // @RequestParam(name = "type", required = false) String type, // + // @RequestParam(name = "instance", required = true) String instance, // + // @RequestParam(name = "ric", required = true) String ric, // + @RequestBody String jsonBody) { + System.out.println("*********************** " + jsonBody); + // System.out.println("policy" + type + instance); + return new ResponseEntity(HttpStatus.OK); } } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java new file mode 100644 index 00000000..34fc4c1e --- /dev/null +++ b/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java @@ -0,0 +1,98 @@ +/*- + * ========================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.controllers; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; + +import java.util.Optional; +import java.util.Vector; + +import org.oransc.policyagent.configuration.ApplicationConfig; +import org.oransc.policyagent.configuration.RicConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class RicRepositoryController { + + private final ApplicationConfig appConfig; + private static Gson gson = new GsonBuilder() // + .serializeNulls() // + .create(); // + + @Autowired + RicRepositoryController(ApplicationConfig config) { + this.appConfig = config; + } + + /** + * Example: http://localhost:8080/rics?managedElementId=kista_1 + */ + @GetMapping("/ric") + @ApiOperation(value = "Returns the name of a RIC managing one Mananged Element") + @ApiResponses( + value = { // + @ApiResponse(code = 200, message = "RIC is fond"), // + @ApiResponse(code = 404, message = "RIC is not fond") // + }) + public ResponseEntity getRic( + @RequestParam(name = "managedElementId", required = false, defaultValue = "") String managedElementId) { + + Optional config = appConfig.lookupRicConfigForManagedElement(managedElementId); + + if (config.isPresent()) { + return new ResponseEntity<>(config.get().name(), HttpStatus.OK); + } else { + return new ResponseEntity<>("", HttpStatus.NOT_FOUND); + } + } + + /** + * @return a Json array of all RIC data + * Example: http://localhost:8080/ric + */ + @GetMapping("/rics") + @ApiOperation(value = "Returns defined NearRT RIC:s as Json") + @ApiResponses( + value = { // + @ApiResponse(code = 200, message = "OK") // + }) + public ResponseEntity getRics() { + Vector result = new Vector(); + for (RicConfig ricConfig : this.appConfig.getRicConfigs()) { + RicInfo ric = ImmutableRicInfo.builder() // + .managedElementIds(ricConfig.managedElementIds()) // + .name(ricConfig.name()) // + .build(); + result.add(ric); + } + return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK); + } + +} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/StatusController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/StatusController.java new file mode 100644 index 00000000..6f86173d --- /dev/null +++ b/policy-agent/src/main/java/org/oransc/policyagent/controllers/StatusController.java @@ -0,0 +1,46 @@ +/*- + * ========================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.controllers; + +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + +@RestController +public class StatusController { + + @GetMapping("/status") + @ApiOperation(value = "Returns status and statistics of the service") + @ApiResponses( + value = { // + @ApiResponse(code = 200, message = "Service is living") // + }) + public Mono> getStatus() { + Mono> response = Mono.just(new ResponseEntity<>("hunky dory", HttpStatus.OK)); + return response; + } + +} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java index 359cd227..a5519caa 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java @@ -23,13 +23,10 @@ package org.oransc.policyagent.repository; import java.util.HashMap; import java.util.Map; -import org.oransc.policyagent.configuration.RicConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -@Component public class Policies { private static final Logger logger = LoggerFactory.getLogger(Policies.class); @@ -43,4 +40,8 @@ public class Policies { policies.put(id, policy); } + public synchronized Policy get(String id) { + return policies.get(id); + } + } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java index 47b815be..ef3f42d4 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java @@ -27,9 +27,7 @@ import org.oransc.policyagent.exceptions.ServiceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -@Component public class PolicyTypes { private static final Logger logger = LoggerFactory.getLogger(PolicyTypes.class); 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 1cbd0b66..d22a9da8 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java @@ -21,11 +21,27 @@ package org.oransc.policyagent; import static org.assertj.core.api.Assertions.assertThat; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + import org.junit.Test; import org.junit.runner.RunWith; +import org.oransc.policyagent.configuration.ApplicationConfig; +import org.oransc.policyagent.repository.ImmutablePolicyType; +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 org.springframework.beans.factory.annotation.Autowired; 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.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.client.RestTemplate; @@ -33,6 +49,40 @@ import org.springframework.web.client.RestTemplate; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class ApplicationTest { + @Autowired + private Policies policies; + + @Autowired + private PolicyTypes policyTypes; + + @Autowired + ApplicationConfig appConfig; + + static class MockApplicationConfig extends ApplicationConfig { + public void initialize() { + URL url = MockApplicationConfig.class.getClassLoader().getResource("test_application_configuration.json"); + loadConfigurationFromFile(url.getFile()); + } + } + + @TestConfiguration + static class Beans { + @Bean + Policies getPolicies() { + return new Policies(); + } + + @Bean + PolicyTypes getPolicyTypes() { + return new PolicyTypes(); + } + + @Bean + ApplicationConfig getApplicationConfig() { + return new MockApplicationConfig(); + } + } + @LocalServerPort private int port; @@ -54,4 +104,47 @@ public class ApplicationTest { assertThat(rsp).contains("kista_1"); } + @Test + public void getRic() throws Exception { + String cmd = "/ric?managedElementId=kista_1"; + String rsp = this.restTemplate.getForObject("http://localhost:" + port + cmd, String.class); + assertThat(rsp).isEqualTo("ric1"); + } + + // managedElmentId -> nodeName + + @Test + public void putPolicy() throws Exception { + // types.putType("type1", ImmutablePolicyType.builder().name("").jsonSchema("").build()); + + String url = "http://localhost:" + port + "/policy?type={type}&instance={instance}&ric={ric}&service={service}"; + + Map uriVariables = new HashMap(); + uriVariables.put("type", "type1"); + uriVariables.put("instance", "instance1"); + uriVariables.put("ric", "ric1"); + uriVariables.put("service", "service"); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + String json = "{}"; + HttpEntity entity = new HttpEntity(json); + + addPolicyType(policyTypes, "type1"); + + this.restTemplate.put(url, entity, uriVariables); + Policy policy = this.policies.get("instance1"); + assertThat(policy).isNotNull(); + assertThat(policy.id()).isEqualTo("instance1"); + assertThat(policy.ownerServiceName()).isEqualTo("service"); + } + + private void addPolicyType(PolicyTypes policyTypes, String name) { + PolicyType type = ImmutablePolicyType.builder() // + .jsonSchema("") // + .name(name) // + .build(); + + policyTypes.putType(name, type); + } + } diff --git a/policy-agent/src/test/resources/test_application_configuration.json b/policy-agent/src/test/resources/test_application_configuration.json new file mode 100644 index 00000000..7033c4aa --- /dev/null +++ b/policy-agent/src/test/resources/test_application_configuration.json @@ -0,0 +1,15 @@ +{ + "config": { + "//description": "Application configuration", + "ric": [ + { + "name": "ric1", + "baseUrl": "http://localhost:8080/", + "managedElementIds": [ + "kista_1", + "kista_2" + ] + } + ] + } +} \ No newline at end of file