44799c80fb8972cff5c3d4039c21aed4cd490077
[nonrtric.git] / policy-agent / src / main / java / org / oransc / policyagent / clients / SdncOnapA1Client.java
1 /*-
2  * ========================LICENSE_START=================================
3  * O-RAN-SC
4  * %%
5  * Copyright (C) 2019 Nordix Foundation
6  * %%
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ========================LICENSE_END===================================
19  */
20
21 package org.oransc.policyagent.clients;
22
23 import com.google.gson.FieldNamingPolicy;
24 import com.google.gson.Gson;
25 import com.google.gson.GsonBuilder;
26
27 import java.lang.invoke.MethodHandles;
28 import java.util.ArrayList;
29 import java.util.List;
30 import org.json.JSONArray;
31 import org.json.JSONException;
32 import org.json.JSONObject;
33 import org.oransc.policyagent.configuration.RicConfig;
34 import org.oransc.policyagent.repository.Policy;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37 import reactor.core.publisher.Flux;
38 import reactor.core.publisher.Mono;
39
40 public class SdncOnapA1Client implements A1Client {
41     private static final String URL_PREFIX = "/A1-ADAPTER-API:";
42
43     private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
44
45     private final String a1ControllerUsername;
46     private final String a1ControllerPassword;
47     private final RicConfig ricConfig;
48     private final AsyncRestClient restClient;
49
50     private static Gson gson = new GsonBuilder() //
51         .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES) //
52         .create();
53
54     public SdncOnapA1Client(RicConfig ricConfig, String baseUrl, String username, String password) {
55         this(ricConfig, username, password, new AsyncRestClient(baseUrl + "/restconf/operations"));
56         if (logger.isDebugEnabled()) {
57             logger.debug("SdnrOnapA1Client for ric: {}, a1ControllerBaseUrl: {}", ricConfig.name(), baseUrl);
58         }
59     }
60
61     public SdncOnapA1Client(RicConfig ricConfig, String username, String password, AsyncRestClient restClient) {
62         this.ricConfig = ricConfig;
63         this.a1ControllerUsername = username;
64         this.a1ControllerPassword = password;
65         this.restClient = restClient;
66     }
67
68     @Override
69     public Mono<List<String>> getPolicyTypeIdentities() {
70         return getPolicyTypeIds() //
71             .collectList();
72     }
73
74     @Override
75     public Mono<List<String>> getPolicyIdentities() {
76         return getPolicyTypeIds() //
77             .flatMap(this::getPolicyIdentitiesByType) //
78             .collectList();
79     }
80
81     @Override
82     public Mono<String> getPolicyTypeSchema(String policyTypeId) {
83         SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
84             .nearRtRicId(ricConfig.baseUrl()) //
85             .policyTypeId(policyTypeId) //
86             .build();
87         String inputJsonString = createInputJsonString(inputParams);
88         logger.debug("POST getPolicyType inputJsonString = {}", inputJsonString);
89
90         return restClient
91             .postWithAuthHeader(URL_PREFIX + "getPolicyType", inputJsonString, a1ControllerUsername,
92                 a1ControllerPassword) //
93             .flatMap(response -> getValueFromResponse(response, "policy-type")) //
94             .flatMap(this::extractPolicySchema);
95     }
96
97     @Override
98     public Mono<String> putPolicy(Policy policy) {
99         SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
100             .nearRtRicId(ricConfig.baseUrl()) //
101             .policyTypeId(policy.type().name()) //
102             .policyInstanceId(policy.id()) //
103             .policyInstance(policy.json()) //
104             .properties(new ArrayList<String>()) //
105             .build();
106
107         String inputJsonString = createInputJsonString(inputParams);
108         logger.debug("POST putPolicy inputJsonString = {}", inputJsonString);
109
110         return restClient.postWithAuthHeader(URL_PREFIX + "createPolicyInstance", inputJsonString,
111             a1ControllerUsername, a1ControllerPassword);
112     }
113
114     @Override
115     public Mono<String> deletePolicy(Policy policy) {
116         return deletePolicyByTypeId(policy.type().name(), policy.id());
117     }
118
119     @Override
120     public Flux<String> deleteAllPolicies() {
121         return getPolicyTypeIds() //
122             .flatMap(this::deletePoliciesForType); //
123     }
124
125     @Override
126     public Mono<A1ProtocolType> getProtocolVersion() {
127         return getPolicyTypeIdentities() //
128             .flatMap(notUsed -> Mono.just(A1ProtocolType.SDNC_ONAP));
129     }
130
131     @Override
132     public Mono<String> getPolicyStatus(Policy policy) {
133         return Mono.error(new Exception("Status not implemented in the controller"));
134     }
135
136     private Flux<String> getPolicyTypeIds() {
137         SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
138             .nearRtRicId(ricConfig.baseUrl()) //
139             .build();
140         String inputJsonString = createInputJsonString(inputParams);
141         logger.debug("POST getPolicyTypeIdentities inputJsonString = {}", inputJsonString);
142
143         return restClient
144             .postWithAuthHeader("/A1-ADAPTER-API:getPolicyTypes", inputJsonString, a1ControllerUsername,
145                 a1ControllerPassword) //
146             .flatMap(response -> getValueFromResponse(response, "policy-type-id-list")) //
147             .flatMapMany(this::parseJsonArrayOfString);
148     }
149
150     private Flux<String> getPolicyIdentitiesByType(String policyTypeId) {
151         SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
152             .nearRtRicId(ricConfig.baseUrl()) //
153             .policyTypeId(policyTypeId) //
154             .build();
155         String inputJsonString = createInputJsonString(inputParams);
156         logger.debug("POST getPolicyIdentities inputJsonString = {}", inputJsonString);
157
158         return restClient
159             .postWithAuthHeader("/A1-ADAPTER-API:getPolicyInstances", inputJsonString, a1ControllerUsername,
160                 a1ControllerPassword) //
161             .flatMap(response -> getValueFromResponse(response, "policy-instance-id-list")) //
162             .flatMapMany(this::parseJsonArrayOfString);
163     }
164
165     private Mono<String> getValueFromResponse(String response, String key) {
166         logger.debug("A1 client: response = {}", response);
167         try {
168             JSONObject outputJson = new JSONObject(response);
169             JSONObject responseParams = outputJson.getJSONObject("output");
170             if (!responseParams.has(key)) {
171                 return Mono.just("");
172             }
173             String value = responseParams.get(key).toString();
174             return Mono.just(value);
175         } catch (JSONException ex) { // invalid json
176             return Mono.error(ex);
177         }
178     }
179
180     private Flux<String> parseJsonArrayOfString(String inputString) {
181         try {
182             List<String> arrayList = new ArrayList<>();
183             if (!inputString.isEmpty()) {
184                 JSONArray jsonArray = new JSONArray(inputString);
185                 for (int i = 0; i < jsonArray.length(); i++) {
186                     arrayList.add(jsonArray.getString(i));
187                 }
188             }
189             logger.debug("A1 client: received list = {}", arrayList);
190             return Flux.fromIterable(arrayList);
191         } catch (JSONException ex) { // invalid json
192             return Flux.error(ex);
193         }
194     }
195
196     private Mono<String> extractPolicySchema(String inputString) {
197         try {
198             JSONObject jsonObject = new JSONObject(inputString);
199             JSONObject schemaObject = jsonObject.getJSONObject("policySchema");
200             String schemaString = schemaObject.toString();
201             return Mono.just(schemaString);
202         } catch (JSONException ex) { // invalid json
203             return Mono.error(ex);
204         }
205     }
206
207     private Flux<String> deletePoliciesForType(String typeId) {
208         return getPolicyIdentitiesByType(typeId) //
209             .flatMap(policyId -> deletePolicyByTypeId(typeId, policyId)); //
210     }
211
212     private Mono<String> deletePolicyByTypeId(String policyTypeId, String policyId) {
213         SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
214             .nearRtRicId(ricConfig.baseUrl()) //
215             .policyTypeId(policyTypeId) //
216             .policyInstanceId(policyId) //
217             .build();
218         String inputJsonString = createInputJsonString(inputParams);
219         logger.debug("POST deletePolicy inputJsonString = {}", inputJsonString);
220
221         return restClient.postWithAuthHeader("/A1-ADAPTER-API:deletePolicyInstance", inputJsonString,
222             a1ControllerUsername, a1ControllerPassword);
223     }
224
225     private String createInputJsonString(SdncOnapAdapterInput params) {
226         JSONObject inputJson = new JSONObject();
227         inputJson.put("input", new JSONObject(gson.toJson(params)));
228         return inputJson.toString();
229     }
230 }