NBI documentation using swagger UI
[nonrtric.git] / policy-agent / src / test / java / org / oransc / policyagent / ApplicationTest.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;
22
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.jupiter.api.Assertions.assertFalse;
26
27 import com.google.gson.Gson;
28 import com.google.gson.GsonBuilder;
29 import com.google.gson.JsonArray;
30 import com.google.gson.JsonElement;
31 import com.google.gson.JsonParser;
32
33 import java.io.IOException;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Vector;
37
38 import org.junit.jupiter.api.Test;
39 import org.junit.jupiter.api.extension.ExtendWith;
40 import org.oransc.policyagent.configuration.ApplicationConfig;
41 import org.oransc.policyagent.configuration.ImmutableRicConfig;
42 import org.oransc.policyagent.configuration.RicConfig;
43 import org.oransc.policyagent.controllers.PolicyInfo;
44 import org.oransc.policyagent.controllers.ServiceRegistrationInfo;
45 import org.oransc.policyagent.controllers.ServiceStatus;
46 import org.oransc.policyagent.exceptions.ServiceException;
47 import org.oransc.policyagent.repository.ImmutablePolicy;
48 import org.oransc.policyagent.repository.ImmutablePolicyType;
49 import org.oransc.policyagent.repository.Policies;
50 import org.oransc.policyagent.repository.Policy;
51 import org.oransc.policyagent.repository.PolicyType;
52 import org.oransc.policyagent.repository.PolicyTypes;
53 import org.oransc.policyagent.repository.Ric;
54 import org.oransc.policyagent.repository.Rics;
55 import org.oransc.policyagent.repository.Services;
56 import org.oransc.policyagent.repository.Ric.RicState;
57 import org.oransc.policyagent.tasks.RepositorySupervision;
58 import org.oransc.policyagent.utils.MockA1Client;
59 import org.oransc.policyagent.utils.MockA1ClientFactory;
60 import org.springframework.beans.factory.annotation.Autowired;
61 import org.springframework.boot.test.context.SpringBootTest;
62 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
63 import org.springframework.boot.test.context.TestConfiguration;
64 import org.springframework.boot.web.server.LocalServerPort;
65 import org.springframework.context.ApplicationContext;
66 import org.springframework.context.annotation.Bean;
67 import org.springframework.http.HttpEntity;
68 import org.springframework.http.HttpHeaders;
69 import org.springframework.http.HttpStatus;
70 import org.springframework.http.HttpStatus.Series;
71 import org.springframework.http.MediaType;
72 import org.springframework.http.ResponseEntity;
73 import org.springframework.http.client.ClientHttpResponse;
74 import org.springframework.test.context.junit.jupiter.SpringExtension;
75 import org.springframework.web.client.ResponseErrorHandler;
76 import org.springframework.web.client.RestTemplate;
77
78 import static org.awaitility.Awaitility.await;
79
80 @ExtendWith(SpringExtension.class)
81 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
82 public class ApplicationTest {
83     @Autowired
84     ApplicationContext context;
85
86     @Autowired
87     private Rics rics;
88
89     @Autowired
90     private Policies policies;
91
92     @Autowired
93     private PolicyTypes policyTypes;
94
95     @Autowired
96     MockA1ClientFactory a1ClientFactory;
97
98     @Autowired
99     RepositorySupervision supervision;
100
101     @Autowired
102     Services services;
103
104     private static Gson gson = new GsonBuilder() //
105         .serializeNulls() //
106         .create(); //
107
108     public static class MockApplicationConfig extends ApplicationConfig {
109         @Override
110         public String getLocalConfigurationFilePath() {
111             return ""; // No config file loaded for the test
112         }
113     }
114
115     /**
116      * Overrides the BeanFactory.
117      */
118     @TestConfiguration
119     static class TestBeanFactory {
120         private final PolicyTypes policyTypes = new PolicyTypes();
121
122         @Bean
123         public ApplicationConfig getApplicationConfig() {
124             return new MockApplicationConfig();
125         }
126
127         @Bean
128         MockA1ClientFactory getA1ClientFactory() {
129             return new MockA1ClientFactory(this.policyTypes);
130         }
131
132         @Bean
133         public Policies getPolicies() {
134             return new Policies();
135         }
136
137         @Bean
138         public PolicyTypes getPolicyTypes() {
139             return this.policyTypes;
140         }
141
142         @Bean
143         public Rics getRics() {
144             return new Rics();
145         }
146     }
147
148     @LocalServerPort
149     private int port;
150
151     private final RestTemplate restTemplate = new RestTemplate();
152
153     public class RestTemplateResponseErrorHandler implements ResponseErrorHandler {
154
155         @Override
156         public boolean hasError(ClientHttpResponse httpResponse) throws IOException {
157             return (httpResponse.getStatusCode().series() == Series.CLIENT_ERROR
158                 || httpResponse.getStatusCode().series() == Series.SERVER_ERROR);
159         }
160
161         @Override
162         public void handleError(ClientHttpResponse httpResponse) throws IOException {
163             System.out.println("Error " + httpResponse.toString());
164         }
165     }
166
167     private void reset() {
168         rics.clear();
169         policies.clear();
170         policyTypes.clear();
171         assertThat(policies.size()).isEqualTo(0);
172         restTemplate.setErrorHandler(new RestTemplateResponseErrorHandler());
173     }
174
175     @Test
176     public void testGetRics() throws Exception {
177         reset();
178         addRic("kista_1");
179         String url = baseUrl() + "/rics";
180         String rsp = this.restTemplate.getForObject(url, String.class);
181         System.out.println(rsp);
182         assertThat(rsp).contains("kista_1");
183
184         url = baseUrl() + "/rics?policyType=ANR";
185         rsp = this.restTemplate.getForObject(url, String.class);
186         assertThat(rsp).isEqualTo("[]");
187     }
188
189     @Test
190     public void testRecovery() throws Exception {
191         reset();
192         Policy policy2 = addPolicy("policyId2", "typeName", "service", "ric");
193
194         getA1Client("ric").putPolicy(policy2); // put it in the RIC
195         policies.remove(policy2); // Remove it from the repo -> should be deleted in the RIC
196
197         Policy policy = addPolicy("policyId", "typeName", "service", "ric"); // This should be created in the RIC
198         supervision.checkAllRics(); // The created policy should be put in the RIC
199         await().untilAsserted(() -> RicState.IDLE.equals(rics.getRic("ric").getState()));
200
201         Policies ricPolicies = getA1Client("ric").getPolicies();
202         assertThat(ricPolicies.size()).isEqualTo(1);
203         Policy ricPolicy = ricPolicies.get("policyId");
204         assertThat(ricPolicy.json()).isEqualTo(policy.json());
205     }
206
207     MockA1Client getA1Client(String ricName) throws ServiceException {
208         return a1ClientFactory.getOrCreateA1Client(ricName);
209     }
210
211     @Test
212     public void testGetRic() throws Exception {
213         reset();
214         Ric ric = addRic("ric1");
215         ric.addManagedElement("kista_1");
216         String url = baseUrl() + "/ric?managedElementId=kista_1";
217
218         String rsp = this.restTemplate.getForObject(url, String.class);
219         System.out.println(rsp);
220         assertThat(rsp).isEqualTo("ric1");
221     }
222
223     @Test
224     public void testPutPolicy() throws Exception {
225         reset();
226         putService("service1");
227         addPolicyType("type1", "ric1");
228
229         String url = baseUrl() + "/policy?type=type1&instance=instance1&ric=ric1&service=service1";
230         final String json = jsonString();
231         this.rics.getRic("ric1").setState(Ric.RicState.IDLE);
232
233         this.restTemplate.put(url, createJsonHttpEntity(json));
234         Policy policy = policies.getPolicy("instance1");
235
236         assertThat(policy).isNotNull();
237         assertThat(policy.id()).isEqualTo("instance1");
238         assertThat(policy.ownerServiceName()).isEqualTo("service1");
239
240         url = baseUrl() + "/policies";
241         String rsp = this.restTemplate.getForObject(url, String.class);
242         System.out.println(rsp);
243     }
244
245     private PolicyType addPolicyType(String policyTypeName, String ricName) {
246         PolicyType type = ImmutablePolicyType.builder() //
247             .name(policyTypeName) //
248             .schema("{\"title\":\"" + policyTypeName + "\"}") //
249             .build();
250
251         policyTypes.put(type);
252         addRic(ricName).addSupportedPolicyType(type);
253         return type;
254     }
255
256     private Ric addRic(String ricName) {
257         if (rics.get(ricName) != null) {
258             return rics.get(ricName);
259         }
260         Vector<String> mes = new Vector<>();
261         RicConfig conf = ImmutableRicConfig.builder() //
262             .name(ricName) //
263             .baseUrl(ricName) //
264             .managedElementIds(mes) //
265             .build();
266         Ric ric = new Ric(conf);
267         this.rics.put(ric);
268         return ric;
269     }
270
271     private String createServiceJson(String name) {
272         ServiceRegistrationInfo service = new ServiceRegistrationInfo(name, 1, "callbackUrl");
273
274         String json = gson.toJson(service);
275         return json;
276     }
277
278     HttpEntity<String> createJsonHttpEntity(String content) {
279         HttpHeaders headers = new HttpHeaders();
280         headers.setContentType(MediaType.APPLICATION_JSON);
281         return new HttpEntity<String>(content, headers);
282     }
283
284     private void putService(String name) {
285         String url = baseUrl() + "/service";
286         HttpEntity<String> entity = createJsonHttpEntity(createServiceJson(name));
287         this.restTemplate.put(url, entity);
288     }
289
290     private String jsonString() {
291         return "{\n  \"servingCellNrcgi\": \"1\"\n }";
292     }
293
294     private Policy addPolicy(String id, String typeName, String service, String ric) throws ServiceException {
295         addRic(ric);
296         Policy p = ImmutablePolicy.builder().id(id) //
297             .json(jsonString()) //
298             .ownerServiceName(service) //
299             .ric(rics.getRic(ric)) //
300             .type(addPolicyType(typeName, ric)) //
301             .lastModified("lastModified").build();
302         policies.put(p);
303         return p;
304     }
305
306     private Policy addPolicy(String id, String typeName, String service) throws ServiceException {
307         return addPolicy(id, typeName, service, "ric");
308     }
309
310     private String baseUrl() {
311         return "http://localhost:" + port;
312     }
313
314     @Test
315     public void testGetPolicy() throws Exception {
316         String url = baseUrl() + "/policy?instance=id";
317         Policy policy = addPolicy("id", "typeName", "service1", "ric1");
318         {
319             String rsp = this.restTemplate.getForObject(url, String.class);
320             assertThat(rsp).isEqualTo(policy.json());
321         }
322         {
323             policies.remove(policy);
324             ResponseEntity<String> rsp = this.restTemplate.getForEntity(url, String.class);
325             assertThat(rsp.getStatusCodeValue()).isEqualTo(HttpStatus.NO_CONTENT.value());
326         }
327     }
328
329     @Test
330     public void testDeletePolicy() throws Exception {
331         reset();
332         String url = baseUrl() + "/policy?instance=id";
333         Policy policy = addPolicy("id", "typeName", "service1", "ric1");
334         policy.ric().setState(Ric.RicState.IDLE);
335         assertThat(policies.size()).isEqualTo(1);
336
337         this.restTemplate.delete(url);
338
339         assertThat(policies.size()).isEqualTo(0);
340     }
341
342     @Test
343     public void testGetPolicySchemas() throws Exception {
344         reset();
345         addPolicyType("type1", "ric1");
346         addPolicyType("type2", "ric2");
347
348         String url = baseUrl() + "/policy_schemas";
349         String rsp = this.restTemplate.getForObject(url, String.class);
350         System.out.println("*** " + rsp);
351         assertThat(rsp).contains("type1");
352         assertThat(rsp).contains("type2");
353         assertThat(rsp).contains("title");
354
355         List<String> info = parseSchemas(rsp);
356         assertEquals(2, info.size());
357
358         url = baseUrl() + "/policy_schemas?ric=ric1";
359         rsp = this.restTemplate.getForObject(url, String.class);
360         assertThat(rsp).contains("type1");
361         info = parseSchemas(rsp);
362         assertEquals(1, info.size());
363     }
364
365     @Test
366     public void testGetPolicySchema() throws Exception {
367         reset();
368         addPolicyType("type1", "ric1");
369         addPolicyType("type2", "ric2");
370
371         String url = baseUrl() + "/policy_schema?id=type1";
372         String rsp = this.restTemplate.getForObject(url, String.class);
373         System.out.println(rsp);
374         assertThat(rsp).contains("type1");
375         assertThat(rsp).contains("title");
376     }
377
378     @Test
379     public void testGetPolicyTypes() throws Exception {
380         reset();
381         addPolicyType("type1", "ric1");
382         addPolicyType("type2", "ric2");
383
384         String url = baseUrl() + "/policy_types";
385         String rsp = this.restTemplate.getForObject(url, String.class);
386         assertThat(rsp).isEqualTo("[\"type2\",\"type1\"]");
387
388         url = baseUrl() + "/policy_types?ric=ric1";
389         rsp = this.restTemplate.getForObject(url, String.class);
390         assertThat(rsp).isEqualTo("[\"type1\"]");
391     }
392
393     @Test
394     public void testGetPolicies() throws Exception {
395         String url = baseUrl() + "/policies";
396         addPolicy("id1", "type1", "service1");
397
398         String rsp = this.restTemplate.getForObject(url, String.class);
399         System.out.println(rsp);
400         List<PolicyInfo> info = parseList(rsp, PolicyInfo.class);
401         assertThat(info).size().isEqualTo(1);
402         PolicyInfo policyInfo = info.get(0);
403         assert (policyInfo.validate());
404         assertThat(policyInfo.id).isEqualTo("id1");
405         assertThat(policyInfo.type).isEqualTo("type1");
406         assertThat(policyInfo.service).isEqualTo("service1");
407     }
408
409     @Test
410     public void testGetPoliciesFilter() throws Exception {
411         addPolicy("id1", "type1", "service1");
412         addPolicy("id2", "type1", "service2");
413         addPolicy("id3", "type2", "service1");
414
415         String url = baseUrl() + "/policies?type=type1";
416         String rsp = this.restTemplate.getForObject(url, String.class);
417         System.out.println(rsp);
418         assertThat(rsp).contains("id1");
419         assertThat(rsp).contains("id2");
420         assertFalse(rsp.contains("id3"));
421
422         url = baseUrl() + "/policies?type=type1&service=service2";
423         rsp = this.restTemplate.getForObject(url, String.class);
424         System.out.println(rsp);
425         assertFalse(rsp.contains("id1"));
426         assertThat(rsp).contains("id2");
427         assertFalse(rsp.contains("id3"));
428     }
429
430     @Test
431     public void testPutAndGetService() throws Exception {
432         reset();
433         // PUT
434         putService("name");
435
436         // GET
437         String url = baseUrl() + "/services?name=name";
438         String rsp = this.restTemplate.getForObject(url, String.class);
439         List<ServiceStatus> info = parseList(rsp, ServiceStatus.class);
440         assertThat(info.size() == 1);
441         ServiceStatus status = info.iterator().next();
442         assertThat(status.keepAliveIntervalSeconds == 1);
443         assertThat(status.name.equals("name"));
444
445         // GET (all)
446         url = baseUrl() + "/services";
447         rsp = this.restTemplate.getForObject(url, String.class);
448         assertThat(rsp.contains("name"));
449         System.out.println(rsp);
450
451         // Keep alive
452         url = baseUrl() + "/services/keepalive?name=name";
453         rsp = this.restTemplate.postForObject(url, null, String.class);
454         assertThat(rsp.contains("OK"));
455
456         // DELETE
457         assertThat(services.size() == 1);
458         url = baseUrl() + "/services?name=name";
459         this.restTemplate.delete(url);
460         assertThat(services.size() == 0);
461
462         // Keep alive, no registerred service
463         url = baseUrl() + "/services/keepalive?name=nameXXX";
464         ResponseEntity<String> entity = this.restTemplate.postForEntity(url, null, String.class);
465         assertThat(entity.getStatusCode().equals(HttpStatus.NOT_FOUND));
466     }
467
468     private static <T> List<T> parseList(String jsonString, Class<T> clazz) {
469         List<T> result = new ArrayList<>();
470         JsonArray jsonArr = JsonParser.parseString(jsonString).getAsJsonArray();
471         for (JsonElement jsonElement : jsonArr) {
472             T o = gson.fromJson(jsonElement.toString(), clazz);
473             result.add(o);
474         }
475         return result;
476     }
477
478     private static List<String> parseSchemas(String jsonString) {
479         JsonArray arrayOfSchema = JsonParser.parseString(jsonString).getAsJsonArray();
480         List<String> result = new ArrayList<>();
481         for (JsonElement schemaObject : arrayOfSchema) {
482             result.add(schemaObject.toString());
483         }
484         return result;
485     }
486
487 }