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