Add Http Response Code in A1 Controller Api
[nonrtric.git] / dashboard / webapp-backend / src / test / java / org / oransc / ric / portal / dashboard / config / A1ControllerMockConfiguration.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 package org.oransc.ric.portal.dashboard.config;
21
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.Mockito.doAnswer;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.when;
26 import com.fasterxml.jackson.core.JsonProcessingException;
27 import java.lang.invoke.MethodHandles;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Optional;
35 import java.util.Set;
36 import org.oransc.ric.a1controller.client.api.A1ControllerApi;
37 import org.oransc.ric.a1controller.client.invoker.ApiClient;
38 import org.oransc.ric.a1controller.client.model.InputNRRidPTidPIidPISchema;
39 import org.oransc.ric.a1controller.client.model.InputNRRidPTidPIidSchema;
40 import org.oransc.ric.a1controller.client.model.InputNRRidPTidSchema;
41 import org.oransc.ric.a1controller.client.model.InputNRRidSchema;
42 import org.oransc.ric.a1controller.client.model.OutputCodeSchema;
43 import org.oransc.ric.a1controller.client.model.OutputCodeSchemaOutput;
44 import org.oransc.ric.a1controller.client.model.OutputDescNamePTCodeSchema;
45 import org.oransc.ric.a1controller.client.model.OutputDescNamePTCodeSchemaOutput;
46 import org.oransc.ric.a1controller.client.model.OutputPICodeSchema;
47 import org.oransc.ric.a1controller.client.model.OutputPICodeSchemaOutput;
48 import org.oransc.ric.a1controller.client.model.OutputPIidsListCodeSchema;
49 import org.oransc.ric.a1controller.client.model.OutputPIidsListCodeSchemaOutput;
50 import org.oransc.ric.a1controller.client.model.OutputPTidsListCodeSchema;
51 import org.oransc.ric.a1controller.client.model.OutputPTidsListCodeSchemaOutput;
52 import org.oransc.ric.portal.dashboard.model.PolicyType;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
55 import org.springframework.beans.factory.annotation.Value;
56 import org.springframework.context.annotation.Bean;
57 import org.springframework.context.annotation.Configuration;
58 import org.springframework.context.annotation.Profile;
59 import org.springframework.http.HttpStatus;
60
61 /**
62  * Creates a mock implementation of the A1 controller client API.
63  */
64 @Profile("test")
65 @Configuration
66 public class A1ControllerMockConfiguration {
67
68         private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
69
70         // A "control" is an element in the XApp descriptor
71         public static final String AC_CONTROL_NAME = "admission_control_policy";
72
73         // Simulate remote method delay for UI testing
74         @Value("${mock.config.delay:0}")
75         private int delayMs;
76
77         public A1ControllerMockConfiguration() {
78                 logger.info("Configuring mock A1 Mediator");
79         }
80
81         private ApiClient apiClient() {
82                 ApiClient mockClient = mock(ApiClient.class);
83                 when(mockClient.getStatusCode()).thenReturn(HttpStatus.OK);
84                 return mockClient;
85         }
86
87         @Bean
88         // Use the same name as regular configuration
89         public A1ControllerApi a1ControllerApi() {
90                 ApiClient apiClient = apiClient();
91                 A1ControllerApi mockApi = mock(A1ControllerApi.class);
92
93                 when(mockApi.getApiClient()).thenReturn(apiClient);
94
95                 doAnswer(inv -> {
96                         if (delayMs > 0) {
97                                 logger.debug("a1ControllerGetHandler sleeping {}", delayMs);
98                                 Thread.sleep(delayMs);
99                         }
100                         List<Integer> types = database.getTypes();
101                         OutputPTidsListCodeSchemaOutput output = new OutputPTidsListCodeSchemaOutput();
102                         output.setPolicyTypeIdList(types);
103                         output.setCode(String.valueOf(HttpStatus.OK.value()));
104                         OutputPTidsListCodeSchema outputSchema = new OutputPTidsListCodeSchema();
105                         outputSchema.setOutput(output);
106                         return outputSchema;
107                 }).when(mockApi).a1ControllerGetAllPolicyTypes(any(InputNRRidSchema.class));
108
109                 doAnswer(inv -> {
110                         if (delayMs > 0) {
111                                 logger.debug("a1ControllerGetPolicyType sleeping {}", delayMs);
112                                 Thread.sleep(delayMs);
113                         }
114                         InputNRRidPTidSchema input = inv.<InputNRRidPTidSchema>getArgument(0);
115                         PolicyType policyType = database.getPolicyType(input.getInput().getPolicyTypeId());
116                         OutputDescNamePTCodeSchemaOutput type = new OutputDescNamePTCodeSchemaOutput();
117                         type.setName(policyType.getName());
118                         type.setDescription(policyType.getDescription());
119                         type.setPolicyType(database.normalize(policyType.getCreateSchema()));
120                         type.setCode(String.valueOf(HttpStatus.OK.value()));
121                         OutputDescNamePTCodeSchema outputSchema = new OutputDescNamePTCodeSchema();
122                         outputSchema.setOutput(type);
123                         return outputSchema;
124                 }).when(mockApi).a1ControllerGetPolicyType(any(InputNRRidPTidSchema.class));
125
126                 doAnswer(inv -> {
127                         if (delayMs > 0) {
128                                 logger.debug("a1ControllerGetHandler sleeping {}", delayMs);
129                                 Thread.sleep(delayMs);
130                         }
131                         InputNRRidPTidSchema input = inv.<InputNRRidPTidSchema>getArgument(0);
132                         List<String> instances = database.getInstances(Optional.of(input.getInput().getPolicyTypeId()));
133                         OutputPIidsListCodeSchemaOutput instancesOutput = new OutputPIidsListCodeSchemaOutput();
134                         instancesOutput.setPolicyInstanceIdList(instances);
135                         instancesOutput.setCode(String.valueOf(HttpStatus.OK.value()));
136                         OutputPIidsListCodeSchema outputSchema = new OutputPIidsListCodeSchema();
137                         outputSchema.setOutput(instancesOutput);
138                         return outputSchema;
139                 }).when(mockApi).a1ControllerGetAllInstancesForType(any(InputNRRidPTidSchema.class));
140
141                 doAnswer(inv -> {
142                         if (delayMs > 0) {
143                                 logger.debug("a1ControllerGetHandler sleeping {}", delayMs);
144                                 Thread.sleep(delayMs);
145                         }
146                         InputNRRidPTidPIidSchema input = inv.<InputNRRidPTidPIidSchema>getArgument(0);
147                         Integer polcyTypeId = input.getInput().getPolicyTypeId();
148                         String instanceId = input.getInput().getPolicyInstanceId();
149                         String instance = database.normalize(database.getInstance(polcyTypeId, instanceId));
150                         OutputPICodeSchemaOutput instanceOutput = new OutputPICodeSchemaOutput();
151                         instanceOutput.setPolicyInstance(instance);
152                         instanceOutput.setCode(String.valueOf(HttpStatus.OK.value()));
153                         OutputPICodeSchema outputSchema = new OutputPICodeSchema();
154                         outputSchema.setOutput(instanceOutput);
155                         return outputSchema;
156                 }).when(mockApi).a1ControllerGetPolicyInstance(any(InputNRRidPTidPIidSchema.class));
157
158                 doAnswer(inv -> {
159                         if (delayMs > 0) {
160                                 logger.debug("a1ControllerGetHandler sleeping {}", delayMs);
161                                 Thread.sleep(delayMs);
162                         }
163                         InputNRRidPTidPIidPISchema input = inv.<InputNRRidPTidPIidPISchema>getArgument(0);
164                         Integer polcyTypeId = input.getInput().getPolicyTypeId();
165                         String instanceId = input.getInput().getPolicyInstanceId();
166                         String instance = input.getInput().getPolicyInstance();
167                         database.putInstance(polcyTypeId, instanceId, instance);
168                         OutputCodeSchemaOutput outputCodeSchemaOutput = new OutputCodeSchemaOutput();
169                         outputCodeSchemaOutput.setCode(String.valueOf(HttpStatus.CREATED.value()));
170                         OutputCodeSchema outputCodeSchema = new OutputCodeSchema();
171             outputCodeSchema.setOutput(outputCodeSchemaOutput);
172                         return outputCodeSchema;
173                 }).when(mockApi).a1ControllerCreatePolicyInstance(any(InputNRRidPTidPIidPISchema.class));
174
175                 doAnswer(inv -> {
176                         if (delayMs > 0) {
177                                 logger.debug("a1ControllerGetHandler sleeping {}", delayMs);
178                                 Thread.sleep(delayMs);
179                         }
180                         InputNRRidPTidPIidSchema input = inv.<InputNRRidPTidPIidSchema>getArgument(0);
181                         Integer polcyTypeId = input.getInput().getPolicyTypeId();
182                         String instanceId = input.getInput().getPolicyInstanceId();
183                         database.deleteInstance(polcyTypeId, instanceId);
184                         OutputCodeSchemaOutput outputCodeSchemaOutput = new OutputCodeSchemaOutput();
185             outputCodeSchemaOutput.setCode(String.valueOf(HttpStatus.NO_CONTENT.value()));
186             OutputCodeSchema outputCodeSchema = new OutputCodeSchema();
187             outputCodeSchema.setOutput(outputCodeSchemaOutput);
188             return outputCodeSchema;
189                 }).when(mockApi).a1ControllerDeletePolicyInstance(any(InputNRRidPTidPIidSchema.class));
190
191                 return mockApi;
192         }
193
194         class Database {
195
196                 private String schema1 = "{\"$schema\": " //
197                                 + "\"http://json-schema.org/draft-07/schema#\"," //
198                                 + "\"title\": \"ANR\"," //
199                                 + "\"description\": \"ANR Neighbour Cell Relation Policy\"," //
200                                 + "\"type\": \"object\"," //
201                                 + "\"properties\": " //
202                                 + "{ \"servingCellNrcgi\": {" //
203                                 + "\"type\": \"string\"," //
204                                 + "\"description\" : \"Serving Cell Identifier (NR CGI)\"}," //
205                                 + "\"neighborCellNrpci\": {" //
206                                 + "\"type\": \"string\"," //
207                                 + "\"description\": \"Neighbor Cell Identifier (NR PCI)\"}," //
208                                 + "\"neighborCellNrcgi\": {" //
209                                 + "\"type\": \"string\"," //
210                                 + "\"description\": \"Neighbor Cell Identifier (NR CGI)\"}," //
211                                 + "\"flagNoHo\": {" //
212                                 + "\"type\": \"boolean\"," //
213                                 + "\"description\": \"Flag for HANDOVER NOT ALLOWED\"}," //
214                                 + "\"flagNoXn\": {" //
215                                 + "\"type\": \"boolean\"," //
216                                 + "\"description\": \"Flag for Xn CONNECTION NOT ALLOWED\"}," //
217                                 + "\"flagNoRemove\": {" //
218                                 + "\"type\": \"boolean\"," //
219                                 + "\"description\": \"Flag for DELETION NOT ALLOWED\"}}, " //
220                                 + "\"required\": [ \"servingCellNrcgi\",\"neighborCellNrpci\",\"neighborCellNrcgi\",\"flagNoHo\",\"flagNoXn\",\"flagNoRemove\" ]}";
221                 private PolicyType policy1 = new PolicyType(1, "ANR", "ANR Neighbour Cell Relation Policy", schema1);
222
223                 private String policyInstance1 = "{\"servingCellNrcgi\": \"Cell1\",\r\n" + //
224                                 "\"neighborCellNrpci\": \"NCell1\",\r\n" + //
225                                 "\"neighborCellNrcgi\": \"Ncell1\",\r\n" + //
226                                 "\"flagNoHo\": true,\r\n" + //
227                                 "\"flagNoXn\": true,\r\n" + //
228                                 "\"flagNoRemove\": true}";
229
230                 private String schema2 = "{\n" + "          \"type\": \"object\",\n" + //
231                                 "          \"title\": \"Car\",\n" + //
232                                 "          \"properties\": {\n" + //
233                                 "            \"make\": {\n" + //
234                                 "              \"type\": \"string\",\n" + //
235                                 "              \"enum\": [\n" + //
236                                 "                \"Toyota\",\n" + //
237                                 "                \"BMW\",\n" + //
238                                 "                \"Honda\",\n" + //
239                                 "                \"Ford\",\n" + //
240                                 "                \"Chevy\",\n" + //
241                                 "                \"VW\"\n" + //
242                                 "              ]\n" + //
243                                 "            },\n" + //
244                                 "            \"model\": {\n" + //
245                                 "              \"type\": \"string\"\n" + //
246                                 "            },\n" + //
247                                 "            \"year\": {\n" + //
248                                 "              \"type\": \"integer\",\n" + //
249                                 "              \"enum\": [\n" + //
250                                 "                1995,1996,1997,1998,1999,\n" + //
251                                 "                2000,2001,2002,2003,2004,\n" + //
252                                 "                2005,2006,2007,2008,2009,\n" + //
253                                 "                2010,2011,2012,2013,2014\n" + //
254                                 "              ],\n" + //
255                                 "              \"default\": 2008\n" + //
256                                 "            },\n" + //
257                                 "            \"safety\": {\n" + //
258                                 "              \"type\": \"integer\",\n" + //
259                                 "              \"format\": \"rating\",\n" + //
260                                 "              \"maximum\": 5,\n" + //
261                                 "              \"exclusiveMaximum\": false,\n" + //
262                                 "              \"readonly\": false\n" + //
263                                 "            }\n" + //
264                                 "          }\n" + //
265                                 "        }\n";
266                 private PolicyType policy2 = new PolicyType(2, "type2", "Type2 description", schema2);
267
268                 private String schema3 = "{\n" + //
269                                 "  \"$id\": \"https://example.com/person.schema.json\",\n" + //
270                                 "  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n" + //
271                                 "  \"title\": \"Person\",\n" + //
272                                 "  \"type\": \"object\",\n" + //
273                                 "  \"properties\": {\n" + //
274                                 "    \"firstName\": {\n" + //
275                                 "      \"type\": \"string\",\n" + //
276                                 "      \"description\": \"The person's first name.\"\n" + //
277                                 "    },\n" + //
278                                 "    \"lastName\": {\n" + //
279                                 "      \"type\": \"string\",\n" + //
280                                 "      \"description\": \"The person's last name.\"\n" + //
281                                 "    },\n" + //
282                                 "    \"age\": {\n" + //
283                                 "      \"description\": \"Age in years which must be equal to or greater than zero.\",\n" + //
284                                 "      \"type\": \"integer\",\n" + //
285                                 "      \"minimum\": 0\n" + //
286                                 "    }\n" + //
287                                 "  }\n" + //
288                                 "}";
289                 private PolicyType policy3 = new PolicyType(3, "type3", "Type3 description", schema3);
290
291                 private String schema4 = "{" + //
292                                 "                 \"$id\": \"https://example.com/arrays.schema.json\"," + //
293                                 "                 \"$schema\": \"http://json-schema.org/draft-07/schema#\"," + //
294                                 "                 \"description\": \"A representation of a person, company, organization, or place\"," + //
295                                 "                 \"type\": \"object\"," + //
296                                 "                 \"properties\": {" + //
297                                 "                   \"fruits\": {" + //
298                                 "                     \"type\": \"array\"," + //
299                                 "                     \"items\": {" + //
300                                 "                       \"type\": \"string\"" + //
301                                 "                     }" + //
302                                 "                   }," + //
303                                 "                   \"vegetables\": {" + //
304                                 "                     \"type\": \"array\"," + //
305                                 "                     \"items\": { \"$ref\": \"#/definitions/veggie\" }" + //
306                                 "                   }" + //
307                                 "                 }," + //
308                                 "                 \"definitions\": {" + //
309                                 "                   \"veggie\": {" + //
310                                 "                     \"type\": \"object\"," + //
311                                 "                     \"required\": [ \"veggieName\", \"veggieLike\" ]," + //
312                                 "                     \"properties\": {" + //
313                                 "                       \"veggieName\": {" + //
314                                 "                         \"type\": \"string\"," + //
315                                 "                         \"description\": \"The name of the vegetable.\"" + //
316                                 "                       }," + //
317                                 "                       \"veggieLike\": {" + //
318                                 "                         \"type\": \"boolean\"," + //
319                                 "                         \"description\": \"Do I like this vegetable?\"" + //
320                                 "                       }" + //
321                                 "                     }" + //
322                                 "                   }" + //
323                                 "                 }" + //
324                                 "               }";
325                 private PolicyType policy4 = new PolicyType(4, "type4", "Type4 description", schema4);
326
327                 public class PolicyException extends Exception {
328
329                         private static final long serialVersionUID = 1L;
330
331                         public PolicyException(String message) {
332                                 super(message);
333                                 System.out.println("**** Exception " + message);
334                         }
335                 }
336
337                 private class PolicyTypeHolder {
338                         PolicyTypeHolder(PolicyType pt) {
339                                 this.policyType = pt;
340                         }
341
342                         String getInstance(String instanceId) throws PolicyException {
343                                 String instance = instances.get(instanceId);
344                                 if (instance == null) {
345                                         throw new PolicyException("Instance not found: " + instanceId);
346                                 }
347                                 return instance;
348                         }
349
350                         PolicyType getPolicyType() {
351                                 return policyType;
352                         }
353
354                         void putInstance(String id, String data) {
355                                 instances.put(id, data);
356                         }
357
358                         void deleteInstance(String id) {
359                                 instances.remove(id);
360                         }
361
362                         List<String> getInstances() {
363                                 return new ArrayList<>(instances.keySet());
364                         }
365
366                         private final PolicyType policyType;
367                         private Map<String, String> instances = new HashMap<>();
368                 }
369
370                 Database() {
371                         types.put(1, new PolicyTypeHolder(policy1));
372                         types.put(2, new PolicyTypeHolder(policy2));
373                         types.put(3, new PolicyTypeHolder(policy3));
374                         types.put(4, new PolicyTypeHolder(policy4));
375                         try {
376                                 putInstance(1, "ANR-1", policyInstance1);
377                         } catch (JsonProcessingException | PolicyException e) {
378                                 // Nothing
379                         }
380                 }
381
382                 String normalize(String str) {
383                         return str.replace('\n', ' ');
384                 }
385
386                 void putInstance(Integer typeId, String instanceId, String instanceData)
387                                 throws JsonProcessingException, PolicyException {
388                         PolicyTypeHolder type = getTypeHolder(typeId);
389                         type.putInstance(instanceId, instanceData);
390                 }
391
392                 void deleteInstance(Integer typeId, String instanceId) throws JsonProcessingException, PolicyException {
393                         PolicyTypeHolder type = getTypeHolder(typeId);
394                         type.deleteInstance(instanceId);
395                 }
396
397                 String getInstance(Integer typeId, String instanceId) throws JsonProcessingException, PolicyException {
398                         return getTypeHolder(typeId).getInstance(instanceId);
399                 }
400
401                 List<Integer> getTypes() {
402                         return new ArrayList<>(types.keySet());
403                 }
404
405                 List<String> getInstances(Optional<Integer> typeId) throws PolicyException {
406                         if (typeId.isPresent()) {
407                                 return getTypeHolder(typeId.get()).getInstances();
408                         } else {
409                                 Set<String> res = new HashSet<String>();
410                                 for (Iterator<PolicyTypeHolder> i = types.values().iterator(); i.hasNext();) {
411                                         res.addAll(i.next().getInstances());
412                                 }
413                                 return new ArrayList<>(res);
414                         }
415                 }
416
417                 private PolicyTypeHolder getTypeHolder(Integer typeId) throws PolicyException {
418                         PolicyTypeHolder typeHolder = types.get(typeId);
419                         if (typeHolder == null) {
420                                 throw new PolicyException("Type not found: " + typeId);
421                         }
422                         return typeHolder;
423                 }
424
425                 private PolicyType getPolicyType(Integer typeId) throws PolicyException {
426                         PolicyTypeHolder typeHolder = getTypeHolder(typeId);
427                         return typeHolder.getPolicyType();
428                 }
429
430                 private Map<Integer, PolicyTypeHolder> types = new HashMap<>();
431
432         }
433
434         private final Database database = new Database();
435 }