Use new get method from A1 API for AC policy 82/782/4
authorLott, Christopher (cl778h) <cl778h@att.com>
Fri, 23 Aug 2019 01:07:50 +0000 (21:07 -0400)
committerLott, Christopher (cl778h) <cl778h@att.com>
Sat, 24 Aug 2019 00:08:26 +0000 (20:08 -0400)
Upgrade A1 API spec to version 0.10.3 which defines object
  (not void) return value on the get-policy method.
Extend AC FE screen to read policy using get method.
Change controller name from AC to A1.
Ensure numeric values go as numbers, not strings.

Change-Id: I2cede67d499cb2d6a835d9a2938fedcafbe6eed4
Signed-off-by: Lott, Christopher (cl778h) <cl778h@att.com>
13 files changed:
a1-med-client/pom.xml
a1-med-client/src/main/resources/a1_mediator_0.10.3.yaml [moved from a1-med-client/src/main/resources/a1_mediator_0.10.0.yaml with 97% similarity]
a1-med-client/src/test/java/org/oransc/ric/portal/dashboard/a1med/client/test/A1MediatorClientTest.java
docs/release-notes.rst
webapp-backend/pom.xml
webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/WebSecurityConfiguration.java
webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/A1MediatorController.java [moved from webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AcXappController.java with 67% similarity]
webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/A1MediatorMockConfiguration.java
webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/A1MediatorControllerTest.java [moved from webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AcXappControllerTest.java with 77% similarity]
webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AdminControllerTest.java
webapp-frontend/src/app/ac-xapp/ac-xapp.component.html
webapp-frontend/src/app/ac-xapp/ac-xapp.component.ts
webapp-frontend/src/app/services/ac-xapp/ac-xapp.service.ts

index dd4a9e3..edb1b4e 100644 (file)
@@ -31,7 +31,7 @@ limitations under the License.
        <groupId>org.o-ran-sc.ric.plt.a1med.client</groupId>
        <artifactId>a1-med-client</artifactId>
        <name>RIC A1 Mediator client</name>
-       <version>0.10.0-SNAPSHOT</version>
+       <version>0.10.3-SNAPSHOT</version>
        <properties>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -102,7 +102,7 @@ limitations under the License.
                                                        <goal>generate</goal>
                                                </goals>
                                                <configuration>
-                                                       <inputSpec>${project.basedir}/src/main/resources/a1_mediator_0.10.0.yaml</inputSpec>
+                                                       <inputSpec>${project.basedir}/src/main/resources/a1_mediator_0.10.3.yaml</inputSpec>
                                                        <language>java</language>
                                                        <packageName>${client.base.package.name}</packageName>
                                                        <modelPackage>${client.base.package.name}.model</modelPackage>
@@ -16,7 +16,7 @@
 # ==================================================================================
 openapi: 3.0.0
 info:
-  version: 0.10.0
+  version: 0.10.3
   title: RIC A1
 paths:
   '/a1-p/healthcheck':
@@ -43,13 +43,11 @@ paths:
       description: >
           Replace the current operation of policyname with the new parameters (replaces the current policy with the new one specified here).
 
-
           Until there are standard policy definitions that are defined OUTSIDE of the scope of xapps, this API will be *very underspecified*.
           This is a known gap, do not despair.
           The PUT body is specified, *currently* in the xapp manifest that implements this policy; the caller should refer to the message_receives_payload_schema field to make this request.
           The return content is also specified as above (in the xapp manifest) in the message_sends_payload_schema field.
 
-
           Eventually, we need concrete policy defintions that are decoupled from xapp, and then this API description will become more fully specified.
       tags:
         - A1 Mediator
@@ -103,6 +101,10 @@ paths:
         '200':
           description: >
             The downstream component responsible for implementing this policy replied with a good response. Check the manifest for response details.
+          content:
+            application/json:
+              schema:
+                type: object
         '400':
           description: >
             The downstream component for implementing this policy does not support policy fetching.
