Add SDNR A1 client in policy-agent 68/2368/3
authorRehanRaza <muhammad.rehan.raza@est.tech>
Wed, 29 Jan 2020 09:41:41 +0000 (10:41 +0100)
committerRehanRaza <muhammad.rehan.raza@est.tech>
Wed, 29 Jan 2020 16:42:00 +0000 (17:42 +0100)
Change-Id: Id20042eda95298cd4bbbf1a9f9ea23ea1be81ca9
Issue-ID: NONRTRIC-108
Signed-off-by: RehanRaza <muhammad.rehan.raza@est.tech>
policy-agent/config/application_configuration.json
policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java
policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientFactory.java
policy-agent/src/main/java/org/oransc/policyagent/clients/AsyncRestClient.java
policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java [moved from policy-agent/src/main/java/org/oransc/policyagent/clients/ControllerA1Client.java with 82% similarity]
policy-agent/src/main/java/org/oransc/policyagent/clients/SdnrOnapA1Client.java [new file with mode: 0644]
policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java

index cb039ca..8f3f80b 100644 (file)
             ]
          }
       ]
-   },
-   "streams_subscribes": {
-      "dmaap_subscriber": {
-         "dmaap_info": {
-            "topic_url": "http://dradmin:dradmin@localhost:2222/events/A1-P/users/sdnc1"
-         },
-         "type": "message_router"
-      }
    }
 }
