Support of selecting RIC in dashboard 54/2054/1
authorPatrikBuhr <patrik.buhr@est.tech>
Wed, 18 Dec 2019 10:15:08 +0000 (11:15 +0100)
committerPatrikBuhr <patrik.buhr@est.tech>
Wed, 18 Dec 2019 10:15:43 +0000 (11:15 +0100)
Change-Id: I3b428fd1d45b03f0017177389c06c9591f0b237e
Issue-ID: NONRTRIC-84
Signed-off-by: PatrikBuhr <patrik.buhr@est.tech>
19 files changed:
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/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
policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java
policy-agent/src/main/java/org/oransc/policyagent/clients/AsyncRestClient.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/ServiceRegistrationInfo.java
policy-agent/src/main/java/org/oransc/policyagent/exceptions/AsyncRestClientException.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java
policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java
policy-agent/src/test/java/org/oransc/policyagent/tasks/StartupServiceTest.java

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 a2b5238..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;
 
@@ -123,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);
@@ -141,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 0736064..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
@@ -90,6 +91,15 @@ public class PolicyControllerMockConfiguration {
                        result.addAll(inst);
                        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 {
@@ -111,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
                        }
@@ -136,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 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);
+    }
 }
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);
     }
index 19e4332..db9a4e5 100644 (file)
@@ -19,7 +19,8 @@
  */
 
 package org.oransc.policyagent.controllers;
-import java.util.Vector;
+
+import java.util.Collection;
 
 import org.immutables.gson.Gson;
 import org.immutables.value.Value;
@@ -30,5 +31,7 @@ interface RicInfo {
 
     public String name();
 
-    public Vector<String> nodeNames();
+    public Collection<String> nodeNames();
+
+    public Collection<String> policyTypes();
 }
index 960532a..4c03218 100644 (file)
@@ -90,13 +90,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);
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 df612dc..68b07aa 100644 (file)
@@ -20,8 +20,9 @@
 
 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;
@@ -32,7 +33,7 @@ import org.oransc.policyagent.configuration.RicConfig;
 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}.
@@ -103,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();
     }
 
     /**
@@ -113,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);
     }
 
     /**
@@ -123,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);
         }
@@ -135,7 +138,7 @@ 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());
     }
 
     /**
@@ -145,8 +148,8 @@ public class Ric {
      *
      * @return true if the given type issupported by this Ric, false otherwise.
      */
-    public boolean isSupportingType(PolicyType type) {
-        return supportedPolicyTypes.contains(type);
+    public boolean isSupportingType(String typeName) {
+        return supportedPolicyTypes.containsKey(typeName);
     }
 
     /**
index b3e2c98..55597ea 100644 (file)
@@ -114,7 +114,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
index fd98e07..18ff62b 100644 (file)
@@ -98,7 +98,7 @@ public class StartupServiceTest {
         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(type1), "Not correct type supported");
+        assertTrue(firstRic.isSupportingType(type1.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");
 
@@ -107,8 +107,8 @@ public class StartupServiceTest {
         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(type1), "Not correct type supported");
-        assertTrue(secondRic.isSupportingType(type2), "Not correct type supported");
+        assertTrue(secondRic.isSupportingType(type1.name()), "Not correct type supported");
+        assertTrue(secondRic.isSupportingType(type2.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");