Add SDNR A1 client in policy-agent
[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=ANR";
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.IDLE.equals(rics.getRic("ric").getState()));
199
200         Policies ricPolicies = getA1Client("ric").getPolicies();
201         assertThat(ricPolicies.size()).isEqualTo(1);
202         Policy ricPolicy = ricPolicies.get("policyId");
203         assertThat(ricPolicy.json()).isEqualTo(policy.json());
204     }
205
206     MockA1Client getA1Client(String ricName) throws ServiceException {
207         return a1ClientFactory.getOrCreateA1Client(ricName);
208     }
209
210     @Test
211     public void testGetRic() throws Exception {
212         reset();
213         Ric ric = addRic("ric1");
214         ric.addManagedElement("kista_1");
215         String url = baseUrl() + "/ric?managedElementId=kista_1";
216
217         String rsp = this.restTemplate.getForObject(url, String.class);
218         System.out.println(rsp);
219         assertThat(rsp).isEqualTo("ric1");
220     }
221
222     @Test
223     public void testPutPolicy() throws Exception {
224         reset();
225         putService("service1");
226         addPolicyType("type1", "ric1");
227
228         String url = baseUrl() + "/policy?type=type1&instance=instance1&ric=ric1&service=service1";
229         final String json = jsonString();
230         this.rics.getRic("ric1").setState(Ric.RicState.IDLE);
231
232         this.restTemplate.put(url, createJsonHttpEntity(json));
233         Policy policy = policies.getPolicy("instance1");
234
235         assertThat(policy).isNotNull();
236         assertThat(policy.id()).isEqualTo("instance1");
237         assertThat(policy.ownerServiceName()).isEqualTo("service1");
238
239         url = baseUrl() + "/policies";
240         String rsp = this.restTemplate.getForObject(url, String.class);
241         System.out.println(rsp);
242     }
243
244     private PolicyType addPolicyType(String policyTypeName, String ricName) {
245         PolicyType type = ImmutablePolicyType.builder() //
246             .name(policyTypeName) //
247             .schema("{\"title\":\"" + policyTypeName + "\"}") //
248             .build();
249
250         policyTypes.put(type);
251         addRic(ricName).addSupportedPolicyType(type);
252         return type;
253     }
254
255     private Ric addRic(String ricName) {
256         if (rics.get(ricName) != null) {
257             return rics.get(ricName);
258         }
259         Vector<String> mes = new Vector<>();
260         RicConfig conf = ImmutableRicConfig.builder() //
261             .name(ricName) //
262             .baseUrl(ricName) //
263             .managedElementIds(mes) //
264             .build();
265         Ric ric = new Ric(conf);
266         this.rics.put(ric);
267         return ric;
268     }
269
270     private String createServiceJson(String name) {
271         ServiceRegistrationInfo service = new ServiceRegistrationInfo(name, 1, "callbackUrl");
272
273         String json = gson.toJson(service);
274         return json;
275     }
276
277     HttpEntity<String> createJsonHttpEntity(String content) {
278         HttpHeaders headers = new HttpHeaders();
279         headers.setContentType(MediaType.APPLICATION_JSON);
280         return new HttpEntity<String>(content, headers);
281     }
282
283     private void putService(String name) {
284         String url = baseUrl() + "/service";
285         HttpEntity<String> entity = createJsonHttpEntity(createServiceJson(name));
286         this.restTemplate.put(url, entity);
287     }
288
289     private String jsonString() {
290         return "{\n  \"servingCellNrcgi\": \"1\"\n }";
291     }
292
293     private Policy addPolicy(String id, String typeName, String service, String ric) throws ServiceException {
294         addRic(ric);
295         Policy p = ImmutablePolicy.builder().id(id) //
296             .json(jsonString()) //
297             .ownerServiceName(service) //
298             .ric(rics.getRic(ric)) //
299             .type(addPolicyType(typeName, ric)) //
300             .lastModified("lastModified").build();
301         policies.put(p);
302         return p;
303     }
304
305     private Policy addPolicy(String id, String typeName, String service) throws ServiceException {
306         return addPolicy(id, typeName, service, "ric");
307     }
308
309     private String baseUrl() {
310         return "http://localhost:" + port;
311     }
312
313     @Test
314     public void testGetPolicy() throws Exception {
315         String url = baseUrl() + "/policy?instance=id";
316         Policy policy = addPolicy("id", "typeName", "service1", "ric1");
317         {
318             String rsp = this.restTemplate.getForObject(url, String.class);
319             assertThat(rsp).isEqualTo(policy.json());
320         }
321         {
322             policies.remove(policy);
323             ResponseEntity<String> rsp = this.restTemplate.getForEntity(url, String.class);
324             assertThat(rsp.getStatusCodeValue()).isEqualTo(HttpStatus.NO_CONTENT.value());
325         }
326     }
327
328     @Test
329     public void testDeletePolicy() throws Exception {
330         reset();
331         String url = baseUrl() + "/policy?instance=id";
332         Policy policy = addPolicy("id", "typeName", "service1", "ric1");
333         policy.ric().setState(Ric.RicState.IDLE);
334         assertThat(policies.size()).isEqualTo(1);
335
336         this.restTemplate.delete(url);
337
338         assertThat(policies.size()).isEqualTo(0);
339     }
340
341     @Test
342     public void testGetPolicySchemas() throws Exception {
343         reset();
344         addPolicyType("type1", "ric1");
345         addPolicyType("type2", "ric2");
346
347         String url = baseUrl() + "/policy_schemas";
348         String rsp = this.restTemplate.getForObject(url, String.class);
349         System.out.println("*** " + rsp);
350         assertThat(rsp).contains("type1");
351         assertThat(rsp).contains("type2");
352         assertThat(rsp).contains("title");
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.name.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     private static <T> List<T> parseList(String jsonString, Class<T> clazz) {
468         List<T> result = new ArrayList<>();
469         JsonArray jsonArr = JsonParser.parseString(jsonString).getAsJsonArray();
470         for (JsonElement jsonElement : jsonArr) {
471             T o = gson.fromJson(jsonElement.toString(), clazz);
472             result.add(o);
473         }
474         return result;
475     }
476
477     private static List<String> parseSchemas(String jsonString) {
478         JsonArray arrayOfSchema = JsonParser.parseString(jsonString).getAsJsonArray();
479         List<String> result = new ArrayList<>();
480         for (JsonElement schemaObject : arrayOfSchema) {
481             result.add(schemaObject.toString());
482         }
483         return result;
484     }
485
486 }