\ No newline at end of file
index 213dfa5..0a2bc8e 100644 (file)
@@ -30,7 +30,7 @@ import reactor.core.publisher.Mono;
 public interface A1Client {
 
     public static enum A1ProtocolType {
-        UNKNOWN, STD_V1, OSC_V1, CONTROLLER
+        UNKNOWN, STD_V1, OSC_V1, SDNC_OSC, SDNR_ONAP
     }
 
     public Mono<A1ProtocolType> getProtocolVersion();
index cd53f83..7b7e0ce 100644 (file)
@@ -41,15 +41,18 @@ public class A1ClientFactory {
             return Mono.just(createStdA1ClientImpl(ric));
         } else if (version == A1ProtocolType.OSC_V1) {
             return Mono.just(new OscA1Client(ric.getConfig()));
-        } else if (version == A1ProtocolType.CONTROLLER) {
-            return Mono.just(createControllerA1Client(ric));
+        } else if (version == A1ProtocolType.SDNC_OSC) {
+            return Mono.just(createSdncOscA1Client(ric));
+        } else if (version == A1ProtocolType.SDNR_ONAP) {
+            return Mono.just(createSdnrOnapA1Client(ric));
         }
         return Mono.error(new ServiceException("Not supported protocoltype: " + version));
     }
 
     private Mono<A1Client.A1ProtocolType> getProtocolVersion(Ric ric) {
         if (ric.getProtocolVersion() == A1ProtocolType.UNKNOWN) {
-            return fetchVersion(ric, createControllerA1Client(ric)) //
+            return fetchVersion(ric, createSdnrOnapA1Client(ric)) //
+                .onErrorResume(err -> fetchVersion(ric, createSdncOscA1Client(ric)))
                 .onErrorResume(err -> fetchVersion(ric, new OscA1Client(ric.getConfig())))
                 .onErrorResume(err -> fetchVersion(ric, createStdA1ClientImpl(ric)))
                 .doOnNext(version -> ric.setProtocolVersion(version))
@@ -64,8 +67,12 @@ public class A1ClientFactory {
         return new StdA1Client(ric.getConfig());
     }
 
-    protected A1Client createControllerA1Client(Ric ric) {
-        return new ControllerA1Client(ric.getConfig());
+    protected A1Client createSdncOscA1Client(Ric ric) {
+        return new SdncOscA1Client(ric.getConfig());
+    }
+
+    protected A1Client createSdnrOnapA1Client(Ric ric) {
+        return new SdnrOnapA1Client(ric.getConfig());
     }
 
     private Mono<A1Client.A1ProtocolType> fetchVersion(Ric ric, A1Client a1Client) {
index 3fd16d0..b10cf27 100644 (file)
@@ -56,6 +56,18 @@ public class AsyncRestClient {
             .bodyToMono(String.class);
     }
 
+    public Mono<String> postWithAuthHeader(String uri, String body, String username, String password) {
+        return client.post() //
+            .uri(uri) //
+            .headers(headers -> headers.setBasicAuth(username, password)) //
+            .contentType(MediaType.APPLICATION_JSON) //
+            .bodyValue(body) //
+            .retrieve() //
+            .onStatus(HttpStatus::isError,
+                response -> Mono.error(new AsyncRestClientException(response.statusCode().toString()))) //
+            .bodyToMono(String.class);
+    }
+
     public Mono<String> put(String uri, String body) {
         logger.debug("PUT uri = '{}''", uri);
         return client.put() //
@@ -35,18 +35,19 @@ import org.slf4j.LoggerFactory;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
-public class ControllerA1Client implements A1Client {
+public class SdncOscA1Client implements A1Client {
     private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-    private static final String A1_CONTROLLER_URL =
-        "http://admin:Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U@a1-controller-container:8181/restconf/operations";
+    private static final String A1_CONTROLLER_URL = "http://a1-controller-container:8181/restconf/operations";
+    private static final String A1_CONTROLLER_USERNAME = "admin";
+    private static final String A1_CONTROLLER_PASSWORD = "Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U";
 
     private final RicConfig ricConfig;
     private final AsyncRestClient restClient;
 
-    public ControllerA1Client(RicConfig ricConfig) {
+    public SdncOscA1Client(RicConfig ricConfig) {
         this.ricConfig = ricConfig;
         this.restClient = new AsyncRestClient(A1_CONTROLLER_URL);
-        logger.debug("ControllerA1Client for ric: {}", this.ricConfig.name());
+        logger.debug("SdncOscA1Client for ric: {}", this.ricConfig.name());
     }
 
     @Override
@@ -56,7 +57,9 @@ public class ControllerA1Client implements A1Client {
         String inputJsonString = createInputJsonString(paramsJson);
         logger.debug("POST getPolicyTypeIdentities inputJsonString = {}", inputJsonString);
 
-        return restClient.post("/A1-ADAPTER-API:getPolicyTypeIdentities", inputJsonString) //
+        return restClient
+            .postWithAuthHeader("/A1-ADAPTER-API:getPolicyTypeIdentities", inputJsonString, A1_CONTROLLER_USERNAME,
+                A1_CONTROLLER_PASSWORD) //
             .flatMap(response -> getValueFromResponse(response, "policy-type-id-list")) //
             .flatMap(this::parseJsonArrayOfString);
     }
@@ -68,7 +71,9 @@ public class ControllerA1Client implements A1Client {
         String inputJsonString = createInputJsonString(paramsJson);
         logger.debug("POST getPolicyIdentities inputJsonString = {}", inputJsonString);
 
-        return restClient.post("/A1-ADAPTER-API:getPolicyIdentities", inputJsonString) //
+        return restClient
+            .postWithAuthHeader("/A1-ADAPTER-API:getPolicyIdentities", inputJsonString, A1_CONTROLLER_USERNAME,
+                A1_CONTROLLER_PASSWORD) //
             .flatMap(response -> getValueFromResponse(response, "policy-id-list")) //
             .flatMap(this::parseJsonArrayOfString);
     }
@@ -81,7 +86,9 @@ public class ControllerA1Client implements A1Client {
         String inputJsonString = createInputJsonString(paramsJson);
         logger.debug("POST getPolicyType inputJsonString = {}", inputJsonString);
 
-        return restClient.post("/A1-ADAPTER-API:getPolicyType", inputJsonString) //
+        return restClient
+            .postWithAuthHeader("/A1-ADAPTER-API:getPolicyType", inputJsonString, A1_CONTROLLER_USERNAME,
+                A1_CONTROLLER_PASSWORD) //
             .flatMap(response -> getValueFromResponse(response, "policy-type")) //
             .flatMap(this::extractPolicySchema);
     }
@@ -96,7 +103,9 @@ public class ControllerA1Client implements A1Client {
         String inputJsonString = createInputJsonString(paramsJson);
         logger.debug("POST putPolicy inputJsonString = {}", inputJsonString);
 
-        return restClient.post("/A1-ADAPTER-API:putPolicy", inputJsonString) //
+        return restClient
+            .postWithAuthHeader("/A1-ADAPTER-API:putPolicy", inputJsonString, A1_CONTROLLER_USERNAME,
+                A1_CONTROLLER_PASSWORD) //
             .flatMap(response -> getValueFromResponse(response, "returned-policy")) //
             .flatMap(this::validateJson);
     }
@@ -120,13 +129,14 @@ public class ControllerA1Client implements A1Client {
         String inputJsonString = createInputJsonString(paramsJson);
         logger.debug("POST deletePolicy inputJsonString = {}", inputJsonString);
 
-        return restClient.post("/A1-ADAPTER-API:deletePolicy", inputJsonString);
+        return restClient.postWithAuthHeader("/A1-ADAPTER-API:deletePolicy", inputJsonString, A1_CONTROLLER_USERNAME,
+            A1_CONTROLLER_PASSWORD);
     }
 
     @Override
     public Mono<A1ProtocolType> getProtocolVersion() {
         return getPolicyTypeIdentities() //
-            .flatMap(x -> Mono.just(A1ProtocolType.CONTROLLER));
+            .flatMap(x -> Mono.just(A1ProtocolType.SDNC_OSC));
     }
 
     private String createInputJsonString(JSONObject paramsJson) {
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdnrOnapA1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/SdnrOnapA1Client.java
new file mode 100644 (file)
index 0000000..4a0a506
--- /dev/null
@@ -0,0 +1,198 @@
+/*-
+ * ========================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.oransc.policyagent.configuration.RicConfig;
+import org.oransc.policyagent.repository.Policy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+public class SdnrOnapA1Client implements A1Client {
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static final String A1_CONTROLLER_URL = "http://sdnc_controller_container:8181/restconf/operations";
+    private static final String A1_CONTROLLER_USERNAME = "admin";
+    private static final String A1_CONTROLLER_PASSWORD = "Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U";
+
+    private final RicConfig ricConfig;
+    private final AsyncRestClient restClient;
+
+    public SdnrOnapA1Client(RicConfig ricConfig) {
+        this.ricConfig = ricConfig;
+        this.restClient = new AsyncRestClient(A1_CONTROLLER_URL);
+        logger.debug("SdnrOnapA1Client for ric: {}", this.ricConfig.name());
+    }
+
+    @Override
+    public Mono<List<String>> getPolicyTypeIdentities() {
+        JSONObject paramsJson = new JSONObject();
+        paramsJson.put("near-rt-ric-id", ricConfig.baseUrl());
+        String inputJsonString = createInputJsonString(paramsJson);
+        logger.debug("POST getPolicyTypeIdentities inputJsonString = {}", inputJsonString);
+
+        return restClient
+            .postWithAuthHeader("/A1-ADAPTER-API:getPolicyTypes", inputJsonString, A1_CONTROLLER_USERNAME,
+                A1_CONTROLLER_PASSWORD) //
+            .flatMap(response -> getValueFromResponse(response, "policy-type-id-list")) //
+            .flatMap(this::parseJsonArrayOfString);
+    }
+
+    @Override
+    public Mono<List<String>> getPolicyIdentities() {
+        return getPolicyTypeIdentities() //
+            .flatMapMany(types -> Flux.fromIterable(types)) //
+            .flatMap(type -> getPolicyIdentities(type)) //
+            .flatMap(policyIds -> Flux.fromIterable(policyIds)) //
+            .collectList();
+    }
+
+    public Mono<List<String>> getPolicyIdentities(String policyTypeId) {
+        JSONObject paramsJson = new JSONObject();
+        paramsJson.put("near-rt-ric-id", ricConfig.baseUrl());
+        paramsJson.put("policy-type-id", policyTypeId);
+        String inputJsonString = createInputJsonString(paramsJson);
+        logger.debug("POST getPolicyIdentities inputJsonString = {}", inputJsonString);
+
+        return restClient
+            .postWithAuthHeader("/A1-ADAPTER-API:getPolicyInstances", inputJsonString, A1_CONTROLLER_USERNAME,
+                A1_CONTROLLER_PASSWORD) //
+            .flatMap(response -> getValueFromResponse(response, "policy-instance-id-list")) //
+            .flatMap(this::parseJsonArrayOfString);
+    }
+
+    @Override
+    public Mono<String> getPolicyTypeSchema(String policyTypeId) {
+        JSONObject paramsJson = new JSONObject();
+        paramsJson.put("near-rt-ric-id", ricConfig.baseUrl());
+        paramsJson.put("policy-type-id", policyTypeId);
+        String inputJsonString = createInputJsonString(paramsJson);
+        logger.debug("POST getPolicyType inputJsonString = {}", inputJsonString);
+
+        return restClient
+            .postWithAuthHeader("/A1-ADAPTER-API:getPolicyType", inputJsonString, A1_CONTROLLER_USERNAME,
+                A1_CONTROLLER_PASSWORD) //
+            .flatMap(response -> getValueFromResponse(response, "policy-type")) //
+            .flatMap(this::extractPolicySchema);
+    }
+
+    @Override
+    public Mono<String> putPolicy(Policy policy) {
+        JSONObject paramsJson = new JSONObject();
+        paramsJson.put("near-rt-ric-id", ricConfig.baseUrl());
+        paramsJson.put("policy-instance-id", policy.id());
+        paramsJson.put("policy-type-id", policy.type().name());
+        paramsJson.put("policy-instance", policy.json());
+        paramsJson.put("properties", new JSONArray());
+        String inputJsonString = createInputJsonString(paramsJson);
+        logger.debug("POST putPolicy inputJsonString = {}", inputJsonString);
+
+        return restClient.postWithAuthHeader("/A1-ADAPTER-API:createPolicyInstance", inputJsonString,
+            A1_CONTROLLER_USERNAME, A1_CONTROLLER_PASSWORD);
+    }
+
+    public Mono<String> deletePolicy(String policyTypeId, String policyId) {
+        JSONObject paramsJson = new JSONObject();
+        paramsJson.put("near-rt-ric-id", ricConfig.baseUrl());
+        paramsJson.put("policy-instance-id", policyId);
+        paramsJson.put("policy-type-id", policyTypeId);
+        String inputJsonString = createInputJsonString(paramsJson);
+        logger.debug("POST deletePolicy inputJsonString = {}", inputJsonString);
+
+        return restClient.postWithAuthHeader("/A1-ADAPTER-API:deletePolicyInstance", inputJsonString,
+            A1_CONTROLLER_USERNAME, A1_CONTROLLER_PASSWORD);
+    }
+
+    @Override
+    public Mono<String> deletePolicy(Policy policy) {
+        return deletePolicy(policy.type().name(), policy.id());
+    }
+
+    @Override
+    public Flux<String> deleteAllPolicies() {
+        return getPolicyTypeIdentities() //
+            .flatMapMany(types -> Flux.fromIterable(types)) //
+            .flatMap(typeId -> deletePoliciesForType(typeId)); //
+    }
+
+    private Flux<String> deletePoliciesForType(String typeId) {
+        return getPolicyIdentities(typeId) //
+            .flatMapMany(policyIds -> Flux.fromIterable(policyIds)) //
+            .flatMap(policyId -> deletePolicy(typeId, policyId)); //
+    }
+
+    @Override
+    public Mono<A1ProtocolType> getProtocolVersion() {
+        return getPolicyTypeIdentities() //
+            .flatMap(x -> Mono.just(A1ProtocolType.SDNR_ONAP));
+    }
+
+    private String createInputJsonString(JSONObject paramsJson) {
+        JSONObject inputJson = new JSONObject();
+        inputJson.put("input", paramsJson);
+        return inputJson.toString();
+    }
+
+    private Mono<String> getValueFromResponse(String response, String key) {
+        logger.debug("A1 client: response = {}", response);
+        try {
+            JSONObject outputJson = new JSONObject(response);
+            JSONObject responseParams = outputJson.getJSONObject("output");
+            String value = responseParams.get(key).toString();
+            return Mono.just(value);
+        } catch (JSONException ex) { // invalid json
+            return Mono.error(ex);
+        }
+    }
+
+    private Mono<List<String>> parseJsonArrayOfString(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 Mono.just(arrayList);
+        } catch (JSONException ex) { // invalid json
+            return Mono.error(ex);
+        }
+    }
+
+    private Mono<String> extractPolicySchema(String inputString) {
+        try {
+            JSONObject jsonObject = new JSONObject(inputString);
+            JSONObject schemaObject = jsonObject.getJSONObject("policySchema");
+            String schemaString = schemaObject.toString();
+            return Mono.just(schemaString);
+        } catch (JSONException ex) { // invalid json
+            return Mono.error(ex);
+        }
+    }
+}
index eec9c70..3e5932f 100644 (file)
@@ -21,6 +21,7 @@
 package org.oransc.policyagent;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
 import static org.junit.Assert.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 
@@ -51,9 +52,9 @@ import org.oransc.policyagent.repository.Policy;
 import org.oransc.policyagent.repository.PolicyType;
 import org.oransc.policyagent.repository.PolicyTypes;
 import org.oransc.policyagent.repository.Ric;
+import org.oransc.policyagent.repository.Ric.RicState;
 import org.oransc.policyagent.repository.Rics;
 import org.oransc.policyagent.repository.Services;
-import org.oransc.policyagent.repository.Ric.RicState;
 import org.oransc.policyagent.tasks.RepositorySupervision;
 import org.oransc.policyagent.utils.MockA1Client;
 import org.oransc.policyagent.utils.MockA1ClientFactory;
@@ -75,8 +76,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
 import org.springframework.web.client.ResponseErrorHandler;
 import org.springframework.web.client.RestTemplate;
 
-import static org.awaitility.Awaitility.await;
-
 @ExtendWith(SpringExtension.class)
 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
 public class ApplicationTest {