index c09858e..73a28c8 100644 (file)
@@ -28,7 +28,7 @@ import org.springframework.web.client.RestClientException;
 /**
  * Demonstrates use of the generated A1 mediator client.
  * 
- * The test fails because no server is available.
+ * The tests fail because no server is available.
  */
 public class A1MediatorClientTest {
 
@@ -38,8 +38,17 @@ public class A1MediatorClientTest {
                apiClient.setBasePath("http://localhost:30099/");
                A1MediatorApi a1Api = new A1MediatorApi(apiClient);
                try {
-                       a1Api.a1ControllerGetHandler("policy");
-                       System.out.println("getPolicy answered: " + apiClient.getStatusCode().toString());
+                       Object o = a1Api.a1ControllerGetHandler("policy");
+                       System.out.println(
+                                       "getPolicy answered code {} " + apiClient.getStatusCode().toString() + ", content " + o.toString());
+                       Assertions.assertTrue(apiClient.getStatusCode().is2xxSuccessful());
+               } catch (RestClientException e) {
+                       System.err.println("getPolicy failed: " + e.toString());
+               }
+               try {
+                       String policy = "{}";
+                       a1Api.a1ControllerPutHandler("policy", policy);
+                       System.out.println("putPolicy answered: " + apiClient.getStatusCode().toString());
                        Assertions.assertTrue(apiClient.getStatusCode().is2xxSuccessful());
                } catch (RestClientException e) {
                        System.err.println("getPolicy failed: " + e.toString());
index 621a5e6..1e6deb4 100644 (file)
@@ -23,7 +23,7 @@ Version 1.2.1, ? Aug 2019
 -------------------------
 * Add EPSDK-FW user management and Portal security
 
-Version 1.2.0, 21 Aug 2019
+Version 1.2.0, 23 Aug 2019
 --------------------------
 * Split URL properties into prefix/suffix parts
 * Add jacoco plugin to back-end for code coverage
@@ -32,7 +32,6 @@ Version 1.2.0, 21 Aug 2019
 * Drop mock RAN names feature that supported R1 testing
 * Extend mock endpoints to simulate delay seen in tests
 * Move mock configuration classes into test area
-* Update A1 mediator client to spec version 0.10.0
 * Update App manager client to spec version 0.1.7
 * Update E2 manager client to spec version 20190815
 * Add controller for page refresh of Angular routes
@@ -46,6 +45,8 @@ Version 1.2.0, 21 Aug 2019
 * Display AC xAPP metrics data via Kibana source (metrics.url.ac) on dashboard
 * Pass AC policy parameter without parsing as JSON
 * Use snake_case (not camelCase) names in AC policy front end
+* Update A1 mediator client to spec version 0.10.3
+* Extend AC control screen to read policy from A1
 
 Version 1.0.5, 5 July 2019
 --------------------------
index 11f875a..08cc563 100644 (file)
@@ -52,7 +52,7 @@ limitations under the License.
                <dependency>
                        <groupId>org.o-ran-sc.ric.plt.a1med.client</groupId>
                        <artifactId>a1-med-client</artifactId>
-                       <version>0.10.0-SNAPSHOT</version>
+                       <version>0.10.3-SNAPSHOT</version>
                </dependency>
                <dependency>
                        <groupId>org.o-ran-sc.ric.plt.appmgr.client</groupId>
index 92ea75e..4e1ddb4 100644 (file)
@@ -27,7 +27,7 @@ import org.onap.portalsdk.core.onboarding.crossapi.PortalRestAPIProxy;
 import org.onap.portalsdk.core.onboarding.util.PortalApiConstants;
 import org.oransc.ric.portal.dashboard.DashboardConstants;
 import org.oransc.ric.portal.dashboard.LoginServlet;
-import org.oransc.ric.portal.dashboard.controller.AcXappController;
+import org.oransc.ric.portal.dashboard.controller.A1MediatorController;
 import org.oransc.ric.portal.dashboard.controller.AdminController;
 import org.oransc.ric.portal.dashboard.controller.AnrXappController;
 import org.oransc.ric.portal.dashboard.controller.AppManagerController;
@@ -93,7 +93,7 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
                        "/swagger-ui.html", //
                        "/webjars/**", //
                        PortalApiConstants.API_PREFIX + "/**", //
-                       AcXappController.CONTROLLER_PATH + "/" + AcXappController.VERSION_METHOD, //
+                       A1MediatorController.CONTROLLER_PATH + "/" + A1MediatorController.VERSION_METHOD, //
                        AdminController.CONTROLLER_PATH + "/" + AdminController.HEALTH_METHOD, //
                        AdminController.CONTROLLER_PATH + "/" + AdminController.VERSION_METHOD, //
                        AnrXappController.CONTROLLER_PATH + "/" + AnrXappController.HEALTH_ALIVE_METHOD, //
@@ -34,6 +34,7 @@ import org.springframework.http.MediaType;
 import org.springframework.security.access.annotation.Secured;
 import org.springframework.util.Assert;
 import org.springframework.web.bind.annotation.GetMapping;
+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;
@@ -43,7 +44,8 @@ import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 
 /**
- * Proxies calls from the front end to the AC xApp via the A1 Mediator API.
+ * Proxies calls from the front end to the A1 Mediator API to get and put
+ * policies. The first application managed via this path is Admission Control.
  * 
  * If a method throws RestClientResponseException, it is handled by
  * {@link CustomResponseEntityExceptionHandler#handleProxyMethodException(Exception, org.springframework.web.context.request.WebRequest)}
@@ -51,25 +53,23 @@ import io.swagger.annotations.ApiParam;
  * returns status 500.
  */
 @RestController
-@RequestMapping(value = AcXappController.CONTROLLER_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
-public class AcXappController {
+@RequestMapping(value = A1MediatorController.CONTROLLER_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
+public class A1MediatorController {
 
        private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
        // Publish paths in constants so tests are easy to write
-       public static final String CONTROLLER_PATH = DashboardConstants.ENDPOINT_PREFIX + "/xapp/admctl";
+       public static final String CONTROLLER_PATH = DashboardConstants.ENDPOINT_PREFIX + "/a1-p";
        // Endpoints
        public static final String VERSION_METHOD = DashboardConstants.VERSION_METHOD;
-       public static final String POLICY_METHOD = "policy";
-
-       // A "control" is an element in the XApp descriptor
-       private static final String AC_CONTROL_NAME = "admission_control_policy";
+       // Path parameters
+       public static final String PP_POLICIES = "policies";
 
        // Populated by the autowired constructor
        private final A1MediatorApi a1MediatorApi;
 
        @Autowired
-       public AcXappController(final A1MediatorApi a1MediatorApi) {
+       public A1MediatorController(final A1MediatorApi a1MediatorApi) {
                Assert.notNull(a1MediatorApi, "API must not be null");
                this.a1MediatorApi = a1MediatorApi;
                if (logger.isDebugEnabled())
@@ -84,31 +84,27 @@ public class AcXappController {
        }
 
        /*
-        * This controller is deliberately kept ignorant of the data expected by AC. The
-        * fields are defined in the ACAdmissionIntervalControl Typescript interface.
+        * This method is deliberately kept ignorant of the data passing thru.
         */
-       @ApiOperation(value = "Gets the admission control policy for AC xApp via the A1 Mediator")
-       @GetMapping(POLICY_METHOD)
+       @ApiOperation(value = "Gets the specified policy from the A1 Mediator")
+       @GetMapping(PP_POLICIES + "/{" + PP_POLICIES + "}")
        @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD })
-       public Object getAdmissionControlPolicy(HttpServletResponse response) {
-               logger.debug("getAdmissionControlPolicy");
-               response.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
-               return null;
+       public Object getPolicy(@PathVariable(PP_POLICIES) String policyName) {
+               logger.debug("getPolicy {}", policyName);
+               return a1MediatorApi.a1ControllerGetHandler(policyName);
        }
 
        /*
-        * This controller is deliberately kept ignorant of the data expected by AC. The
-        * fields are defined in the ACAdmissionIntervalControl Typescript interface. AC
-        * uses snake_case keys but Jackson automatically converts to CamelCase on
-        * parse. To avoid this conversion, specify the request parameter as String.
+        * This method is deliberately kept ignorant of the data passing thru.
         */
-       @ApiOperation(value = "Sets the admission control policy for AC xApp via the A1 Mediator")
-       @PutMapping(POLICY_METHOD)
+       @ApiOperation(value = "Puts the specified policy to the A1 Mediator")
+       @PutMapping(PP_POLICIES + "/{" + PP_POLICIES + "}")
        @Secured({ DashboardConstants.ROLE_ADMIN })
-       public void putAdmissionControlPolicy(@ApiParam(value = "Admission control policy") @RequestBody String acPolicy, //
+       public void putPolicy(@PathVariable(PP_POLICIES) String policyName,
+                       @ApiParam(value = "Policy body") @RequestBody String policy, //
                        HttpServletResponse response) {
-               logger.debug("putAdmissionControlPolicy {}", acPolicy);
-               a1MediatorApi.a1ControllerPutHandler(AC_CONTROL_NAME, acPolicy);
+               logger.debug("putPolicy name {} value {}", policyName, policy);
+               a1MediatorApi.a1ControllerPutHandler(policyName, policy);
                response.setStatus(a1MediatorApi.getApiClient().getStatusCode().value());
        }
 
index aef5bc4..bf74a91 100644 (file)
@@ -25,6 +25,8 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import java.lang.invoke.MethodHandles;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.oransc.ric.a1med.client.api.A1MediatorApi;
 import org.oransc.ric.a1med.client.invoker.ApiClient;
@@ -36,6 +38,9 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Profile;
 import org.springframework.http.HttpStatus;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
 /**
  * Creates a mock implementation of the A1 mediator client API.
  */
@@ -45,12 +50,28 @@ public class A1MediatorMockConfiguration {
 
        private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+       // A "control" is an element in the XApp descriptor
+       public static final String AC_CONTROL_NAME = "admission_control_policy";
+
        // Simulate remote method delay for UI testing
        @Value("${mock.config.delay:0}")
        private int delayMs;
 
+       private final Map<String, String> appPolicyMap;
+
        public A1MediatorMockConfiguration() {
                logger.info("Configuring mock A1 Mediator");
+               appPolicyMap = new HashMap<>();
+               // Define a mock AC policy
+               ObjectMapper mapper = new ObjectMapper();
+               ObjectNode node = mapper.createObjectNode();
+               // These fields are defined in the ACAdmissionIntervalControl 
+               // Typescript interface, but are otherwise unknown to this backend.
+               node.put("enforce", Boolean.TRUE);
+               node.put("window_length", 0);
+               node.put("blocking_rate", 0);
+               node.put("trigger_threshold", 0);
+               appPolicyMap.put(AC_CONTROL_NAME, node.toString());
        }
 
        private ApiClient apiClient() {
@@ -70,13 +91,17 @@ public class A1MediatorMockConfiguration {
                                logger.debug("a1ControllerGetHandler sleeping {}", delayMs);
                                Thread.sleep(delayMs);
                        }
-                       return null;
+                       String appName = inv.<String>getArgument(0);
+                       return appPolicyMap.get(appName);
                }).when(mockApi).a1ControllerGetHandler(any(String.class));
                doAnswer(inv -> {
                        if (delayMs > 0) {
                                logger.debug("a1ControllerPutHandler sleeping {}", delayMs);
                                Thread.sleep(delayMs);
                        }
+                       String appName = inv.<String>getArgument(0);
+                       String policy = inv.<String>getArgument(1);
+                       appPolicyMap.put(appName, policy);
                        return null;
                }).when(mockApi).a1ControllerPutHandler(any(String.class), any(Object.class));
                return mockApi;
@@ -23,8 +23,10 @@ import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.net.URI;
 
+import org.junit.Assert;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
+import org.oransc.ric.portal.dashboard.config.A1MediatorMockConfiguration;
 import org.oransc.ric.portal.dashboard.model.SuccessTransport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,13 +37,13 @@ import org.springframework.http.ResponseEntity;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
-public class AcXappControllerTest extends AbstractControllerTest {
+public class A1MediatorControllerTest extends AbstractControllerTest {
 
        private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
        @Test
        public void versionTest() {
-               URI uri = buildUri(null, AcXappController.CONTROLLER_PATH, AcXappController.VERSION_METHOD);
+               URI uri = buildUri(null, A1MediatorController.CONTROLLER_PATH, A1MediatorController.VERSION_METHOD);
                logger.info("Invoking {}", uri);
                SuccessTransport st = restTemplate.getForObject(uri, SuccessTransport.class);
                Assertions.assertFalse(st.getData().toString().isEmpty());
@@ -49,19 +51,21 @@ public class AcXappControllerTest extends AbstractControllerTest {
 
        @Test
        public void getTest() throws IOException {
-               // Always returns 501; surprised that no exception is thrown.
-               URI uri = buildUri(null, AcXappController.CONTROLLER_PATH, AcXappController.POLICY_METHOD);
+               URI uri = buildUri(null, A1MediatorController.CONTROLLER_PATH, A1MediatorController.PP_POLICIES,
+                               A1MediatorMockConfiguration.AC_CONTROL_NAME);
                logger.info("Invoking {}", uri);
                ResponseEntity<String> response = testRestTemplateStandardRole().exchange(uri, HttpMethod.GET, null,
                                String.class);
-               Assertions.assertTrue(response.getStatusCode().is5xxServerError());
+               Assertions.assertTrue(response.getStatusCode().is2xxSuccessful());
+               Assert.assertFalse(response.getBody().isEmpty());
        }
 
        @Test
        public void putTest() throws IOException {
                ObjectMapper mapper = new ObjectMapper();
                JsonNode body = mapper.readTree("{ \"policy\" : true }");
-               URI uri = buildUri(null, AcXappController.CONTROLLER_PATH, AcXappController.POLICY_METHOD);
+               URI uri = buildUri(null, A1MediatorController.CONTROLLER_PATH, A1MediatorController.PP_POLICIES,
+                               A1MediatorMockConfiguration.AC_CONTROL_NAME);
                HttpEntity<JsonNode> entity = new HttpEntity<>(body);
                logger.info("Invoking {}", uri);
                ResponseEntity<Void> voidResponse = testRestTemplateAdminRole().exchange(uri, HttpMethod.PUT, entity,
index 8c61a4e..604a071 100644 (file)
@@ -30,7 +30,6 @@ import org.junit.jupiter.api.Test;
 import org.oransc.ric.portal.dashboard.DashboardConstants;
 import org.oransc.ric.portal.dashboard.model.DashboardUser;
 import org.oransc.ric.portal.dashboard.model.ErrorTransport;
-import org.oransc.ric.portal.dashboard.model.IDashboardResponse;
 import org.oransc.ric.portal.dashboard.model.SuccessTransport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -83,21 +82,22 @@ public class AdminControllerTest extends AbstractControllerTest {
                metricsQueryParms.put("app", DashboardConstants.APP_NAME_AC);
                URI uri = buildUri(metricsQueryParms, AdminController.CONTROLLER_PATH, AdminController.XAPPMETRICS_METHOD);
                logger.debug("Invoking {}", uri);
-               ResponseEntity<SuccessTransport> successResponse = testRestTemplateStandardRole().exchange(uri, HttpMethod.GET, null,
-                               SuccessTransport.class);
+               ResponseEntity<SuccessTransport> successResponse = testRestTemplateStandardRole().exchange(uri, HttpMethod.GET,
+                               null, SuccessTransport.class);
                Assertions.assertFalse(successResponse.getBody().getData().toString().isEmpty());
                Assertions.assertTrue(successResponse.getStatusCode().is2xxSuccessful());
        }
 
        @Test
        public void getxAppMetricsUrlTestFail() {
-               Map<String, String> metricsQueryParms = new HashMap<String, String>(); 
-               //Providing a bogus value for application name in query parameter to test failure 
+               Map<String, String> metricsQueryParms = new HashMap<String, String>();
+               // Providing a bogus value for application name in query parameter to test
+               // failure
                metricsQueryParms.put("app", "ABCD");
                URI uri = buildUri(metricsQueryParms, AdminController.CONTROLLER_PATH, AdminController.XAPPMETRICS_METHOD);
                logger.debug("Invoking {}", uri);
-               ResponseEntity<ErrorTransport> errorResponse = testRestTemplateStandardRole().exchange(uri, HttpMethod.GET, null,
-                               ErrorTransport.class);
+               ResponseEntity<ErrorTransport> errorResponse = testRestTemplateStandardRole().exchange(uri, HttpMethod.GET,
+                               null, ErrorTransport.class);
                logger.debug("{}", errorResponse.getBody().getError().toString());
                Assertions.assertTrue(errorResponse.getStatusCode().is4xxClientError());
        }
index d6081b0..e6a70bf 100644 (file)
@@ -48,9 +48,6 @@
     <div class="input-display-block">
       <button class="mat-raised-button mat-primary update-button" [disabled]="!acForm.valid">Update</button>
     </div>
-    <div class="input-display-block">
-      <span class="version__text">AC API version {{acVersion}}</span>
-    </div>
 </form>
 
 </div>
\ No newline at end of file
index f7c360c..7cadd26 100644 (file)
@@ -24,6 +24,7 @@ import { ACAdmissionIntervalControl, ACAdmissionIntervalControlAck } from '../in
 import { ACXappService } from '../services/ac-xapp/ac-xapp.service';
 import { ErrorDialogService } from '../services/ui/error-dialog.service';
 import { NotificationService } from './../services/ui/notification.service';
+import { HttpErrorResponse } from '@angular/common/http';
 
 @Component({
   selector: 'rd-ac-xapp',
@@ -34,9 +35,6 @@ export class AcXappComponent implements OnInit {
 
   private acForm: FormGroup;
 
-  // this is probably the A1 version string
-  acVersion: string;
-
   constructor(
     private acXappService: ACXappService,
     private errorDialogService: ErrorDialogService,
@@ -46,22 +44,39 @@ export class AcXappComponent implements OnInit {
     const windowLengthPattern = /^([0-9]{1}|[1-5][0-9]{1}|60)$/;
     const blockingRatePattern = /^([0-9]{1,2}|100)$/;
     const triggerPattern = /^([0-9]+)$/;
-    // No way to fetch current settings via A1 at present
     this.acForm = new FormGroup({
       // Names must match the ACAdmissionIntervalControl interface
-      enforce: new FormControl(true,  [Validators.required]),
+      enforce: new FormControl(true, [Validators.required]),
       window_length: new FormControl('', [Validators.required, Validators.pattern(windowLengthPattern)]),
       blocking_rate: new FormControl('', [Validators.required, Validators.pattern(blockingRatePattern)]),
       trigger_threshold: new FormControl('', [Validators.required, Validators.pattern(triggerPattern)])
     });
-    this.acXappService.getVersion().subscribe((res: string) => this.acVersion = res);
+    // TODO: show pending action indicator
+    this.acXappService.getPolicy().subscribe((res: ACAdmissionIntervalControl) => {
+      this.acForm.controls['enforce'].setValue(res.enforce);
+      this.acForm.controls['window_length'].setValue(res.window_length);
+      this.acForm.controls['blocking_rate'].setValue(res.blocking_rate);
+      this.acForm.controls['trigger_threshold'].setValue(res.trigger_threshold);
+      // TODO: clear pending action indicator
+    },
+      (error: HttpErrorResponse) => {
+        // TODO: clear pending action indicator
+        this.errorDialogService.displayError(error.message);
+      });
   }
 
   updateAc = (acFormValue: ACAdmissionIntervalControl) => {
     if (this.acForm.valid) {
-      this.acXappService.putPolicy(acFormValue).subscribe(
+      // convert strings to numbers using the plus operator
+      const acFormValueConverted = {
+        enforce: acFormValue.enforce,
+        window_length: +acFormValue.window_length,
+        blocking_rate: +acFormValue.blocking_rate,
+        trigger_threshold: +acFormValue.trigger_threshold
+      };
+      this.acXappService.putPolicy(acFormValueConverted).subscribe(
         response => {
-          if (response.status === 200 ) {
+          if (response.status === 200) {
             this.notificationService.success('AC update policy succeeded!');
           }
         },
index 19e5fc9..47b5440 100644 (file)
@@ -26,15 +26,16 @@ import { ACAdmissionIntervalControl, ACAdmissionIntervalControlAck } from '../..
 import { DashboardSuccessTransport } from '../../interfaces/dashboard.types';
 
 /**
- * Services for calling the Dashboard's AC endpoints.
+ * Services for calling the Dashboard's A1 endpoints to get/put AC policies.
  */
 @Injectable({
   providedIn: 'root'
 })
 export class ACXappService {
 
-  private basePath = 'api/xapp/admctl';
-  private policyPath = 'policy';
+  private basePath = 'api/a1-p';
+  private policyPath = 'policies';
+  private acPolicyName = 'admission_control_policy';
 
   private buildPath(...args: any[]) {
     let result = this.basePath;
@@ -61,21 +62,21 @@ export class ACXappService {
   }
 
   /**
-   * Gets admission control parameters.
+   * Gets admission control policy.
    * @returns Observable that should yield an ACAdmissionIntervalControl
    */
   getPolicy(): Observable<ACAdmissionIntervalControl> {
-    const url = this.buildPath(this.policyPath);
+    const url = this.buildPath(this.policyPath, this.acPolicyName);
     return this.httpClient.get<ACAdmissionIntervalControl>(url);
   }
 
   /**
-   * Puts admission control parameters.
+   * Puts admission control policy.
    * @param policy an instance of ACAdmissionIntervalControl
    * @returns Observable that should yield a response code, no data
    */
   putPolicy(policy: ACAdmissionIntervalControl): Observable<any> {
-    const url = this.buildPath(this.policyPath);
+    const url = this.buildPath(this.policyPath, this.acPolicyName);
     return this.httpClient.put<ACAdmissionIntervalControlAck>(url, policy, { observe: 'response' });
   }