Merge "Swagger documentation"
authorHenrik Andersson <henrik.b.andersson@est.tech>
Fri, 20 Dec 2019 09:47:40 +0000 (09:47 +0000)
committerGerrit Code Review <gerrit@o-ran-sc.org>
Fri, 20 Dec 2019 09:47:40 +0000 (09:47 +0000)
57 files changed:
dashboard/.gitignore
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/PolicyController.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApi.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApiImpl.java
dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/PolicyControllerMockConfiguration.java
dashboard/webapp-frontend/src/app/footer/footer.component.scss
dashboard/webapp-frontend/src/app/policy-control/policy-instance-dialog.component.html
dashboard/webapp-frontend/src/app/policy-control/policy-instance-dialog.component.scss
dashboard/webapp-frontend/src/app/policy-control/policy-instance-dialog.component.ts
dashboard/webapp-frontend/src/app/services/policy/policy.service.ts
near-rt-ric-simulator/auto-test/.gitignore [new file with mode: 0644]
near-rt-ric-simulator/auto-test/FTC1.sh [new file with mode: 0755]
near-rt-ric-simulator/common/test_env.sh [new file with mode: 0755]
near-rt-ric-simulator/common/testcase_common.sh [new file with mode: 0755]
near-rt-ric-simulator/simulator-group/consul_cbs/config.json [moved from near-rt-ric-simulator/consul_cbs/config.json with 100% similarity]
near-rt-ric-simulator/simulator-group/consul_cbs/consul/cbs_config.hcl [new file with mode: 0644]
near-rt-ric-simulator/simulator-group/consul_cbs/consul/cbs_localhost_config.hcl [moved from near-rt-ric-simulator/consul_cbs/consul/cbs_localhost_config.hcl with 67% similarity]
near-rt-ric-simulator/simulator-group/consul_cbs/docker-compose-template.yml [moved from near-rt-ric-simulator/consul_cbs/docker-compose-template.yml with 100% similarity]
near-rt-ric-simulator/simulator-group/consul_cbs/docker-compose.yml [moved from near-rt-ric-simulator/consul_cbs/docker-compose.yml with 84% similarity]
near-rt-ric-simulator/simulator-group/consul_cbs/start.sh [moved from near-rt-ric-simulator/consul_cbs/start.sh with 100% similarity]
near-rt-ric-simulator/simulator-group/simulators-start.sh [new file with mode: 0755]
policy-agent/Dockerfile
policy-agent/pom.xml
policy-agent/src/main/java/org/oransc/policyagent/Application.java
policy-agent/src/main/java/org/oransc/policyagent/BeanFactory.java
policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java
policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientImpl.java [new file with mode: 0644]
policy-agent/src/main/java/org/oransc/policyagent/clients/AsyncRestClient.java
policy-agent/src/main/java/org/oransc/policyagent/clients/RicClient.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java
policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java
policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyInfo.java
policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyTypeInfo.java
policy-agent/src/main/java/org/oransc/policyagent/controllers/RicInfo.java
policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java
policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceController.java
policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java
policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceStatus.java
policy-agent/src/main/java/org/oransc/policyagent/controllers/StatusController.java
policy-agent/src/main/java/org/oransc/policyagent/exceptions/AsyncRestClientException.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java
policy-agent/src/main/java/org/oransc/policyagent/repository/Policy.java
policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyType.java
policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java
policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java
policy-agent/src/main/java/org/oransc/policyagent/repository/Service.java
policy-agent/src/main/java/org/oransc/policyagent/tasks/ServiceSupervision.java
policy-agent/src/main/java/org/oransc/policyagent/tasks/StartupService.java
policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java
policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java
policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java
policy-agent/src/test/java/org/oransc/policyagent/tasks/StartupServiceTest.java
policy-agent/src/test/resources/policy_types/anr-policy-schema.json [new file with mode: 0644]
policy-agent/src/test/resources/policy_types/demo-policy-schema-1.json [new file with mode: 0644]
policy-agent/src/test/resources/policy_types/demo-policy-schema-2.json [new file with mode: 0644]
policy-agent/src/test/resources/policy_types/demo-policy-schema-3.json [new file with mode: 0644]
pom.xml

index 675d063..1fe9c87 100644 (file)
@@ -14,7 +14,7 @@
 /.classpath
 /.project
 /.settings
-/target/
+target
 /.mvn/wrapper/maven-wrapper.jar
 /.tox
 
index 8af4e97..410ad1d 100644 (file)
@@ -49,8 +49,9 @@ import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
-
+import java.util.Collection;
 import io.swagger.annotations.ApiOperation;
 
 /**
@@ -126,10 +127,11 @@ public class PolicyController {
                        + "}")
        @Secured({ DashboardConstants.ROLE_ADMIN })
        public void 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);
+               this.policyAgentApi.putPolicy(policyTypeIdString, policyInstanceId, instance, ric);
        }
 
        @ApiOperation(value = "Deletes the policy instances for the given policy type.")
@@ -158,4 +160,17 @@ public class PolicyController {
                        throw new HttpNotImplementedException("Not Implemented Exception");
                }
        }
-}
+
+       @ApiOperation(value = "Returns the rics supporting the given policy type.")
+       @GetMapping("/rics")
+       @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD })
+       public String getRicsSupportingType(
+                       @RequestParam(name = "policyType", required = true) String supportingPolicyType) {
+               logger.debug("getRicsSupportingType {}", supportingPolicyType);
+
+               Collection<String> result = this.policyAgentApi.getRicsSupportingType(supportingPolicyType);
+               String json = gson.toJson(result);
+               return json;
+       }
+
+};
index 41f3c12..144a77a 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.oransc.ric.portal.dashboard.policyagentapi;
 
+import java.util.Collection;
+
 import org.oransc.ric.portal.dashboard.model.PolicyInstances;
 import org.oransc.ric.portal.dashboard.model.PolicyTypes;
 import org.springframework.web.client.RestClientException;
@@ -31,7 +33,11 @@ public interface PolicyAgentApi {
 
     public String getPolicyInstance(String id) throws RestClientException;
 
-    public void putPolicy(String policyTypeIdString, String policyInstanceId, String json) throws RestClientException;
+    public void putPolicy(String policyTypeIdString, String policyInstanceId, String json, String ric)
+            throws RestClientException;
 
     public void deletePolicy(String policyInstanceId) throws RestClientException;
+
+    public Collection<String> getRicsSupportingType(String typeName);
+
 }
index 8236de1..258086d 100644 (file)
@@ -31,8 +31,10 @@ import org.springframework.stereotype.Component;
 import org.springframework.web.client.RestClientException;
 import org.springframework.web.client.RestTemplate;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Vector;
 import java.lang.invoke.MethodHandles;
 import java.lang.reflect.Type;
 
@@ -112,7 +114,6 @@ public class PolicyAgentApiImpl implements PolicyAgentApi {
             result.add(p);
         }
         return result;
-
     }
 
     @Override
@@ -124,12 +125,13 @@ public class PolicyAgentApiImpl implements PolicyAgentApi {
     }
 
     @Override
-    public void putPolicy(String policyTypeIdString, String policyInstanceId, String json) throws RestClientException {
+    public void putPolicy(String policyTypeIdString, String policyInstanceId, String json, String ric)
+            throws RestClientException {
         String url = baseUrl() + "/policy?type={type}&instance={instance}&ric={ric}&service={service}";
         Map<String, ?> uriVariables = Map.of( //
                 "type", policyTypeIdString, //
                 "instance", policyInstanceId, //
-                "ric", "ric1", // TODO
+                "ric", ric, //
                 "service", "dashboard");
 
         this.restTemplate.put(url, json, uriVariables);
@@ -142,4 +144,31 @@ public class PolicyAgentApiImpl implements PolicyAgentApi {
         this.restTemplate.delete(url, uriVariables);
     }
 
+    @Value.Immutable
+    @Gson.TypeAdapters
+    interface RicInfo {
+        public String name();
+
+        public Collection<String> nodeNames();
+
+        public Collection<String> policyTypes();
+    }
+
+    @Override
+    public Collection<String> getRicsSupportingType(String typeName) {
+        String url = baseUrl() + "/rics?policyType={typeName}";
+        Map<String, ?> uriVariables = Map.of("typeName", typeName);
+        String rsp = this.restTemplate.getForObject(url, String.class, uriVariables);
+
+        Type listType = new TypeToken<List<ImmutableRicInfo>>() {
+        }.getType();
+        List<RicInfo> rspParsed = gson.fromJson(rsp, listType);
+
+        Collection<String> result = new Vector<>(rspParsed.size());
+        for (RicInfo ric : rspParsed) {
+            result.add(ric.name());
+        }
+        return result;
+    }
+
 }
index 4213488..44d0b5c 100644 (file)
@@ -29,6 +29,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Vector;
 import java.util.stream.Collectors;
 
 import org.oransc.ric.portal.dashboard.model.ImmutablePolicyInfo;
@@ -66,9 +67,9 @@ public class PolicyControllerMockConfiguration {
                }
 
                @Override
-               public void putPolicy(String policyTypeIdString, String policyInstanceId, String json)
+               public void putPolicy(String policyTypeIdString, String policyInstanceId, String json, String ric)
                                throws RestClientException {
-                       database.putInstance(policyTypeIdString, policyInstanceId, json);
+                       database.putInstance(policyTypeIdString, policyInstanceId, json, ric);
                }
 
                @Override
@@ -91,6 +92,14 @@ public class PolicyControllerMockConfiguration {
                        return result;
                }
 
+               @Override
+               public Collection<String> getRicsSupportingType(String typeName) {
+                       Vector<String> res = new Vector<>();
+                       res.add("ric_1");
+                       res.add("ric_2");
+                       res.add("ric_3");
+                       return res;
+               }
        }
 
        class Database {
@@ -112,7 +121,7 @@ public class PolicyControllerMockConfiguration {
                        policy = new PolicyType("type4", schema);
                        types.put("type4", policy);
                        try {
-                               putInstance("ANR", "ANR-1", getStringFromFile("anr-policy-instance.json"));
+                               putInstance("ANR", "ANR-1", getStringFromFile("anr-policy-instance.json"), "ric_1");
                        } catch (Exception e) {
                                // Nothing
                        }
@@ -137,9 +146,9 @@ public class PolicyControllerMockConfiguration {
                        return java.time.Instant.now().toString();
                }
 
-               void putInstance(String typeId, String instanceId, String instanceData) {
+               void putInstance(String typeId, String instanceId, String instanceData, String ric) {
                        PolicyInfo i = ImmutablePolicyInfo.builder().json(instanceData).lastModified(getTimeStampUTC())
-                                       .id(instanceId).ric("ricXX").service("service").type(typeId).build();
+                                       .id(instanceId).ric(ric).service("service").type(typeId).build();
                        instances.put(instanceId, i);
                }
 
index c06dc01..fb87ba5 100644 (file)
@@ -21,6 +21,7 @@
   color: gray;
   letter-spacing: 0.1rem;
   font-size: 10px;
+  margin-left: 10px;
 }
 
 .copyright__text-dark {
index 776d503..d447c70 100644 (file)
 <div class="text-muted" *ngIf="jsonSchemaObject.description">{{jsonSchemaObject.description}}</div>
 
 <div fxLayout="row" fxLayoutAlign="space-around start" fxLayout.lt-sm="column" fxLayoutAlign.lt-sm="flex-start center">
+
+
     <mat-card class="card" [ngClass]="{'card-dark': darkMode}">
+
+        <mat-form-field *ngIf="!this.policyInstanceId">
+            <mat-label [class.text-danger]="!this.ric">Select RIC</mat-label>
+            <mat-select [(value)]="this.ric">
+                <mat-option *ngFor="let ric of this.allRics" [value]="ric">
+                    {{ric}}
+                </mat-option>
+            </mat-select>
+        </mat-form-field>
+
         <h4 class="default-cursor" (click)="toggleVisible('form')">
             <mat-icon matTooltip="Properties">{{isVisible.form ? 'expand_less' : 'expand_more'}}</mat-icon>
             Properties
@@ -51,8 +63,8 @@
             </json-schema-form>
         </div>
         <hr />
-        <button mat-raised-button (click)="this.onSubmit()" [disabled]="!this.formIsValid" class="submitBtn"
-            style="margin-right:10px">Submit</button>
+        <button mat-raised-button (click)="this.onSubmit()" [disabled]="!this.formIsValid || !this.ric"
+            class="submitBtn">Submit</button>
         <button mat-raised-button (click)="this.onClose()">Close</button>
         <hr />
         <h4 [class.text-danger]="!formIsValid && !isVisible.json" [class.default-cursor]="formIsValid || isVisible.json"
index 5b5cc00..b4ad194 100644 (file)
@@ -74,13 +74,29 @@ export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit {
     formValidationErrors: any;
     formIsValid = false;
 
-
     @ViewChild(MatMenuTrigger, { static: true }) menuTrigger: MatMenuTrigger;
 
-    public policyInstanceId: string;
-    public policyTypeName: string;
+    policyInstanceId: string; // null if not yet created
+    policyTypeName: string;
     darkMode: boolean;
+    ric: string;
+    allRics: string[];
 
+    private fetchRics() {
+        console.log('fetchRics ' + this.policyTypeName);
+        const self: PolicyInstanceDialogComponent = this;
+        this.dataService.getRics(this.policyTypeName).subscribe(
+            {
+                next(value) {
+                    self.allRics = value;
+                    console.log(value);
+                },
+                error(error) {
+                    self.errorService.displayError('Fetching of rics failed: ' + error.message);
+                },
+                complete() { }
+            });
+    }
 
     constructor(
         private dataService: PolicyService,
@@ -94,6 +110,7 @@ export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit {
         this.policyTypeName = data.name;
         this.jsonSchemaObject = data.createSchema;
         this.jsonObject = this.parseJson(data.instanceJson);
+        this.ric = data.ric;
     }
 
     ngOnInit() {
@@ -102,6 +119,9 @@ export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit {
         this.ui.darkModeState.subscribe((isDark) => {
             this.darkMode = isDark;
         });
+        if (!this.policyInstanceId) {
+            this.fetchRics();
+        }
     }
 
     ngAfterViewInit() {
@@ -113,7 +133,7 @@ export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit {
         }
         const policyJson: string = this.prettyLiveFormData;
         const self: PolicyInstanceDialogComponent = this;
-        this.dataService.putPolicy(this.policyTypeName, this.policyInstanceId, policyJson).subscribe(
+        this.dataService.putPolicy(this.policyTypeName, this.policyInstanceId, policyJson, this.ric).subscribe(
             {
                 next(value) {
                     self.notificationService.success('Policy ' + self.policyTypeName + ':' + self.policyInstanceId + ' submitted');
@@ -196,6 +216,7 @@ export function getPolicyDialogProperties(policyType: PolicyType, instance: Poli
     const instanceId = instance ? instance.id : null;
     const instanceJson = instance ? instance.json : null;
     const name = policyType.name;
+    const ric = instance ? instance.ric : null;
     return {
         maxWidth: '1200px',
         maxHeight: '900px',
@@ -207,7 +228,8 @@ export function getPolicyDialogProperties(policyType: PolicyType, instance: Poli
             createSchema,
             instanceId,
             instanceJson,
-            name
+            name,
+            ric
         }
     };
 }
index fc0f306..6af517f 100644 (file)
@@ -87,8 +87,8 @@ export class PolicyService {
      * @param policyJson Json with the policy content
      * @returns Observable that should yield a response code, no data
      */
