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