38de021fcd848328a71b135f9729e16d60d53a36
[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.awaitility.Awaitility.await;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.jupiter.api.Assertions.assertFalse;
27
28 import com.google.gson.Gson;
29 import com.google.gson.GsonBuilder;
30 import com.google.gson.JsonArray;
31 import com.google.gson.JsonElement;
32 import com.google.gson.JsonParser;
33
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.Vector;
38
39 import org.junit.jupiter.api.Test;
40 import org.junit.jupiter.api.extension.ExtendWith;
41 import org.oransc.policyagent.configuration.ApplicationConfig;
42 import org.oransc.policyagent.configuration.ImmutableRicConfig;
43 import org.oransc.policyagent.configuration.RicConfig;
44 import org.oransc.policyagent.controllers.PolicyInfo;
45 import org.oransc.policyagent.controllers.ServiceRegistrationInfo;
46 import org.oransc.policyagent.controllers.ServiceStatus;
47 import org.oransc.policyagent.exceptions.ServiceException;
48 import org.oransc.policyagent.repository.ImmutablePolicy;
49 import org.oransc.policyagent.repository.ImmutablePolicyType;
50 import org.oransc.policyagent.repository.Policies;
51 import org.oransc.policyagent.repository.Policy;
52 import org.oransc.policyagent.repository.PolicyType;
53 import org.oransc.policyagent.repository.PolicyTypes;
54 import org.oransc.policyagent.repository.Ric;
55 import org.oransc.policyagent.repository.Ric.RicState;
56 import org.oransc.policyagent.repository.Rics;
57 import org.oransc.policyagent.repository.Services;
58 import org.oransc.policyagent.tasks.RepositorySupervision;
59 import org.oransc.policyagent.utils.MockA1Client;
60 import org.oransc.policyagent.utils.MockA1ClientFactory;
61 import org.springframework.beans.factory.annotation.Autowired;
62 import org.springframework.boot.test.context.SpringBootTest;
63 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
64 import org.springframework.boot.test.context.TestConfiguration;
65 import org.springframework.boot.web.server.LocalServerPort;
66 import org.springframework.context.ApplicationContext;
67 import org.springframework.context.annotation.Bean;
68 import org.springframework.http.HttpEntity;
69 import org.springframework.http.HttpHeaders;
70 import org.springframework.http.HttpStatus;
71 import org.springframework.http.HttpStatus.Series;
72 import org.springframework.http.MediaType;
73 import org.springframework.http.ResponseEntity;
74 import org.springframework.http.client.ClientHttpResponse;
75 import org.springframework.test.context.junit.jupiter.SpringExtension;
76 import org.springframework.web.client.ResponseErrorHandler;
77 import org.springframework.web.client.RestTemplate;
78
79 @ExtendWith(SpringExtension.class)
80 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
81 public class ApplicationTest {
82     @Autowired
83     ApplicationContext context;
84
85     @Autowired
86     private Rics rics;
87
88     @Autowired
89     private Policies policies;
90
91     @Autowired
92     private PolicyTypes policyTypes;
93
94     @Autowired
95     MockA1ClientFactory a1ClientFactory;
96
97     @Autowired
98     RepositorySupervision supervision;
99
100     @Autowired
101     Services services;
102
103     private static Gson gson = new GsonBuilder() //
104         .serializeNulls() //
105         .create(); //
106
107     public static class MockApplicationConfig extends ApplicationConfig {
108         @Override
109         public String getLocalConfigurationFilePath() {
110             return ""; // No config file loaded for the test
111         }
112     }
113
114     /**
115      * Overrides the BeanFactory.
116      */
117     @TestConfiguration
118     static class TestBeanFactory {
119         private final PolicyTypes policyTypes = new PolicyTypes();
120
121         @Bean
122         public ApplicationConfig getApplicationConfig() {
123             return new MockApplicationConfig();
124         }
125
126         @Bean
127         MockA1ClientFactory getA1ClientFactory() {
128             return new MockA1ClientFactory(this.policyTypes);
129         }
130
131         @Bean
132         public Policies getPolicies() {
133             return new Policies();
134         }
135
136         @Bean
137         public PolicyTypes getPolicyTypes() {
138             return this.policyTypes;
139         }
140
141         @Bean
142         public Rics getRics() {
143             return new Rics();
144         }
145     }
146
147     @LocalServerPort
148     private int port;
149
150     private final RestTemplate restTemplate = new RestTemplate();
151
152     public class RestTemplateResponseErrorHandler implements ResponseErrorHandler {
153
154         @Override
155         public boolean hasError(ClientHttpResponse httpResponse) throws IOException {
156             return (httpResponse.getStatusCode().series() == Series.CLIENT_ERROR
157                 || httpResponse.getStatusCode().series() == Series.SERVER_ERROR);
158         }
159
160         @Override
161         public void handleError(ClientHttpResponse httpResponse) throws IOException {
162             System.out.println("Error " + httpResponse.toString());
163         }
164     }
165
166     private void reset() {
167         rics.clear();
168         policies.clear();
169         policyTypes.clear();
170         assertThat(policies.size()).isEqualTo(0);
171         restTemplate.setErrorHandler(new RestTemplateResponseErrorHandler());
172     }
173
174     @Test
175     public void testGetRics() throws Exception {
176         reset();
177         addRic("kista_1");
178         String url = baseUrl() + "/rics";
179         String rsp = this.restTemplate.getForObject(url, String.class);
180         System.out.println(rsp);
181         assertThat(rsp).contains("kista_1");
182
183         url = baseUrl() + "/rics?policyType=STD_PolicyModelUnconstrained_0.2.0";
184         rsp = this.restTemplate.getForObject(url, String.class);
185         assertThat(rsp).isEqualTo("[]");
186     }
187
188     @Test
189     public void testRecovery() throws Exception {
190         reset();
191         Policy policy2 = addPolicy("policyId2", "typeName", "service", "ric");
192
193         getA1Client("ric").putPolicy(policy2); // put it in the RIC
194         policies.remove(policy2); // Remove it from the repo -> should be deleted in the RIC
195
196         Policy policy = addPolicy("policyId", "typeName", "service", "ric"); // This should be created in the RIC
197         supervision.checkAllRics(); // The created policy should be put in the RIC
198         await().untilAsserted(() -> RicState.RECOVERING.equals(rics.getRic("ric").getState()));
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("[{\"title\":\"type2\"}");
353
354         List<String> info = parseSchemas(rsp);
355         assertEquals(2, info.size());
356
357         url = baseUrl() + "/policy_schemas?ric=ric1";
358         rsp = this.restTemplate.getForObject(url, String.class);
359         assertThat(rsp).contains("type1");
360         info = parseSchemas(rsp);
361         assertEquals(1, info.size());
362     }
363
364     @Test
365     public void testGetPolicySchema() throws Exception {
366         reset();
367         addPolicyType("type1", "ric1");
368         addPolicyType("type2", "ric2");
369
370         String url = baseUrl() + "/policy_schema?id=type1";
371         String rsp = this.restTemplate.getForObject(url, String.class);
372         System.out.println(rsp);
373         assertThat(rsp).contains("type1");
374         assertThat(rsp).contains("title");
375     }
376
377     @Test
378     public void testGetPolicyTypes() throws Exception {
379         reset();
380         addPolicyType("type1", "ric1");
381         addPolicyType("type2", "ric2");
382
383         String url = baseUrl() + "/policy_types";
384         String rsp = this.restTemplate.getForObject(url, String.class);
385         assertThat(rsp).isEqualTo("[\"type2\",\"type1\"]");
386
387         url = baseUrl() + "/policy_types?ric=ric1";
388         rsp = this.restTemplate.getForObject(url, String.class);
389         assertThat(rsp).isEqualTo("[\"type1\"]");
390     }
391
392     @Test
393     public void testGetPolicies() throws Exception {
394         String url = baseUrl() + "/policies";
395         addPolicy("id1", "type1", "service1");
396
397         String rsp = this.restTemplate.getForObject(url, String.class);
398         System.out.println(rsp);
399         List<PolicyInfo> info = parseList(rsp, PolicyInfo.class);
400         assertThat(info).size().isEqualTo(1);
401         PolicyInfo policyInfo = info.get(0);
402         assert (policyInfo.validate());
403         assertThat(policyInfo.id).isEqualTo("id1");
404         assertThat(policyInfo.type).isEqualTo("type1");
405         assertThat(policyInfo.service).isEqualTo("service1");
406     }
407
408     @Test
409     public void testGetPoliciesFilter() throws Exception {
410         addPolicy("id1", "type1", "service1");
411         addPolicy("id2", "type1", "service2");
412         addPolicy("id3", "type2", "service1");
413
414         String url = baseUrl() + "/policies?type=type1";
415         String rsp = this.restTemplate.getForObject(url, String.class);
416         System.out.println(rsp);
417         assertThat(rsp).contains("id1");
418         assertThat(rsp).contains("id2");
419         assertFalse(rsp.contains("id3"));
420
421         url = baseUrl() + "/policies?type=type1&service=service2";
422         rsp = this.restTemplate.getForObject(url, String.class);
423         System.out.println(rsp);
424         assertFalse(rsp.contains("id1"));
425         assertThat(rsp).contains("id2");
426         assertFalse(rsp.contains("id3"));
427     }
428
429     @Test
430     public void testPutAndGetService() throws Exception {
431         reset();
432         // PUT
433         putService("name");
434
435         // GET
436         String url = baseUrl() + "/services?name=name";
437         String rsp = this.restTemplate.getForObject(url, String.class);
438         List<ServiceStatus> info = parseList(rsp, ServiceStatus.class);
439         assertThat(info.size() == 1);
440         ServiceStatus status = info.iterator().next();
441         assertThat(status.keepAliveIntervalSeconds == 1);
442         assertThat(status.serviceName.equals("name"));
443
444         // GET (all)
445         url = baseUrl() + "/services";
446         rsp = this.restTemplate.getForObject(url, String.class);
447         assertThat(rsp.contains("name"));
448         System.out.println(rsp);
449
450         // Keep alive
451         url = baseUrl() + "/services/keepalive?name=name";
452         rsp = this.restTemplate.postForObject(url, null, String.class);
453         assertThat(rsp.contains("OK"));
454
455         // DELETE
456         assertThat(services.size() == 1);
457         url = baseUrl() + "/services?name=name";
458         this.restTemplate.delete(url);
459         assertThat(services.size() == 0);
460
461         // Keep alive, no registerred service
462         url = baseUrl() + "/services/keepalive?name=nameXXX";
463         ResponseEntity<String> entity = this.restTemplate.postForEntity(url, null, String.class);
464         assertThat(entity.getStatusCode().equals(HttpStatus.NOT_FOUND));
465     }
466
467     @Test
468     public void testGetPolicyStatus() throws Exception {
469         reset();
470         Policy policy = addPolicy("id", "typeName", "service1", "ric1");
471         policy.ric().setState(Ric.RicState.IDLE);
472         assertThat(policies.size()).isEqualTo(1);
473
474         String url = baseUrl() + "/policy_status?instance=id";
475         String rsp = this.restTemplate.getForObject(url, String.class);
476         assertThat(rsp.equals("OK"));
477     }
478
479     private static <T> List<T> parseList(String jsonString, Class<T> clazz) {
480         List<T> result = new ArrayList<>();
481         JsonArray jsonArr = JsonParser.parseString(jsonString).getAsJsonArray();
482         for (JsonElement jsonElement : jsonArr) {
483             T o = gson.fromJson(jsonElement.toString(), clazz);
484             result.add(o);
485         }
486         return result;
487     }
488
489     private static List<String> parseSchemas(String jsonString) {
490         JsonArray arrayOfSchema = JsonParser.parseString(jsonString).getAsJsonArray();
491         List<String> result = new ArrayList<>();
492         for (JsonElement schemaObject : arrayOfSchema) {
493             result.add(schemaObject.toString());
494         }
495         return result;
496     }
497
498 }