-    putPolicy(policyTypeId: string, policyInstanceId: string, policyJson: string): Observable<any> {
-        const url = this.buildPath(this.policyTypePath, policyTypeId, this.policyPath, policyInstanceId);
+    putPolicy(policyTypeId: string, policyInstanceId: string, policyJson: string, ric: string): Observable<any> {
+        const url = this.buildPath(this.policyTypePath, policyTypeId, this.policyPath, policyInstanceId) + "?ric=" + ric;
         return this.httpClient.put<PolicyInstanceAck>(url, policyJson, { observe: 'response' });
     }
 
@@ -101,4 +101,10 @@ export class PolicyService {
         const url = this.buildPath(this.policyTypePath, policyTypeId, this.policyPath, policyInstanceId);
         return this.httpClient.delete(url, { observe: 'response' });
     }
+
+
+    getRics(policyTypeId: string): Observable<string[]> {
+        const url = this.buildPath('rics') + '?policyType=' + policyTypeId;
+        return this.httpClient.get<any>(url);
+    }
 }
diff --git a/near-rt-ric-simulator/auto-test/.gitignore b/near-rt-ric-simulator/auto-test/.gitignore
new file mode 100644 (file)
index 0000000..1c5ae4e
--- /dev/null
@@ -0,0 +1,2 @@
+logs
+.tmp_*
\ No newline at end of file
diff --git a/near-rt-ric-simulator/auto-test/FTC1.sh b/near-rt-ric-simulator/auto-test/FTC1.sh
new file mode 100755 (executable)
index 0000000..180682b
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+TC_ONELINE_DESCR="Auto test for policy agent with simulator"
+
+. ../common/testcase_common.sh $1 $2
+
+clean_containers
+
+start_simulators
+
+consul_config_app         "../simulator-group/consul_cbs/config.json"
+
+start_policy_agent
+
+check_policy_agent_logs
+
+#### TEST COMPLETE ####
+
+store_logs          END
+
diff --git a/near-rt-ric-simulator/common/test_env.sh b/near-rt-ric-simulator/common/test_env.sh
new file mode 100755 (executable)
index 0000000..0ea885b
--- /dev/null
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+# Local image and tag, shall point to locally built image (non-nexus path)
+export POLICY_AGENT_LOCAL_IMAGE=o-ran-sc/policy-agent
+
+
+# Common env var for auto-test.
+
+POLICY_AGENT_PORT=8081
+POLICY_AGENT_LOGPATH="/var/log/policy-agent/application.log"  #Path the application log in the policy agent container
+DOCKER_SIM_NWNAME="nonrtric-docker-net"             #Name of docker private network
+CONSUL_HOST="consul-server"            #Host name of consul
+CONSUL_PORT=8500                       #Port number of consul
+CONFIG_BINDING_SERVICE="config-binding-service"  #Host name of CBS
+PA_APP_BASE="policy-agent"
diff --git a/near-rt-ric-simulator/common/testcase_common.sh b/near-rt-ric-simulator/common/testcase_common.sh
new file mode 100755 (executable)
index 0000000..6f2097e
--- /dev/null
@@ -0,0 +1,252 @@
+#!/usr/bin/env bash
+
+. ../common/test_env.sh
+
+echo "Test case started as: ${BASH_SOURCE[$i+1]} "$1 $2
+
+STARTED_POLICY_AGENT="" #Policy agent app names added to this var to keep track of started container in the script
+START_ARG=$1
+IMAGE_TAG="1.0.0-SNAPSHOT"
+
+if [ $# -lt 1 ] || [ $# -gt 2 ]; then
+       echo "Expected arg: local [<image-tag>] ]| remote [<image-tag>] ]| remote-remove [<image-tag>]] | manual-container | manual-app"
+       exit 1
+elif [ $1 == "local" ]; then
+       if [ -z $POLICY_AGENT_LOCAL_IMAGE ]; then
+               echo "POLICY_AGENT_LOCAL_IMAGE not set in test_env"
+               exit 1
+       fi
+       POLICY_AGENT_IMAGE=$POLICY_AGENT_LOCAL_IMAGE":"$IMAGE_TAG
+fi
+
+# Set a description string for the test case
+if [ -z "$TC_ONELINE_DESCR" ]; then
+       TC_ONELINE_DESCR="<no-description>"
+       echo "No test case description found, TC_ONELINE_DESCR should be set on in the test script , using "$TC_ONELINE_DESCR
+fi
+
+ATC=$(basename "${BASH_SOURCE[$i+1]}" .sh)
+
+
+# Create the logs dir if not already created in the current dir
+if [ ! -d "logs" ]; then
+    mkdir logs
+fi
+
+TESTLOGS=$PWD/logs
+
+mkdir -p $TESTLOGS/$ATC
+
+TCLOG=$TESTLOGS/$ATC/TC.log
+exec &>  >(tee ${TCLOG})
+
+#Variables for counting tests as well as passed and failed tests
+RES_TEST=0
+RES_PASS=0
+RES_FAIL=0
+TCTEST_START=$SECONDS
+
+echo "-------------------------------------------------------------------------------------------------"
+echo "-----------------------------------      Test case: "$ATC
+echo "-----------------------------------      Started:   "$(date)
+echo "-------------------------------------------------------------------------------------------------"
+echo "-- Description: "$TC_ONELINE_DESCR
+echo "-------------------------------------------------------------------------------------------------"
+echo "-----------------------------------      Test case setup      -----------------------------------"
+
+
+if [ -z "$SIM_GROUP" ]; then
+               SIM_GROUP=$PWD/../simulator-group
+               if [ ! -d  $SIM_GROUP ]; then
+                       echo "Trying to set env var SIM_GROUP to dir 'simulator-group' in the integration repo, but failed."
+                       echo "Please set the SIM_GROUP manually in the test_env.sh"
+                       exit 1
+               else
+                       echo "SIM_GROUP auto set to: " $SIM_GROUP
+               fi
+elif [ $SIM_GROUP = *simulator_group ]; then
+                       echo "Env var SIM_GROUP does not seem to point to dir 'simulator-group' in the integration repo, check test_env.sh"
+                       exit 1
+fi
+
+echo ""
+
+if [ $1 !=  "manual-container" ] && [ $1 !=  "manual-app" ]; then
+       echo -e "Policy agent image tag set to: \033[1m" $IMAGE_TAG"\033[0m"
+       echo "Configured image for policy agent app(s) (${1}): "$POLICY_AGENT_LOCAL_IMAGE
+       tmp_im=$(docker images ${POLICY_AGENT_LOCAL_IMAGE} | grep -v REPOSITORY)
+
+       if [ $1 == "local" ]; then
+               if [ -z "$tmp_im" ]; then
+                       echo "Local image (non nexus) "$POLICY_AGENT_LOCAL_IMAGE" does not exist in local registry, need to be built"
+                       exit 1
+               else
+                       echo -e "Policy agent local image: \033[1m"$tmp_im"\033[0m"
+                       echo "If the policy agen image seem outdated, rebuild the image and run the test again."
+               fi
+       fi
+fi
+
+
+
+__consul_config() {
+
+       appname=$PA_APP_BASE
+
+       echo "Configuring consul for " $appname " from " $1
+       curl -s http://127.0.0.1:${CONSUL_PORT}/v1/kv/${appname}?dc=dc1 -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -H 'X-Requested-With: XMLHttpRequest' --data-binary "@"$1 >/dev/null
+}
+
+
+consul_config_app() {
+
+    __consul_config $1
+
+}
+
+# Start all simulators in the simulator group
+start_simulators() {
+
+       echo "Starting all simulators"
+       curdir=$PWD
+       cd $SIM_GROUP
+       $SIM_GROUP/simulators-start.sh
+       cd $curdir
+       echo ""
+}
+
+clean_containers() {
+       echo "Stopping all containers, policy agent app(s) and simulators with name prefix 'policy_agent'"
+       docker stop $(docker ps -q --filter name=/policy-agent) &> /dev/null
+       echo "Removing all containers, policy agent app and simulators with name prefix 'policy_agent'"
+       docker rm $(docker ps -a -q --filter name=/policy-agent) &> /dev/null
+       echo "Removing unused docker networks with substring 'policy agent' in network name"
+       docker network rm $(docker network ls -q --filter name=nonrtric)
+       echo ""
+}
+
+start_policy_agent() {
+
+       appname=$PA_APP_BASE
+
+       if [ $START_ARG == "local" ] ; then
+               __start_policy_agent_image $appname
+       fi
+}
+
+__start_policy_agent_image() {
+
+       appname=$1
+       localport=$POLICY_AGENT_PORT
+
+       echo "Creating docker network $DOCKER_SIM_NWNAME, if needed"
+
+       docker network ls| grep $DOCKER_SIM_NWNAME > /dev/null || docker network create $DOCKER_SIM_NWNAME
+
+       echo "Starting policy agent: " $appname " with ports mapped to " $localport " in docker network "$DOCKER_SIM_NWNAME
+       docker run -d -p $localport":8081" --network=$DOCKER_SIM_NWNAME -e CONSUL_HOST=$CONSUL_HOST -e CONSUL_PORT=$CONSUL_PORT -e CONFIG_BINDING_SERVICE=$CONFIG_BINDING_SERVICE -e HOSTNAME=$appname --name $appname $POLICY_AGENT_IMAGE
+       #docker run -d -p 8081:8081 --network=nonrtric-docker-net -e CONSUL_HOST=CONSUL_HOST=$CONSUL_HOST -e CONSUL_PORT=$CONSUL_PORT -e CONFIG_BINDING_SERVICE=$CONFIG_BINDING_SERVICE -e HOSTNAME=policy-agent
+       sleep 3
+       set +x
+       pa_started=false
+       for i in {1..10}; do
+               if [ $(docker inspect --format '{{ .State.Running }}' $appname) ]
+                       then
+                               echo " Image: $(docker inspect --format '{{ .Config.Image }}' ${appname})"
+                               echo "Policy Agent container ${appname} running"
+                               pa_started=true
+                               break
+                       else
+                               sleep $i
+               fi
+       done
+       if ! [ $pa_started  ]; then
+               echo "Policy Agent container ${appname} could not be started"
+               exit 1
+       fi
+
+       pa_st=false
+       echo "Waiting for Policy Agent ${appname} service status..."
+       for i in {1..10}; do
+               result="$(__do_curl http://127.0.0.1:${localport}/status)"
+               if [ $? -eq 0 ]; then
+                       echo "Policy Agent ${appname} responds to service status: " $result
+                       pa_st=true
+                       break
+               else
+                       sleep $i
+               fi
+       done
+
+       if [ "$pa_st" = "false"  ]; then
+               echo "Policy Agent ${appname} did not respond to service status"
+               exit 1
+       fi
+}
+
+check_policy_agent_logs() {
+
+               appname=$PA_APP_BASE
+               tmp=$(docker ps | grep $appname)
+               if ! [ -z "$tmp" ]; then  #Only check logs for running policy agent apps
+                       __check_policy_agent_log $appname
+               fi
+
+}
+
+__check_policy_agent_log() {
+       echo "Checking $1 log $POLICY_AGENT_LOGPATH for WARNINGs and ERRORs"
+       foundentries=$(docker exec -it $1 grep WARN /var/log/policy-agent/application.log | wc -l)
+       if [ $? -ne  0 ];then
+               echo "  Problem to search $1 log $POLICY_AGENT_LOGPATH"
+       else
+               if [ $foundentries -eq 0 ]; then
+                       echo "  No WARN entries found in $1 log $POLICY_AGENT_LOGPATH"
+               else
+                       echo -e "  Found \033[1m"$foundentries"\033[0m WARN entries in $1 log $POLICY_AGENT_LOGPATH"
+               fi
+       fi
+       foundentries=$(docker exec -it $1 grep ERR $POLICY_AGENT_LOGPATH | wc -l)
+       if [ $? -ne  0 ];then
+               echo "  Problem to search $1 log $POLICY_AGENT_LOGPATH"
+       else
+               if [ $foundentries -eq 0 ]; then
+                       echo "  No ERR entries found in $1 log $POLICY_AGENT_LOGPATH"
+               else
+                       echo -e "  Found \033[1m"$foundentries"\033[0m ERR entries in $1 log $POLICY_AGENT_LOGPATH"
+               fi
+       fi
+}
+
+store_logs() {
+       if [ $# != 1 ]; then
+       __print_err "need one arg, <file-prefix>"
+               exit 1
+       fi
+       echo "Storing all container logs and policy agent app log using prefix: "$1
+
+       docker logs polman_consul > $TESTLOGS/$ATC/$1_consul.log 2>&1
+       docker logs polman_cbs > $TESTLOGS/$ATC/$1_cbs.log 2>&1
+}
+
+__do_curl() {
+       res=$(curl -skw "%{http_code}" $1)
+       http_code="${res:${#res}-3}"
+       if [ ${#res} -eq 3 ]; then
+               echo "<no-response-from-server>"
+               return 1
+       else
+               if [ $http_code -lt 200 ] && [ $http_code -gt 299]; then
+                       echo "<not found, resp:${http_code}>"
+                       return 1
+               fi
+               if [ $# -eq 2 ]; then
+                       echo "${res:0:${#res}-3}" | xargs
+               else
+                       echo "${res:0:${#res}-3}"
+               fi
+
+               return 0
+       fi
+}
+
diff --git a/near-rt-ric-simulator/simulator-group/consul_cbs/consul/cbs_config.hcl b/near-rt-ric-simulator/simulator-group/consul_cbs/consul/cbs_config.hcl
new file mode 100644 (file)
index 0000000..9a9c0c4
--- /dev/null
@@ -0,0 +1,13 @@
+#server = true
+#bootstrap = true
+#client_addr = "0.0.0.0"
+
+service  {
+  # Name for CBS in consul, env var CONFIG_BINDING_SERVICE
+  # should be passed to policy agent app with this value
+  Name = "config-binding-service"
+  # Host name where CBS is running
+  Address = "config-binding-service"
+  # Port number where CBS is running
+  Port = 10000
+}
\ No newline at end of file
@@ -1,8 +1,8 @@
 service {
   # Name for CBS in consul, env var CONFIG_BINDING_SERVICE
-  # should be passed to dfc app with this value
+  # should be passed to policy agent app with this value
   # This is only to be used when contacting cbs via local host
-  # (typicall when dfc is executed as an application without a container)
+  # (typicall when policy agent is executed as an application without a container)
   Name = "config-binding-service-localhost"
   # Host name where CBS is running
   Address = "localhost"
@@ -22,6 +22,6 @@ services:
     ports:
     - 8500:8500/tcp
     volumes:
-    - /Users/yonwu/ORAN/nonrtric/near-rt-ric-simulator/consul_cbs/consul:/consul/config:rw
+    - /Users/yonwu/ORAN/nonrtric/near-rt-ric-simulator/simulator-group/consul_cbs/consul:/consul/config:rw
 version: '3.0'
 
diff --git a/near-rt-ric-simulator/simulator-group/simulators-start.sh b/near-rt-ric-simulator/simulator-group/simulators-start.sh
new file mode 100755 (executable)
index 0000000..7f83397
--- /dev/null
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+DOCKER_SIM_NWNAME="nonrtric-docker-net"
+echo "Creating docker network $DOCKER_SIM_NWNAME, if needed"
+docker network ls| grep $DOCKER_SIM_NWNAME > /dev/null || docker network create $DOCKER_SIM_NWNAME
+
+docker-compose -f consul_cbs/docker-compose-template.yml config > docker-compose.yml
+
+docker-compose up -d
\ No newline at end of file
index 7119f07..f28414c 100644 (file)
 # SPDX-License-Identifier: Apache-2.0
 # ============LICENSE_END=========================================================
 #
-FROM adoptopenjdk/openjdk11:latest
+FROM openjdk:11-jre-slim
 
 WORKDIR /opt/app/policy-agent
 RUN mkdir -p /var/log/policy-agent
 RUN mkdir -p /opt/app/policy-agent/etc/cert/
 
+EXPOSE 8081
 
 ADD /config/application.yaml /opt/app/policy-agent/config/
 ADD /target/policy-agent-1.0.0-SNAPSHOT.jar /opt/app/policy-agent/
@@ -30,6 +31,8 @@ ADD /target/policy-agent-1.0.0-SNAPSHOT.jar /opt/app/policy-agent/
 
 RUN chmod -R 777 /opt/app/policy-agent/config/
 
-ENTRYPOINT ["/usr/bin/java", "-jar", "/opt/app/policy-agent/policy-agent-1.0.0-SNAPSHOT.jar"]
+CMD ["java", "-jar", "/opt/app/policy-agent/policy-agent-1.0.0-SNAPSHOT.jar"]
+
+
 
 
index a2bb4bc..18158c3 100644 (file)
 <project
     xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
-    <groupId>org.oransc</groupId>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.1.6.RELEASE</version>
+        <relativePath />
+    </parent>
+    <groupId>org.o-ran-sc.nonrtric</groupId>
     <artifactId>policy-agent</artifactId>
     <version>1.0.0-SNAPSHOT</version>
     <licenses>
             <url>https://nexus.onap.org/content/repositories/releases/</url>
         </repository>
     </repositories>
-    <parent>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-starter-parent</artifactId>
-        <version>2.1.6.RELEASE</version>
-        <relativePath />
-    </parent>
+    <properties>
+        <java.version>11</java.version>
+        <springfox.version>2.8.0</springfox.version>
+        <immutable.version>2.7.1</immutable.version>
+        <sdk.version>1.1.6</sdk.version>
+        <swagger.version>2.0.0</swagger.version>
+        <json.version>20180130</json.version>
+        <awaitility.version>4.0.1</awaitility.version>
+        <maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
+        <formatter-maven-plugin.version>2.8.1</formatter-maven-plugin.version>
+        <spotless-maven-plugin.version>1.18.0</spotless-maven-plugin.version>
+        <docker-maven-plugin>0.30.0</docker-maven-plugin>
+    </properties>
     <dependencies>
         <dependency>
             <groupId>org.springframework.boot</groupId>
         <dependency>
             <groupId>io.swagger.core.v3</groupId>
             <artifactId>swagger-jaxrs2</artifactId>
-            <version>2.0.0</version>
+            <version>${swagger.version}</version>
         </dependency>
         <dependency>
             <groupId>io.swagger.core.v3</groupId>
             <artifactId>swagger-jaxrs2-servlet-initializer</artifactId>
-            <version>2.0.0</version>
+            <version>${swagger.version}</version>
         </dependency>
         <dependency>
             <groupId>io.springfox</groupId>
         <dependency>
             <groupId>org.json</groupId>
             <artifactId>json</artifactId>
-            <version>20180130</version>
+            <version>${json.version}</version>
         </dependency>
         <!--TEST -->
         <dependency>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.dcaegen2.services.sdk.rest.services</groupId>
+            <artifactId>cbs-client</artifactId>
+            <version>${sdk.version}</version>
+        </dependency>
         <!--REQUIRED TO GENERATE DOCUMENTATION -->
         <dependency>
             <groupId>io.springfox</groupId>
             <artifactId>springfox-swagger-ui</artifactId>
             <version>${springfox.version}</version>
         </dependency>
+        <!-- TEST -->
         <dependency>
-            <groupId>org.onap.dcaegen2.services.sdk.rest.services</groupId>
-            <artifactId>cbs-client</artifactId>
-            <version>${sdk.version}</version>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <version>${awaitility.version}</version>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>io.projectreactor</groupId>
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter-engine</artifactId>
-            <version>${junit-jupiter.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
-    <properties>
-        <java.version>11</java.version>
-        <springfox.version>2.8.0</springfox.version>
-        <immutable.version>2.7.1</immutable.version>
-        <sdk.version>1.1.6</sdk.version>
-        <junit-jupiter.version>5.4.0</junit-jupiter.version>
-    </properties>
     <build>
         <plugins>
             <plugin>
             <plugin>
                 <groupId>net.revelc.code.formatter</groupId>
                 <artifactId>formatter-maven-plugin</artifactId>
-                <version>2.8.1</version>
+                <version>${formatter-maven-plugin.version}</version>
                 <configuration>
                     <configFile>${project.basedir}/eclipse-formatter.xml</configFile>
                 </configuration>
-                <!-- https://code.revelc.net/formatter-maven-plugin/ use 
-                 mvn formatter:format spotless:apply process-sources -->
+                <!-- https://code.revelc.net/formatter-maven-plugin/ use
+                    mvn formatter:format spotless:apply process-sources -->
             </plugin>
             <plugin>
                 <groupId>com.diffplug.spotless</groupId>
                 <artifactId>spotless-maven-plugin</artifactId>
-                <version>1.18.0</version>
+                <version>${spotless-maven-plugin.version}</version>
                 <configuration>
                     <java>
-                        <removeUnusedImports/>
+                        <removeUnusedImports />
                         <importOrder>
                             <order>com,java,javax,org</order>
                         </importOrder>
                     </java>
                 </configuration>
-                <!-- https://github.com/diffplug/spotless/tree/master/plugin-maven use 
-                        mvn spotless:apply to rewrite source files use mvn spotless:check to validate 
-                        source files -->
+                <!-- https://github.com/diffplug/spotless/tree/master/plugin-maven
+                    use mvn spotless:apply to rewrite source files use mvn spotless:check to
+                    validate source files -->
             </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
-                <version>2.17</version>
                 <configuration>
                     <skipTests>false</skipTests>
                 </configuration>
             </plugin>
             <plugin>
-                <groupId>com.spotify</groupId>
-                <artifactId>dockerfile-maven-plugin</artifactId>
-                <configuration>
-                    <repository>oransc/policy-agent</repository>
-                    <tag>${project.version}</tag>
-                    <buildArgs>
-                        <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
-                    </buildArgs>
-                </configuration>
+                <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                     </execution>
                 </executions>
             </plugin>
+            <plugin>
+                <groupId>io.fabric8</groupId>
+                <artifactId>docker-maven-plugin</artifactId>
+                <version>${docker-maven-plugin}</version>
+                <inherited>false</inherited>
+                <executions>
+                    <execution>
+                        <id>push-policy-agent-image</id>
+                        <goals>
+                            <goal>build</goal>
+                            <goal>push</goal>
+                        </goals>
+                        <configuration>
+                            <pullRegistry>${env.CONTAINER_PULL_REGISTRY}</pullRegistry>
+                            <pushRegistry>${env.CONTAINER_PUSH_REGISTRY}</pushRegistry>
+                            <images>
+                                <image>
+                                    <name>o-ran-sc/policy-agent:${project.version}</name>
+                                    <build>
+                                        <contextDir>${basedir}</contextDir>
+                                        <dockerFile>Dockerfile</dockerFile>
+                                        <tags>
+                                            <tag>${project.version}</tag>
+                                        </tags>
+                                    </build>
+                                </image>
+                            </images>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
     </build>
+    <issueManagement>
+        <system>JIRA</system>
+        <url>https://jira.o-ran-sc.org/</url>
+    </issueManagement>
 </project>
index fdfca61..6d8cd99 100644 (file)
@@ -41,8 +41,9 @@ public class Application {
     /**
      * Starts the service and reads the configuration.
      *
-     * @param ctx
-     * @return
+     * @param ctx the application context.
+     *
+     * @return the command line runner performing tasks at startup.
      */
     @Bean
     public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
@@ -51,5 +52,4 @@ public class Application {
             startupService.startup();
         };
     }
-
 }
index 637eac1..06b66ca 100644 (file)
@@ -20,6 +20,8 @@
 
 package org.oransc.policyagent;
 
+import org.oransc.policyagent.clients.A1Client;
+import org.oransc.policyagent.clients.A1ClientImpl;
 import org.oransc.policyagent.configuration.ApplicationConfig;
 import org.oransc.policyagent.repository.Policies;
 import org.oransc.policyagent.repository.PolicyTypes;
@@ -55,4 +57,9 @@ class BeanFactory {
         return new Services();
     }
 
+    @Bean
+    A1Client getA1Client() {
+        return new A1ClientImpl();
+    }
+
 }
index db048fb..0cc6903 100644 (file)
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
+
 package org.oransc.policyagent.clients;
 
-import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
-import java.util.List;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
-public class A1Client {
-    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-    public String getBaseUrl(final String nearRtRicUrl) {
-        return nearRtRicUrl + "/A1-P/v1";
-    }
-
-    public Flux<String> getAllPolicyTypes(String nearRtRicUrl) {
-        logger.debug("getAllPolicyTypes nearRtRicUrl = {}", nearRtRicUrl);
-        AsyncRestClient client = new AsyncRestClient(getBaseUrl(nearRtRicUrl));
-        Mono<String> response = client.get("/policytypes");
-        return response.flatMapMany(this::createPolicyTypesFlux);
-    }
-
-    public Flux<String> getPoliciesForType(String nearRtRicUrl, String policyTypeId) {
-        logger.debug("getPoliciesForType nearRtRicUrl = {}, policyTypeId = {}", nearRtRicUrl, policyTypeId);
-        AsyncRestClient client = new AsyncRestClient(getBaseUrl(nearRtRicUrl));
-        Mono<String> response = client.get("/policies");
-        return response.flatMapMany(policiesString -> createPoliciesFlux(policiesString, policyTypeId));
-    }
+public interface A1Client {
 
-    public Mono<String> getPolicy(String nearRtRicUrl, String policyId) {
-        logger.debug("getPolicy nearRtRicUrl = {}, policyId = {}", nearRtRicUrl, policyId);
-        AsyncRestClient client = new AsyncRestClient(getBaseUrl(nearRtRicUrl));
-        Mono<String> response = client.get("/policies/" + policyId);
-        return response.flatMap(this::createPolicyMono);
-    }
+    public Flux<String> getPolicyTypeIdentities(String nearRtRicUrl);
 
-    public Mono<String> putPolicy(String nearRtRicUrl, String policyId, String policyString) {
-        logger.debug("putPolicy nearRtRicUrl = {}, policyId = {}, policyString = {}", nearRtRicUrl, policyId,
-            policyString);
-        try {
-            new JSONObject(policyString);
-        } catch (JSONException ex) { // invalid json
-            return Mono.error(ex);
-        }
-        AsyncRestClient client = new AsyncRestClient(getBaseUrl(nearRtRicUrl));
-        Mono<String> response = client.put("/policies/" + policyId, policyString);
-        return response.flatMap(this::createPolicyMono);
-    }
+    public Flux<String> getPolicyIdentities(String nearRtRicUrl);
 
-    public Mono<Void> deletePolicy(String nearRtRicUrl, String policyId) {
-        logger.debug("deletePolicy nearRtRicUrl = {}, policyId = {}", nearRtRicUrl, policyId);
-        AsyncRestClient client = new AsyncRestClient(getBaseUrl(nearRtRicUrl));
-        return client.delete("/policies/" + policyId);
-    }
+    public Mono<String> getPolicyType(String nearRtRicUrl, String policyTypeId);
 
-    private Flux<String> createPolicyTypesFlux(String policyTypesString) {
-        try {
-            List<String> policyTypesList = new ArrayList<>();
-            JSONArray policyTypesArray = new JSONArray(policyTypesString);
-            for (int i = 0; i < policyTypesArray.length(); i++) {
-                policyTypesList.add(policyTypesArray.getJSONObject(i).toString());
-            }
-            logger.debug("A1 client: policyTypes = {}", policyTypesList);
-            return Flux.fromIterable(policyTypesList);
-        } catch (JSONException ex) { // invalid json
-            return Flux.error(ex);
-        }
-    }
+    public Mono<String> putPolicy(String nearRtRicUrl, String policyId, String policyString);
 
-    private Flux<String> createPoliciesFlux(String policiesString, String policyTypeId) {
-        try {
-            List<String> policiesList = new ArrayList<>();
-            JSONArray policiesArray = new JSONArray(policiesString);
-            for (int i = 0; i < policiesArray.length(); i++) {
-                JSONObject policyObject = policiesArray.getJSONObject(i);
-                if (policyObject.get("policyTypeId").equals(policyTypeId)) {
-                    policiesList.add(policyObject.toString());
-                }
-            }
-            logger.debug("A1 client: policies = {}", policiesList);
-            return Flux.fromIterable(policiesList);
-        } catch (JSONException ex) { // invalid json
-            return Flux.error(ex);
-        }
-    }
+    public Mono<Void> deletePolicy(String nearRtRicUrl, String policyId);
 
-    private Mono<String> createPolicyMono(String policyString) {
-        try {
-            JSONObject policyObject = new JSONObject(policyString);
-            String policy = policyObject.toString();
-            logger.debug("A1 client: policy = {}", policy);
-            return Mono.just(policy);
-        } catch (JSONException ex) { // invalid json
-            return Mono.error(ex);
-        }
-    }
 }
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
new file mode 100644 (file)
index 0000000..7bbb499
--- /dev/null
@@ -0,0 +1,107 @@
+/*-
+ * ========================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.clients;
+
+import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+public class A1ClientImpl implements A1Client {
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+    private static String getBaseUrl(final String nearRtRicUrl) {
+        return nearRtRicUrl + "/A1-P/v1";
+    }
+
+    @Override
+    public Flux<String> getPolicyTypeIdentities(String nearRtRicUrl) {
+        logger.debug("getPolicyTypeIdentities nearRtRicUrl = {}", nearRtRicUrl);
+        AsyncRestClient client = new AsyncRestClient(getBaseUrl(nearRtRicUrl));
+        Mono<String> response = client.get("/policytypes/identities");
+        return response.flatMapMany(this::createFlux);
+    }
+
+    @Override
+    public Flux<String> getPolicyIdentities(String nearRtRicUrl) {
+        logger.debug("getPolicyIdentities nearRtRicUrl = {}", nearRtRicUrl);
+        AsyncRestClient client = new AsyncRestClient(getBaseUrl(nearRtRicUrl));
+        Mono<String> response = client.get("/policies/identities");
+        return response.flatMapMany(this::createFlux);
+    }
+
+    @Override
+    public Mono<String> getPolicyType(String nearRtRicUrl, String policyTypeId) {
+        logger.debug("getPolicyType nearRtRicUrl = {}, policyTypeId = {}", nearRtRicUrl, policyTypeId);
+        AsyncRestClient client = new AsyncRestClient(getBaseUrl(nearRtRicUrl));
+        Mono<String> response = client.get("/policytypes/" + policyTypeId);
+        return response.flatMap(this::createMono);
+    }
+
+    @Override
+    public Mono<String> putPolicy(String nearRtRicUrl, String policyId, String policyString) {
+        logger.debug("putPolicy nearRtRicUrl = {}, policyId = {}, policyString = {}", nearRtRicUrl, policyId,
+            policyString);
+        AsyncRestClient client = new AsyncRestClient(getBaseUrl(nearRtRicUrl));
+        Mono<String> response = client.put("/policies/" + policyId, policyString);
+        return response.flatMap(this::createMono);
+    }
+
+    @Override
+    public Mono<Void> deletePolicy(String nearRtRicUrl, String policyId) {
+        logger.debug("deletePolicy nearRtRicUrl = {}, policyId = {}", nearRtRicUrl, policyId);
+        AsyncRestClient client = new AsyncRestClient(getBaseUrl(nearRtRicUrl));
+        return client.delete("/policies/" + policyId);
+    }
+
+    private Flux<String> createFlux(String inputString) {
+        try {
+            List<String> arrayList = new ArrayList<>();
+            JSONArray jsonArray = new JSONArray(inputString);
+            for (int i = 0; i < jsonArray.length(); i++) {
+                arrayList.add(jsonArray.getString(i));
+            }
+            logger.debug("A1 client: received list = {}", arrayList);
+            return Flux.fromIterable(arrayList);
+        } catch (JSONException ex) { // invalid json
+            return Flux.error(ex);
+        }
+    }
+
+    private Mono<String> createMono(String inputString) {
+        try {
+            JSONObject jsonObject = new JSONObject(inputString);
+            String jsonString = jsonObject.toString();
+            logger.debug("A1 client: received string = {}", jsonString);
+            return Mono.just(jsonString);
+        } catch (JSONException ex) { // invalid json
+            return Mono.error(ex);
+        }
+    }
+}
index 2e6df94..1aa2ef4 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.oransc.policyagent.clients;
 
-import org.oransc.policyagent.exceptions.AsyncRestClientException;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.web.reactive.function.client.WebClient;
@@ -28,6 +27,15 @@ import reactor.core.publisher.Mono;
 public class AsyncRestClient {
     private final WebClient client;
 
+    private static class AsyncRestClientException extends Exception {
+
+        private static final long serialVersionUID = 1L;
+
+        public AsyncRestClientException(String message) {
+            super(message);
+        }
+    }
+
     public AsyncRestClient(String baseUrl) {
         this.client = WebClient.create(baseUrl);
     }
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/RicClient.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/RicClient.java
deleted file mode 100644 (file)
index 709c023..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*-
- * ========================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.clients;
-
-import java.util.Vector;
-
-import org.oransc.policyagent.repository.PolicyType;
-import org.springframework.stereotype.Service;
-
-@Service
-public class RicClient {
-
-    public void deleteAllPolicies(String url) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public Vector<PolicyType> getPolicyTypes(String url) {
-        return new Vector<>();
-    }
-
-}
index c5cd44a..e41f55e 100644 (file)
@@ -194,5 +194,4 @@ public class ApplicationConfig {
     InputStream createInputStream(@NotNull String filepath) throws IOException {
         return new BufferedInputStream(new FileInputStream(filepath));
     }
-
 }
index 890b2a4..8c6964e 100644 (file)
@@ -17,6 +17,7 @@
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
+
 package org.oransc.policyagent.controllers;
 
 import com.google.gson.Gson;
@@ -179,7 +180,6 @@ public class PolicyController {
         Vector<PolicyTypeInfo> v = new Vector<>(types.size());
         for (PolicyType t : types) {
             PolicyTypeInfo policyInfo = ImmutablePolicyTypeInfo.builder() //
-                .schema(t.jsonSchema()) //
                 .name(t.name()) //
                 .build();
             v.add(policyInfo);
index eb54ba9..ed705dc 100644 (file)
@@ -17,8 +17,8 @@
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
-package org.oransc.policyagent.controllers;
 
+package org.oransc.policyagent.controllers;
 
 import org.immutables.gson.Gson;
 import org.immutables.value.Value;
index efd749a..35c8f66 100644 (file)
@@ -17,8 +17,8 @@
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
-package org.oransc.policyagent.controllers;
 
+package org.oransc.policyagent.controllers;
 
 import org.immutables.gson.Gson;
 import org.immutables.value.Value;
@@ -28,6 +28,4 @@ import org.immutables.value.Value;
 public interface PolicyTypeInfo {
 
     public String name();
-
-    public String schema();
 }
index 1139151..db9a4e5 100644 (file)
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
-package org.oransc.policyagent.controllers;
 
+package org.oransc.policyagent.controllers;
 
-import java.util.Vector;
+import java.util.Collection;
 
 import org.immutables.gson.Gson;
 import org.immutables.value.Value;
@@ -31,5 +31,7 @@ interface RicInfo {
 
     public String name();
 
-    public Vector<String> nodeNames();
+    public Collection<String> nodeNames();
+
+    public Collection<String> policyTypes();
 }
index cae588a..175d5eb 100644 (file)
@@ -91,13 +91,17 @@ public class RicRepositoryController {
         value = { //
             @ApiResponse(code = 200, message = "OK") //
         })
-    public ResponseEntity<String> getRics() {
+    public ResponseEntity<String> getRics(
+        @RequestParam(name = "policyType", required = false) String supportingPolicyType) {
         Vector<RicInfo> result = new Vector<>();
         for (Ric ric : rics.getRics()) {
-            result.add(ImmutableRicInfo.builder() //
-                .name(ric.name()) //
-                .nodeNames(ric.getManagedNodes()) //
-                .build());
+            if (supportingPolicyType == null || ric.isSupportingType(supportingPolicyType)) {
+                result.add(ImmutableRicInfo.builder() //
+                    .name(ric.name()) //
+                    .nodeNames(ric.getManagedNodes()) //
+                    .policyTypes(ric.getSupportedPolicyTypeNames()) //
+                    .build());
+            }
         }
 
         return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK);
index 86335b6..47123f2 100644 (file)
@@ -17,6 +17,7 @@
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
+
 package org.oransc.policyagent.controllers;
 
 import com.google.gson.Gson;
index fe920a9..2bc7e9b 100644 (file)
@@ -17,8 +17,8 @@
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
-package org.oransc.policyagent.controllers;
 
+package org.oransc.policyagent.controllers;
 
 import org.immutables.gson.Gson;
 import org.immutables.value.Value;
index 64647b8..3063c6b 100644 (file)
@@ -17,6 +17,7 @@
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
+
 package org.oransc.policyagent.controllers;
 
 import com.google.gson.annotations.SerializedName;
index 6f86173..226ee73 100644 (file)
@@ -17,6 +17,7 @@
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
+
 package org.oransc.policyagent.controllers;
 
 import io.swagger.annotations.ApiOperation;
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/exceptions/AsyncRestClientException.java b/policy-agent/src/main/java/org/oransc/policyagent/exceptions/AsyncRestClientException.java
deleted file mode 100644 (file)
index b5a6df3..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*-
- * ========================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.exceptions;
-
-public class AsyncRestClientException extends Exception {
-
-    private static final long serialVersionUID = 1L;
-
-    public AsyncRestClientException(String message) {
-        super(message);
-    }
-}
index daaa193..9895ff1 100644 (file)
@@ -26,12 +26,8 @@ import java.util.Map;
 import java.util.Vector;
 
 import org.oransc.policyagent.exceptions.ServiceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public class Policies {
-    private static final Logger logger = LoggerFactory.getLogger(Policies.class);
-
     private Map<String, Policy> policiesId = new HashMap<>();
     private Map<String, Map<String, Policy>> policiesRic = new HashMap<>();
     private Map<String, Map<String, Policy>> policiesService = new HashMap<>();
index 038e484..5148226 100644 (file)
@@ -17,6 +17,7 @@
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
+
 package org.oransc.policyagent.repository;
 
 import org.immutables.gson.Gson;
index 896e676..6b252d4 100644 (file)
@@ -27,7 +27,4 @@ import org.immutables.value.Value;
 @Gson.TypeAdapters
 public interface PolicyType {
     public String name();
-
-    public String jsonSchema();
-
 }
index 63450cb..0d66e7d 100644 (file)
@@ -44,8 +44,8 @@ public class PolicyTypes {
         types.put(type.name(), type);
     }
 
-    public boolean contains(PolicyType policyType) {
-        return types.containsKey(policyType.name());
+    public boolean contains(String policyType) {
+        return types.containsKey(policyType);
     }
 
     public synchronized Collection<PolicyType> getAll() {
index 3caadae..18a2dc7 100644 (file)
 
 package org.oransc.policyagent.repository;
 
-import java.util.Collections;
-import java.util.List;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Vector;
 
 import org.oransc.policyagent.configuration.RicConfig;
-import org.oransc.policyagent.repository.Ric.RicState;
 
 /**
  * Represents the dynamic information about a NearRealtime-RIC.
@@ -33,7 +33,7 @@ import org.oransc.policyagent.repository.Ric.RicState;
 public class Ric {
     private final RicConfig ricConfig;
     private RicState state = RicState.NOT_INITIATED;
-    private Vector<PolicyType> supportedPolicyTypes = new Vector<>();
+    private Map<String, PolicyType> supportedPolicyTypes = new HashMap<>();
 
     /**
      * Creates the Ric. Initial state is {@link RicState.NOT_INITIATED}.
@@ -56,6 +56,10 @@ public class Ric {
         state = newState;
     }
 
+    public RicConfig getConfig() {
+        return this.ricConfig;
+    }
+
     /**
      * Gets the nodes managed by this Ric.
      *
@@ -100,8 +104,12 @@ public class Ric {
      *
      * @return the policy types supported by this Ric in an unmodifiable list.
      */
-    public List<PolicyType> getSupportedPolicyTypes() {
-        return Collections.unmodifiableList(supportedPolicyTypes);
+    public Collection<PolicyType> getSupportedPolicyTypes() {
+        return supportedPolicyTypes.values();
+    }
+
+    public Collection<String> getSupportedPolicyTypeNames() {
+        return supportedPolicyTypes.keySet();
     }
 
     /**
@@ -110,9 +118,7 @@ public class Ric {
      * @param type the policy type to support.
      */
     public void addSupportedPolicyType(PolicyType type) {
-        if (!supportedPolicyTypes.contains(type)) {
-            supportedPolicyTypes.add(type);
-        }
+        supportedPolicyTypes.put(type.name(), type);
     }
 
     /**
@@ -120,7 +126,7 @@ public class Ric {
      *
      * @param types the policy types to support.
      */
-    public void addSupportedPolicyTypes(Vector<PolicyType> types) {
+    public void addSupportedPolicyTypes(Collection<PolicyType> types) {
         for (PolicyType type : types) {
             addSupportedPolicyType(type);
         }
@@ -132,18 +138,18 @@ public class Ric {
      * @param type the policy type to remove as supported by this Ric.
      */
     public void removeSupportedPolicyType(PolicyType type) {
-        supportedPolicyTypes.remove(type);
+        supportedPolicyTypes.remove(type.name());
     }
 
     /**
      * Checks if a type is supported by this Ric.
      *
-     * @param type the type to check if it is supported.
+     * @param typeName the name of the type to check if it is supported.
      *
-     * @return true if the given type issupported by this Ric, false otherwise.
+     * @return true if the given type is supported by this Ric, false otherwise.
      */
-    public boolean isSupportingType(PolicyType type) {
-        return supportedPolicyTypes.contains(type);
+    public boolean isSupportingType(String typeName) {
+        return supportedPolicyTypes.containsKey(typeName);
     }
 
     /**
@@ -157,14 +163,6 @@ public class Ric {
         /**
          * The Ric is working fine.
          */
-        ACTIVE,
-        /**
-         * Something is wrong with the Ric.
-         */
-        FAULTY,
-        /**
-         * The node is unreachable at the moment.
-         */
-        UNREACHABLE
+        ACTIVE
     }
 }
index 6a26b98..512d065 100644 (file)
@@ -17,6 +17,7 @@
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
+
 package org.oransc.policyagent.repository;
 
 import java.time.Duration;
index acb546b..3ab6152 100644 (file)
@@ -20,6 +20,7 @@
 
 package org.oransc.policyagent.tasks;
 
+import org.oransc.policyagent.clients.A1Client;
 import org.oransc.policyagent.repository.Policies;
 import org.oransc.policyagent.repository.Policy;
 import org.oransc.policyagent.repository.Service;
@@ -30,7 +31,9 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
+
 import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
 
 @Component
 @EnableScheduling
@@ -38,11 +41,13 @@ public class ServiceSupervision {
     private static final Logger logger = LoggerFactory.getLogger(ServiceSupervision.class);
     private final Services services;
     private final Policies policies;
+    private A1Client a1Client;
 
     @Autowired
-    public ServiceSupervision(Services services, Policies policies) {
+    public ServiceSupervision(Services services, Policies policies, A1Client a1Client) {
         this.services = services;
         this.policies = policies;
+        this.a1Client = a1Client;
     }
 
     @Scheduled(fixedRate = 1000 * 60)
@@ -63,16 +68,27 @@ public class ServiceSupervision {
         logger.debug("Checking services completed");
     }
 
-    Flux<Policy> createTask() {
+    private Flux<Policy> createTask() {
         return Flux.fromIterable(services.getAll()) //
             .filter(service -> service.isExpired()) //
             .doOnNext(service -> logger.info("Service is expired:" + service.getName()))
             .flatMap(service -> getAllPolicies(service)) //
-            .doOnNext(policy -> this.policies.remove(policy));
+            .doOnNext(policy -> this.policies.remove(policy)) //
+            .flatMap(policy -> deletePolicyInRic(policy));
     }
 
-    Flux<Policy> getAllPolicies(Service service) {
+    private Flux<Policy> getAllPolicies(Service service) {
         return Flux.fromIterable(policies.getForService(service.getName()));
     }
 
+    private Mono<Policy> deletePolicyInRic(Policy policy) {
+        return a1Client.deletePolicy(policy.ric().getConfig().baseUrl(), policy.id()) //
+            .onErrorResume(exception -> handleDeleteFromRicFailure(policy, exception)) //
+            .map((nothing) -> policy);
+    }
+
+    private Mono<Void> handleDeleteFromRicFailure(Policy policy, Throwable e) {
+        logger.warn("Could not delete policy: {} from ric: {}", policy.id(), policy.ric().name(), e);
+        return Mono.empty();
+    }
 }
index 1fa0aa8..f7420a0 100644 (file)
 
 package org.oransc.policyagent.tasks;
 
-import java.util.Vector;
-
-import org.oransc.policyagent.clients.RicClient;
+import org.oransc.policyagent.clients.A1Client;
 import org.oransc.policyagent.configuration.ApplicationConfig;
-import org.oransc.policyagent.configuration.RicConfig;
+import org.oransc.policyagent.repository.ImmutablePolicyType;
 import org.oransc.policyagent.repository.PolicyType;
 import org.oransc.policyagent.repository.PolicyTypes;
 import org.oransc.policyagent.repository.Ric;
@@ -35,6 +33,9 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
 /**
  * Loads information about RealTime-RICs at startup.
  */
@@ -53,13 +54,13 @@ public class StartupService {
     PolicyTypes policyTypes;
 
     @Autowired
-    private RicClient ricClient;
+    private A1Client a1Client;
 
-    StartupService(ApplicationConfig appConfig, Rics rics, PolicyTypes policyTypes, RicClient ricClient) {
+    StartupService(ApplicationConfig appConfig, Rics rics, PolicyTypes policyTypes, A1Client a1Client) {
         this.applicationConfig = appConfig;
         this.rics = rics;
         this.policyTypes = policyTypes;
-        this.ricClient = ricClient;
+        this.a1Client = a1Client;
     }
 
     /**
@@ -67,22 +68,56 @@ public class StartupService {
      */
     public void startup() {
         applicationConfig.initialize();
-        Vector<RicConfig> ricConfigs = applicationConfig.getRicConfigs();
-        for (RicConfig ricConfig : ricConfigs) {
-            Ric ric = new Ric(ricConfig);
-            String baseUrl = ricConfig.baseUrl();
-            ricClient.deleteAllPolicies(baseUrl);
-            Vector<PolicyType> types = ricClient.getPolicyTypes(baseUrl);
-            for (PolicyType policyType : types) {
-                if (!policyTypes.contains(policyType)) {
-                    policyTypes.put(policyType);
-                }
-            }
-            ric.addSupportedPolicyTypes(types);
-            ric.setState(RicState.ACTIVE);
-            rics.put(ric);
+        Flux.fromIterable(applicationConfig.getRicConfigs()) //
+            .map(ricConfig -> new Ric(ricConfig)) //
+            .doOnNext(ric -> logger.debug("Handling ric: {}", ric.getConfig().name())) //
+            .flatMap(this::addPolicyTypesForRic)
+            .flatMap(this::deletePoliciesForRic) //
+            .flatMap(this::setRicToActive) //
+            .flatMap(this::addRicToRepo) //
+            .subscribe();
+    }
+
+    private Mono<Ric> addPolicyTypesForRic(Ric ric) {
+        a1Client.getPolicyTypeIdentities(ric.getConfig().baseUrl()) //
+            .doOnNext(typeId -> logger.debug("For ric: {}, handling type: {}", ric.getConfig().name(), typeId))
+            .flatMap(this::addTypeToRepo) //
+            .flatMap(type -> addTypeToRic(ric, type)) //
+            .subscribe();
+        return Mono.just(ric);
+    }
+
+    private Mono<PolicyType> addTypeToRepo(String policyTypeId) {
+        ImmutablePolicyType type = ImmutablePolicyType.builder().name(policyTypeId).build();
+        if (!policyTypes.contains(policyTypeId)) {
+            policyTypes.put(type);
         }
+        return Mono.just(type);
+    }
 
+    private Mono<Void> addTypeToRic(Ric ric, PolicyType policyType) {
+        ric.addSupportedPolicyType(policyType);
+        return Mono.empty();
     }
 
+    private Mono<Ric> deletePoliciesForRic(Ric ric) {
+        a1Client.getPolicyIdentities(ric.getConfig().baseUrl()) //
+            .doOnNext(policyId -> logger.debug("deleting policy: {}, for ric: {}", policyId, ric.getConfig().name())) //
+            .flatMap(policyId -> a1Client.deletePolicy(ric.getConfig().baseUrl(), policyId)) //
+            .subscribe();
+
+        return Mono.just(ric);
+    }
+
+    private Mono<Ric> setRicToActive(Ric ric) {
+        ric.setState(RicState.ACTIVE);
+
+        return Mono.just(ric);
+    }
+
+    private Mono<Void> addRicToRepo(Ric ric) {
+        rics.put(ric);
+
+        return Mono.empty();
+    }
 }
index df26ba4..83ee760 100644 (file)
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
+
 package org.oransc.policyagent;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
@@ -30,9 +31,8 @@ import java.net.URL;
 import java.util.List;
 import java.util.Vector;
 
-import org.junit.Test;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 import org.oransc.policyagent.configuration.ApplicationConfig;
 import org.oransc.policyagent.configuration.ImmutableRicConfig;
 import org.oransc.policyagent.configuration.RicConfig;
@@ -55,15 +55,18 @@ 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.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
-import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
 import org.springframework.web.client.RestTemplate;
 
-@RunWith(SpringRunner.class)
+@ExtendWith(SpringExtension.class)
 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
 public class ApplicationTest {
+    @Autowired
+    ApplicationContext context;
 
     @Autowired
     private Rics rics;
@@ -87,7 +90,7 @@ public class ApplicationTest {
     }
 
     /**
-     * overrides the BeanFactory
+     * Overrides the BeanFactory.
      */
     @TestConfiguration
     static class TestBeanFactory {
@@ -96,6 +99,16 @@ public class ApplicationTest {
         public ApplicationConfig getApplicationConfig() {
             return new MockApplicationConfig();
         }
+
+        @Bean
+        public Rics getRics() {
+            Rics rics = new Rics();
+            rics.put(new Ric(ImmutableRicConfig.builder().name("kista_1").baseUrl("kista_url")
+                .managedElementIds(new Vector<>()).build()));
+            rics.put(new Ric(ImmutableRicConfig.builder().name("ric1").baseUrl("ric_url")
+                .managedElementIds(new Vector<>()).build()));
+            return rics;
+        }
     }
 
     @LocalServerPort
@@ -103,8 +116,7 @@ public class ApplicationTest {
 
     private final RestTemplate restTemplate = new RestTemplate();
 
-    @BeforeEach
-    public void reset() {
+    private void reset() {
         rics.clear();
         policies.clear();
         policyTypes.clear();
@@ -115,7 +127,13 @@ public class ApplicationTest {
     public void testGetRics() throws Exception {
         String url = baseUrl() + "/rics";
         String rsp = this.restTemplate.getForObject(url, String.class);
+        System.out.println(rsp);
         assertThat(rsp).contains("kista_1");
+
+        url = baseUrl() + "/rics?policyType=ANR";
+        rsp = this.restTemplate.getForObject(url, String.class);
+        // TODO this should test that the correct types are retrieved from the RIC
+        assertThat(rsp).isEqualTo("[]");
     }
 
     @Test
@@ -150,7 +168,6 @@ public class ApplicationTest {
 
     private PolicyType addPolicyType(String name) {
         PolicyType type = ImmutablePolicyType.builder() //
-            .jsonSchema("") //
             .name(name) //
             .build();
 
@@ -213,7 +230,7 @@ public class ApplicationTest {
         assertThat(policies.size()).isEqualTo(0);
     }
 
-    public static <T> List<T> parseList(String json, Class<T> clazz) {
+    private static <T> List<T> parseList(String json, Class<T> clazz) {
         if (null == json) {
             return null;
         }
@@ -222,11 +239,11 @@ public class ApplicationTest {
 
     @Test
     public void testGetPolicyTypes() throws Exception {
-        String url = baseUrl() + "/policy_types";
         reset();
         addPolicy("id1", "type1", "service1");
         addPolicy("id2", "type2", "service2");
 
+        String url = baseUrl() + "/policy_types";
         String rsp = this.restTemplate.getForObject(url, String.class);
         System.out.println(rsp);
         assertThat(rsp).contains("type1");
index d02522c..d7b9fec 100644 (file)
@@ -17,6 +17,7 @@
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
+
 package org.oransc.policyagent;
 
 import com.google.gson.JsonObject;
@@ -26,12 +27,15 @@ import java.io.File;
 import java.io.IOException;
 import java.net.URL;
 import java.nio.file.Files;
+import java.util.Vector;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.oransc.policyagent.clients.A1Client;
 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.oransc.policyagent.repository.Rics;
@@ -43,6 +47,9 @@ import org.springframework.boot.web.server.LocalServerPort;
 import org.springframework.context.annotation.Bean;
 import org.springframework.test.context.junit4.SpringRunner;
 
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
 @RunWith(SpringRunner.class)
 @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
 public class MockPolicyAgent {
@@ -64,16 +71,89 @@ public class MockPolicyAgent {
         }
     }
 
+    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 Flux<String> getPolicyTypeIdentities(String nearRtRicUrl) {
+            Vector<String> result = new Vector<>();
+            for (PolicyType p : this.policyTypes.getAll()) {
+                result.add(p.name());
+            }
+            return Flux.fromIterable(result);
+        }
+
+        @Override
+        public Flux<String> getPolicyIdentities(String nearRtRicUrl) {
+            Vector<String> result = new Vector<>();
+            for (Policy p : this.policies.getAll()) {
+                result.add(p.id());
+            }
+            return Flux.fromIterable(result);
+        }
+
+        @Override
+        public Mono<String> getPolicyType(String nearRtRicUrl, String policyTypeId) {
+            try {
+                return Mono.just(this.policyTypes.getType(policyTypeId).toString());
+            } catch (Exception e) {
+                return Mono.error(e);
+            }
+        }
+
+        @Override
+        public Mono<String> putPolicy(String nearRtRicUrl, String policyId, String policyString) {
+            return Mono.just("OK");
+        }
+
+        @Override
+        public Mono<Void> deletePolicy(String nearRtRicUrl, String policyId) {
+            return Mono.error(new Exception("TODO We cannot use Void like this")); // TODO We cannot use Void like this
+        }
+
+    }
+
     /**
      * 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(this.policies, this.policyTypes);
+        }
+
+        @Bean
+        public Policies getPolicies() {
+            return this.policies;
+        }
+
+        @Bean
+        public PolicyTypes getPolicyTypes() {
+            return this.policyTypes;
+        }
+
+        @Bean
+        public Rics getRics() {
+            return this.rics;
+        }
+
     }
 
     @LocalServerPort
@@ -113,7 +193,7 @@ public class MockPolicyAgent {
             try {
                 String schema = readFile(file);
                 String typeName = title(schema);
-                PolicyType type = ImmutablePolicyType.builder().name(typeName).jsonSchema(schema).build();
+                PolicyType type = ImmutablePolicyType.builder().name(typeName).build();
                 policyTypes.put(type);
             } catch (Exception e) {
                 System.out.println("Could not load json schema " + e);
index 34ebdf9..9cfb616 100644 (file)
 package org.oransc.policyagent.configuration;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -51,6 +50,11 @@ import java.util.Vector;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.mockito.junit.jupiter.MockitoExtension;
 import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsClient;
 import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.EnvProperties;
 import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.ImmutableEnvProperties;
@@ -61,10 +65,14 @@ import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 import reactor.test.StepVerifier;
 
+@ExtendWith(MockitoExtension.class)
+@RunWith(MockitoJUnitRunner.class)
 public class ApplicationConfigTest {
 
     private ApplicationConfig appConfigUnderTest;
-    CbsClient cbsClient = mock(CbsClient.class);
+
+    @Mock
+    CbsClient cbsClient;
 
     public static final ImmutableRicConfig CORRECT_RIC_CONIFG = ImmutableRicConfig.builder() //
         .name("ric1") //
index 4dcceb6..045a8c7 100644 (file)
 
 package org.oransc.policyagent.tasks;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 import static org.oransc.policyagent.repository.Ric.RicState.ACTIVE;
 
 import java.util.Vector;
 
 import org.junit.jupiter.api.Test;
-import org.oransc.policyagent.clients.RicClient;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.oransc.policyagent.clients.A1Client;
 import org.oransc.policyagent.configuration.ApplicationConfig;
 import org.oransc.policyagent.configuration.ImmutableRicConfig;
 import org.oransc.policyagent.configuration.RicConfig;
@@ -43,6 +49,11 @@ import org.oransc.policyagent.repository.PolicyTypes;
 import org.oransc.policyagent.repository.Ric;
 import org.oransc.policyagent.repository.Rics;
 
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@ExtendWith(MockitoExtension.class)
+@RunWith(MockitoJUnitRunner.class)
 public class StartupServiceTest {
     private static final String FIRST_RIC_NAME = "first";
     private static final String FIRST_RIC_URL = "firstUrl";
@@ -53,65 +64,72 @@ public class StartupServiceTest {
     private static final String MANAGED_NODE_C = "nodeC";
 
     private static final String POLICY_TYPE_1_NAME = "type1";
+    private static final PolicyType POLICY_TYPE_1 = ImmutablePolicyType.builder().name(POLICY_TYPE_1_NAME).build();
     private static final String POLICY_TYPE_2_NAME = "type2";
+    private static final PolicyType POLICY_TYPE_2 = ImmutablePolicyType.builder().name(POLICY_TYPE_2_NAME).build();
+    private static final String POLICY_ID_1 = "policy1";
+    private static final String POLICY_ID_2 = "policy2";
 
+    @Mock
     ApplicationConfig appConfigMock;
 
+    @Mock
+    A1Client a1ClientMock;
+
     @Test
     public void startup_allOk() throws ServiceException {
-        ApplicationConfig appConfigMock = mock(ApplicationConfig.class);
         Vector<RicConfig> ricConfigs = new Vector<>(2);
         ricConfigs.add(getRicConfig(FIRST_RIC_NAME, FIRST_RIC_URL, MANAGED_NODE_A));
         ricConfigs.add(getRicConfig(SECOND_RIC_NAME, SECOND_RIC_URL, MANAGED_NODE_B, MANAGED_NODE_C));
         when(appConfigMock.getRicConfigs()).thenReturn(ricConfigs);
 
-        Vector<PolicyType> firstTypes = new Vector<>();
-        PolicyType type1 = ImmutablePolicyType.builder().name(POLICY_TYPE_1_NAME).jsonSchema("{}").build();
-        firstTypes.add(type1);
-        Vector<PolicyType> secondTypes = new Vector<>();
-        secondTypes.add(type1);
-        PolicyType type2 = ImmutablePolicyType.builder().name(POLICY_TYPE_2_NAME).jsonSchema("{}").build();
-        secondTypes.add(type2);
-        RicClient ricClientMock = mock(RicClient.class);
-        when(ricClientMock.getPolicyTypes(FIRST_RIC_URL)).thenReturn(firstTypes);
-        when(ricClientMock.getPolicyTypes("secondUrl")).thenReturn(secondTypes);
+        Flux<String> fluxType1 = Flux.just(POLICY_TYPE_1_NAME);
+        Flux<String> fluxType2 = Flux.just(POLICY_TYPE_2_NAME);
+        when(a1ClientMock.getPolicyTypeIdentities(anyString())).thenReturn(fluxType1)
+            .thenReturn(fluxType1.concatWith(fluxType2));
+        Flux<String> policies = Flux.just(new String[] {POLICY_ID_1, POLICY_ID_2});
+        when(a1ClientMock.getPolicyIdentities(anyString())).thenReturn(policies);
+        when(a1ClientMock.deletePolicy(anyString(), anyString())).thenReturn(Mono.empty());
 
         Rics rics = new Rics();
         PolicyTypes policyTypes = new PolicyTypes();
-        StartupService serviceUnderTest = new StartupService(appConfigMock, rics, policyTypes, ricClientMock);
+        StartupService serviceUnderTest = new StartupService(appConfigMock, rics, policyTypes, a1ClientMock);
 
         serviceUnderTest.startup();
 
-        verify(ricClientMock).deleteAllPolicies(FIRST_RIC_URL);
-        verify(ricClientMock).getPolicyTypes(FIRST_RIC_URL);
-        verify(ricClientMock).deleteAllPolicies(SECOND_RIC_URL);
-        verify(ricClientMock).getPolicyTypes(SECOND_RIC_URL);
-        verifyNoMoreInteractions(ricClientMock);
+        await().untilAsserted(() -> assertThat(policyTypes.size()).isEqualTo(2));
+
+        verify(a1ClientMock).getPolicyTypeIdentities(FIRST_RIC_URL);
+        verify(a1ClientMock).deletePolicy(FIRST_RIC_URL, POLICY_ID_1);
+        verify(a1ClientMock).deletePolicy(FIRST_RIC_URL, POLICY_ID_2);
+
+        verify(a1ClientMock).getPolicyTypeIdentities(SECOND_RIC_URL);
+        verify(a1ClientMock).deletePolicy(SECOND_RIC_URL, POLICY_ID_1);
+        verify(a1ClientMock).deletePolicy(SECOND_RIC_URL, POLICY_ID_2);
 
-        assertEquals("Not correct number of policy types added.", 2, policyTypes.size());
-        assertEquals("Not correct type added.", type1, policyTypes.getType(POLICY_TYPE_1_NAME));
-        assertEquals("Not correct type added.", type2, policyTypes.getType(POLICY_TYPE_2_NAME));
-        assertEquals("Correct nymber of Rics not added to Rics", 2, rics.size());
+        assertTrue(policyTypes.contains(POLICY_TYPE_1_NAME), POLICY_TYPE_1_NAME + " not added to PolicyTypes.");
+        assertTrue(policyTypes.contains(POLICY_TYPE_2_NAME), POLICY_TYPE_2_NAME + " not added to PolicyTypes.");
+        assertEquals(2, rics.size(), "Correct number of Rics not added to Rics");
 
         Ric firstRic = rics.getRic(FIRST_RIC_NAME);
-        assertNotNull("Ric \"" + FIRST_RIC_NAME + "\" not added to repositpry", firstRic);
-        assertEquals("Not correct Ric \"" + FIRST_RIC_NAME + "\" added to Rics", FIRST_RIC_NAME, firstRic.name());
-        assertEquals("Not correct state for \"" + FIRST_RIC_NAME + "\"", ACTIVE, firstRic.state());
-        assertEquals("Not correct no of types supported", 1, firstRic.getSupportedPolicyTypes().size());
-        assertTrue("Not correct type supported", firstRic.isSupportingType(type1));
-        assertEquals("Not correct no of managed nodes", 1, firstRic.getManagedNodes().size());
-        assertTrue("Not managed by node", firstRic.isManaging(MANAGED_NODE_A));
+        assertNotNull(firstRic, "Ric \"" + FIRST_RIC_NAME + "\" not added to repositpry");
+        assertEquals(FIRST_RIC_NAME, firstRic.name(), "Not correct Ric \"" + FIRST_RIC_NAME + "\" added to Rics");
+        assertEquals(ACTIVE, firstRic.state(), "Not correct state for \"" + FIRST_RIC_NAME + "\"");
+        assertEquals(1, firstRic.getSupportedPolicyTypes().size(), "Not correct no of types supported");
+        assertTrue(firstRic.isSupportingType(POLICY_TYPE_1_NAME), "Not correct type supported");
+        assertEquals(1, firstRic.getManagedNodes().size(), "Not correct no of managed nodes");
+        assertTrue(firstRic.isManaging(MANAGED_NODE_A), "Not managed by node");
 
         Ric secondRic = rics.getRic(SECOND_RIC_NAME);
-        assertNotNull("Ric \"" + SECOND_RIC_NAME + "\" not added to repositpry", secondRic);
-        assertEquals("Not correct Ric \"" + SECOND_RIC_NAME + "\" added to Rics", SECOND_RIC_NAME, secondRic.name());
-        assertEquals("Not correct state for \"" + SECOND_RIC_NAME + "\"", ACTIVE, secondRic.state());
-        assertEquals("Not correct no of types supported", 2, secondRic.getSupportedPolicyTypes().size());
-        assertTrue("Not correct type supported", secondRic.isSupportingType(type1));
-        assertTrue("Not correct type supported", secondRic.isSupportingType(type2));
-        assertEquals("Not correct no of managed nodes", 2, secondRic.getManagedNodes().size());
-        assertTrue("Not correct managed node", secondRic.isManaging(MANAGED_NODE_B));
-        assertTrue("Not correct managed node", secondRic.isManaging(MANAGED_NODE_C));
+        assertNotNull(secondRic, "Ric \"" + SECOND_RIC_NAME + "\" not added to repositpry");
+        assertEquals(SECOND_RIC_NAME, secondRic.name(), "Not correct Ric \"" + SECOND_RIC_NAME + "\" added to Rics");
+        assertEquals(ACTIVE, secondRic.state(), "Not correct state for \"" + SECOND_RIC_NAME + "\"");
+        assertEquals(2, secondRic.getSupportedPolicyTypes().size(), "Not correct no of types supported");
+        assertTrue(secondRic.isSupportingType(POLICY_TYPE_1_NAME), "Not correct type supported");
+        assertTrue(secondRic.isSupportingType(POLICY_TYPE_2_NAME), "Not correct type supported");
+        assertEquals(2, secondRic.getManagedNodes().size(), "Not correct no of managed nodes");
+        assertTrue(secondRic.isManaging(MANAGED_NODE_B), "Not correct managed node");
+        assertTrue(secondRic.isManaging(MANAGED_NODE_C), "Not correct managed node");
     }
 
     private RicConfig getRicConfig(String name, String baseUrl, String... nodeNames) {
diff --git a/policy-agent/src/test/resources/policy_types/anr-policy-schema.json b/policy-agent/src/test/resources/policy_types/anr-policy-schema.json
new file mode 100644 (file)
index 0000000..6e0263d
--- /dev/null
@@ -0,0 +1,40 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "title": "ANR",
+  "description": "ANR Neighbour Cell Relation Policy",
+  "type": "object",
+  "properties": {
+    "servingCellNrcgi": {
+      "type": "string",
+      "description": "Serving Cell Identifier (NR CGI)"
+    },
+    "neighborCellNrpci": {
+      "type": "string",
+      "description": "Neighbor Cell Identifier (NR PCI)"
+    },
+    "neighborCellNrcgi": {
+      "type": "string",
+      "description": "Neighbor Cell Identifier (NR CGI)"
+    },
+    "flagNoHo": {
+      "type": "boolean",
+      "description": "Flag for HANDOVER NOT ALLOWED"
+    },
+    "flagNoXn": {
+      "type": "boolean",
+      "description": "Flag for Xn CONNECTION NOT ALLOWED"
+    },
+    "flagNoRemove": {
+      "type": "boolean",
+      "description": "Flag for DELETION NOT ALLOWED"
+    }
+  },
+  "required": [
+    "servingCellNrcgi",
+    "neighborCellNrpci",
+    "neighborCellNrcgi",
+    "flagNoHo",
+    "flagNoXn",
+    "flagNoRemove"
+  ]
+}
\ No newline at end of file
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
new file mode 100644 (file)
index 0000000..fa7410f
--- /dev/null
@@ -0,0 +1,42 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "title": "Example_QoSTarget_1.0.0",
+  "description": "Example QoS Target policy type",
+  "type": "object",
+  "properties": {
+    "scope": {
+      "type": "object",
+      "properties": {
+        "qosId": {
+          "type": "string"
+        },
+        "cellId": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "required": [
+        "qosId"
+      ]
+    },
+    "statement": {
+      "type": "object",
+      "properties": {
+        "gfbr": {
+          "type": "number"
+        },
+        "mfbr": {
+          "type": "number"
+        },
+        "priorityLevel": {
+          "type": "number"
+        },
+        "pdb": {
+          "type": "number"
+        }
+      },
+      "minProperties": 1,
+      "additionalProperties": false
+    }
+  }
+}
\ No newline at end of file
diff --git a/policy-agent/src/test/resources/policy_types/demo-policy-schema-2.json b/policy-agent/src/test/resources/policy_types/demo-policy-schema-2.json
new file mode 100644 (file)
index 0000000..f3eb28f
--- /dev/null
@@ -0,0 +1,49 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "title": "Example_QoETarget_1.0.0",
+  "description": "Example QoE Target policy type",
+  "type": "object",
+  "properties": {
+    "scope": {
+      "type": "object",
+      "properties": {
+        "ueId": {
+          "type": "string"
+        },
+        "sliceId": {
+          "type": "string"
+        },
+        "qosId": {
+          "type": "string"
+        },
+        "cellId": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "required": [
+        "ueId",
+        "sliceId"
+      ]
+    },
+    "statement": {
+      "type": "object",
+      "properties": {
+        "qoeScore": {
+          "type": "number"
+        },
+        "initialBuffering": {
+          "type": "number"
+        },
+        "reBuffFreq": {
+          "type": "number"
+        },
+        "stallRatio": {
+          "type": "number"
+        }
+      },
+      "minProperties": 1,
+      "additionalProperties": false
+    }
+  }
+}
\ No newline at end of file
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
new file mode 100644 (file)
index 0000000..695514c
--- /dev/null
@@ -0,0 +1,59 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "title": "Example_TrafficSteeringPreference_1.0.0",
+  "description": "Example QoE Target policy type",
+  "type": "object",
+  "properties": {
+    "scope": {
+      "type": "object",
+      "properties": {
+        "ueId": {
+          "type": "string"
+        },
+        "sliceId": {
+          "type": "string"
+        },
+        "qosId": {
+          "type": "string"
+        },
+        "cellId": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "required": [
+        "ueId"
+      ]
+    },
+    "statement": {
+      "type": "object",
+      "properties": {
+        "cellIdList": {
+          "type": "array",
+          "minItems": 1,
+          "uniqueItems": true,
+          "items": {
+            "type": "string"
+          }
+        },
+        "preference": {
+          "type": "string",
+          "enum": [
+            "SHALL",
+            "PREFER",
+            "AVOID",
+            "FORBID"
+          ]
+        },
+        "primary": {
+          "type": "boolean"
+        }
+      },
+      "required": [
+        "cellIdList",
+        "preference"
+      ],
+      "additionalProperties": false
+    }
+  }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index f7e42ab..0a9184f 100644 (file)
--- a/pom.xml
+++ b/pom.xml
   ============LICENSE_END=========================================================
 -->
 <project xmlns="http://maven.apache.org/POM/4.0.0"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-       <modelVersion>4.0.0</modelVersion>
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
 
-       <groupId>org.oransc</groupId>
-       <artifactId>nonrtric</artifactId>
-       <version>1.0.0-SNAPSHOT</version>
-       <packaging>pom</packaging>
+    <groupId>org.o-ran-sc</groupId>
+    <artifactId>nonrtric</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
 
-       <name>nonrtric</name>
-       <modules>
-               <module>dashboard</module>
-               <module>near-rt-ric-simulator</module>
-               <module>sdnc-a1-controller</module>
-                <module>policy-agent</module>
-       </modules>
-</project>
+    <name>nonrtric</name>
+    <modules>
+        <module>policy-agent</module>
+        <module>dashboard</module>
+        <module>near-rt-ric-simulator</module>
+    </modules>
+ </project>