Fix Sonar complains
[oam/nf-oam-adopter.git] / ves-nf-oam-adopter / ves-nf-oam-adopter-pm-sb-rest-client / src / test / java / org / o / ran / oam / nf / oam / adopter / pm / sb / rest / client / DefaultHttpRestClientTest.java
1 package org.o.ran.oam.nf.oam.adopter.pm.sb.rest.client;
2
3 import static org.mockito.ArgumentMatchers.any;
4 import static org.mockito.ArgumentMatchers.nullable;
5 import static org.mockito.Mockito.when;
6
7 import io.reactivex.rxjava3.observers.TestObserver;
8 import java.io.ByteArrayInputStream;
9 import java.io.IOException;
10 import java.time.ZoneId;
11 import java.util.Arrays;
12 import java.util.concurrent.CompletableFuture;
13 import java.util.concurrent.Future;
14 import java.util.zip.ZipInputStream;
15 import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
16 import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
17 import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
18 import org.apache.hc.core5.concurrent.FutureCallback;
19 import org.apache.hc.core5.http.ContentType;
20 import org.apache.hc.core5.http.HttpStatus;
21 import org.junit.jupiter.api.MethodOrderer;
22 import org.junit.jupiter.api.Test;
23 import org.junit.jupiter.api.TestMethodOrder;
24 import org.mockito.stubbing.Answer;
25 import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.api.HttpRestClient;
26 import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos.Adapter;
27 import org.o.ran.oam.nf.oam.adopter.pm.sb.rest.client.properties.PmEndpointsUrlsProperties;
28 import org.springframework.beans.factory.annotation.Autowired;
29 import org.springframework.boot.context.properties.EnableConfigurationProperties;
30 import org.springframework.boot.test.context.SpringBootTest;
31 import org.springframework.boot.test.mock.mockito.MockBean;
32 import org.springframework.test.annotation.DirtiesContext;
33 import org.springframework.test.annotation.DirtiesContext.MethodMode;
34
35 @SpringBootTest(classes = {DefaultHttpRestClient.class, PmEndpointsUrlsProperties.class})
36 @EnableConfigurationProperties
37 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
38 class DefaultHttpRestClientTest {
39
40     private static final Adapter ADAPTER =
41             Adapter.builder().hostIpAddress("150.62.25.26").username("admin").password("secretPassword").build();
42     @Autowired
43     public HttpRestClient restClient;
44
45     @MockBean
46     CloseableHttpAsyncClient client;
47
48     @Test
49     @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD)
50     void testGetFailedToken() {
51         final SimpleHttpResponse response =
52                 SimpleHttpResponse.create(HttpStatus.SC_UNAUTHORIZED, "error", ContentType.APPLICATION_JSON);
53
54         when(client.execute(any(SimpleHttpRequest.class), nullable(FutureCallback.class)))
55                 .thenAnswer((Answer<Future<SimpleHttpResponse>>) invocation -> {
56                     final SimpleHttpRequest req = (SimpleHttpRequest) invocation.getArguments()[0];
57                     if ("/auth/token".equals(req.getPath())) {
58                         return CompletableFuture.completedFuture(response);
59                     }
60                     throw new IllegalStateException("Unexpected value: " + req.getPath());
61                 });
62
63
64         final TestObserver<ZoneId> observer = restClient.getTimeZone(ADAPTER).test();
65         observer.assertError(throwable -> throwable.getMessage()
66             .equals("Failed to obtain a token for host https://150.62.25.26: HTTP/1.1 401 Unauthorized"));
67     }
68
69     @Test
70     void testReadFiles() throws IOException {
71         final String tokenJson = JsonUtils.readJson("/json/tokenResponse.json");
72         final SimpleHttpResponse response =
73                 SimpleHttpResponse.create(HttpStatus.SC_OK, tokenJson, ContentType.APPLICATION_JSON);
74
75         final SimpleHttpResponse zipResponse =
76                 SimpleHttpResponse.create(HttpStatus.SC_OK, "mockZip", ContentType.APPLICATION_OCTET_STREAM);
77
78         when(client.execute(any(SimpleHttpRequest.class), nullable(FutureCallback.class)))
79                 .thenAnswer((Answer<Future<SimpleHttpResponse>>) invocation -> {
80                     final SimpleHttpRequest req = (SimpleHttpRequest) invocation.getArguments()[0];
81                     switch (req.getPath()) {
82                         case "/auth/token":
83                             return CompletableFuture.completedFuture(response);
84                         case "/pm/files":
85                             return CompletableFuture.completedFuture(zipResponse);
86                         default:
87                             throw new IllegalStateException("Unexpected value: " + req.getPath());
88                     }
89                 });
90
91
92         final TestObserver<ZipInputStream> observer = restClient.readFiles(ADAPTER).test();
93         final ZipInputStream expected = new ZipInputStream(new ByteArrayInputStream("mockZip".getBytes()));
94         observer.assertValue(zip -> Arrays.equals(zip.readAllBytes(), expected.readAllBytes()));
95     }
96
97     @Test
98     void testReadFilesResponseFail() throws IOException {
99         final String tokenJson = JsonUtils.readJson("/json/tokenResponse.json");
100         final SimpleHttpResponse response =
101                 SimpleHttpResponse.create(HttpStatus.SC_OK, tokenJson, ContentType.APPLICATION_JSON);
102
103         final SimpleHttpResponse zipResponse = SimpleHttpResponse.create(HttpStatus.SC_BAD_REQUEST, "mockZip",
104                 ContentType.APPLICATION_OCTET_STREAM);
105
106         when(client.execute(any(SimpleHttpRequest.class), nullable(FutureCallback.class)))
107                 .thenAnswer((Answer<Future<SimpleHttpResponse>>) invocation -> {
108                     final SimpleHttpRequest req = (SimpleHttpRequest) invocation.getArguments()[0];
109                     switch (req.getPath()) {
110                         case "/auth/token":
111                             return CompletableFuture.completedFuture(response);
112                         case "/pm/files":
113                             return CompletableFuture.completedFuture(zipResponse);
114                         default:
115                             throw new IllegalStateException("Unexpected value: " + req.getPath());
116                     }
117                 });
118
119
120         final TestObserver<ZipInputStream> observer = restClient.readFiles(ADAPTER).test();
121         observer.assertError(throwable -> throwable.getMessage()
122             .equals("Download files from 150.62.25.26 failed: HTTP/1.1 400 Bad Request"));
123     }
124
125     @Test
126     void testGetTimeOffset() throws IOException {
127         final String tokenJson = JsonUtils.readJson("/json/tokenResponse.json");
128         final SimpleHttpResponse response =
129                 SimpleHttpResponse.create(HttpStatus.SC_OK, tokenJson, ContentType.APPLICATION_JSON);
130
131         final String timeZoneOFfsetResponseJson = JsonUtils.readJson("/json/timeZoneOffsetResponse.json");
132         final SimpleHttpResponse timeOffsetResponse =
133                 SimpleHttpResponse.create(HttpStatus.SC_OK, timeZoneOFfsetResponseJson, ContentType.APPLICATION_JSON);
134
135         when(client.execute(any(SimpleHttpRequest.class), nullable(FutureCallback.class)))
136                 .thenAnswer((Answer<Future<SimpleHttpResponse>>) invocation -> {
137                     final SimpleHttpRequest req = (SimpleHttpRequest) invocation.getArguments()[0];
138                     switch (req.getPath()) {
139                         case "/auth/token":
140                             return CompletableFuture.completedFuture(response);
141                         case "/system/timeZone":
142                             return CompletableFuture.completedFuture(timeOffsetResponse);
143                         default:
144                             throw new IllegalStateException("Unexpected value: " + req.getPath());
145                     }
146                 });
147
148
149         final TestObserver<ZoneId> observer = restClient.getTimeZone(ADAPTER).test();
150         observer.assertValues(ZoneId.of("+02:00"));
151     }
152
153     @Test
154     void testGetTimeOffsetFail() throws IOException {
155         final String tokenJson = JsonUtils.readJson("/json/tokenResponse.json");
156         final SimpleHttpResponse response =
157                 SimpleHttpResponse.create(HttpStatus.SC_OK, tokenJson, ContentType.APPLICATION_JSON);
158
159         final SimpleHttpResponse timeOffsetResponse =
160                 SimpleHttpResponse.create(HttpStatus.SC_OK, "", ContentType.APPLICATION_JSON);
161
162         when(client.execute(any(SimpleHttpRequest.class), nullable(FutureCallback.class)))
163                 .thenAnswer((Answer<Future<SimpleHttpResponse>>) invocation -> {
164                     final SimpleHttpRequest req = (SimpleHttpRequest) invocation.getArguments()[0];
165                     switch (req.getPath()) {
166                         case "/auth/token":
167                             return CompletableFuture.completedFuture(response);
168                         case "/system/timeZone":
169                             return CompletableFuture.completedFuture(timeOffsetResponse);
170                         default:
171                             throw new IllegalStateException("Unexpected value: " + req.getPath());
172                     }
173                 });
174
175
176         final TestObserver<ZoneId> observer = restClient.getTimeZone(ADAPTER).test();
177         observer.assertError(throwable -> throwable.getMessage()
178             .equals("Get Zone offset failed for 150.62.25.26 . Empty output received"));
179     }
180
181     @Test
182     void testGetTimeOffsetFailExecutionException() {
183         final TestObserver<ZoneId> observer = restClient.getTimeZone(ADAPTER).test();
184         observer.assertError(throwable -> throwable.getMessage().equals("Failed to get Zone ID for 150.62.25.26"));
185     }
186 }