2 * ========================LICENSE_START=================================
4 * ======================================================================
5 * Copyright (C) 2019-2020 Nordix Foundation. All rights reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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===================================
21 package org.oransc.enrichment;
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.awaitility.Awaitility.await;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
27 import com.google.gson.Gson;
28 import com.google.gson.GsonBuilder;
29 import com.google.gson.JsonElement;
30 import com.google.gson.JsonObject;
31 import com.google.gson.JsonPrimitive;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Collection;
37 import org.junit.jupiter.api.AfterEach;
38 import org.junit.jupiter.api.BeforeEach;
39 import org.junit.jupiter.api.Test;
40 import org.junit.jupiter.api.extension.ExtendWith;
41 import org.oransc.enrichment.clients.AsyncRestClient;
42 import org.oransc.enrichment.clients.ProducerJobInfo;
43 import org.oransc.enrichment.configuration.ApplicationConfig;
44 import org.oransc.enrichment.configuration.ImmutableWebClientConfig;
45 import org.oransc.enrichment.configuration.WebClientConfig;
46 import org.oransc.enrichment.controller.ProducerSimulatorController;
47 import org.oransc.enrichment.controllers.consumer.ConsumerConsts;
48 import org.oransc.enrichment.controllers.consumer.ConsumerEiJobInfo;
49 import org.oransc.enrichment.controllers.producer.ProducerConsts;
50 import org.oransc.enrichment.controllers.producer.ProducerRegistrationInfo;
51 import org.oransc.enrichment.controllers.producer.ProducerRegistrationInfo.ProducerEiTypeRegistrationInfo;
52 import org.oransc.enrichment.repository.EiJob;
53 import org.oransc.enrichment.repository.EiJobs;
54 import org.oransc.enrichment.repository.EiProducer;
55 import org.oransc.enrichment.repository.EiProducers;
56 import org.oransc.enrichment.repository.EiType;
57 import org.oransc.enrichment.repository.EiTypes;
58 import org.oransc.enrichment.repository.ImmutableEiJob;
59 import org.oransc.enrichment.repository.ImmutableEiProducer;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62 import org.springframework.beans.factory.annotation.Autowired;
63 import org.springframework.boot.test.context.SpringBootTest;
64 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
65 import org.springframework.boot.test.context.TestConfiguration;
66 import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
67 import org.springframework.boot.web.server.LocalServerPort;
68 import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
69 import org.springframework.context.ApplicationContext;
70 import org.springframework.context.annotation.Bean;
71 import org.springframework.http.HttpStatus;
72 import org.springframework.http.MediaType;
73 import org.springframework.http.ResponseEntity;
74 import org.springframework.test.context.TestPropertySource;
75 import org.springframework.test.context.junit.jupiter.SpringExtension;
76 import org.springframework.web.reactive.function.client.WebClientResponseException;
78 import reactor.core.publisher.Mono;
79 import reactor.test.StepVerifier;
81 @ExtendWith(SpringExtension.class)
82 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
85 "server.ssl.key-store=./config/keystore.jks", //
86 "app.webclient.trust-store=./config/truststore.jks"})
87 class ApplicationTest {
88 private static final Logger logger = LoggerFactory.getLogger(ApplicationTest.class);
91 ApplicationContext context;
100 EiProducers eiProducers;
103 ApplicationConfig applicationConfig;
106 ProducerSimulatorController producerSimulator;
108 private static Gson gson = new GsonBuilder() //
113 * Overrides the BeanFactory.
116 static class TestBeanFactory {
118 public ServletWebServerFactory servletContainer() {
119 return new TomcatServletWebServerFactory();
129 this.eiTypes.clear();
130 this.eiProducers.clear();
131 this.producerSimulator.getTestResults().reset();
136 assertThat(this.producerSimulator.getTestResults().errorFound).isFalse();
140 void getEiTypes() throws Exception {
142 String url = ConsumerConsts.API_ROOT + "/eitypes";
143 String rsp = restClient().get(url).block();
144 assertThat(rsp).isEqualTo("[\"test\"]");
148 void getEiType() throws Exception {
150 String url = ConsumerConsts.API_ROOT + "/eitypes/test";
151 String rsp = restClient().get(url).block();
152 assertThat(rsp).contains("job_data_schema");
156 void getEiTypeNotFound() throws Exception {
157 String url = ConsumerConsts.API_ROOT + "/eitypes/junk";
158 testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Could not find EI type: junk");
162 void getEiJobsIds() throws Exception {
163 addEiJob("typeId", "jobId");
164 String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs";
165 String rsp = restClient().get(url).block();
166 assertThat(rsp).isEqualTo("[\"jobId\"]");
170 void getEiJobTypeNotFound() throws Exception {
171 String url = ConsumerConsts.API_ROOT + "/eitypes/junk/eijobs";
172 testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Could not find EI type: junk");
176 void getEiJob() throws Exception {
177 addEiJob("typeId", "jobId");
178 String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
179 String rsp = restClient().get(url).block();
180 assertThat(rsp).contains("job_data");
184 void getEiJobStatus() throws Exception {
185 addEiJob("typeId", "jobId");
186 String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId/status";
187 String rsp = restClient().get(url).block();
188 assertThat(rsp).contains("ENABLED");
194 void deleteEiJob() throws Exception {
195 addEiJob("typeId", "jobId");
196 assertThat(this.eiJobs.size()).isEqualTo(1);
197 String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
198 restClient().delete(url).block();
199 assertThat(this.eiJobs.size()).isEqualTo(0);
201 ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults();
202 await().untilAsserted(() -> assertThat(simulatorResults.jobsStopped.size()).isEqualTo(1));
203 assertThat(simulatorResults.jobsStopped.get(0).id).isEqualTo("jobId");
207 void putEiJob() throws Exception {
210 String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
211 String body = gson.toJson(eiJobInfo());
212 ResponseEntity<String> resp = restClient().putForEntity(url, body).block();
213 assertThat(this.eiJobs.size()).isEqualTo(1);
214 assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.CREATED);
216 ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults();
217 await().untilAsserted(() -> assertThat(simulatorResults.jobsStarted.size()).isEqualTo(1));
218 ProducerJobInfo request = simulatorResults.jobsStarted.get(0);
219 assertThat(request.id).isEqualTo("jobId");
221 resp = restClient().putForEntity(url, body).block();
222 assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
223 EiJob job = this.eiJobs.getJob("jobId");
224 assertThat(job.owner()).isEqualTo("owner");
228 void getEiProducerTypes() throws Exception {
229 this.addEiJob("typeId", "jobId");
230 String url = ProducerConsts.API_ROOT + "/eitypes";
232 ResponseEntity<String> resp = restClient().getForEntity(url).block();
233 assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
237 void putEiProducer() throws Exception {
238 String url = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId";
239 String body = gson.toJson(producerEiRegistratioInfo());
241 ResponseEntity<String> resp = restClient().putForEntity(url, body).block();
242 assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.CREATED);
244 assertThat(this.eiTypes.size()).isEqualTo(1);
245 EiType type = this.eiTypes.getType("typeId");
246 assertThat(type.getProducerIds().contains("eiProducerId")).isTrue();
247 assertThat(this.eiProducers.size()).isEqualTo(1);
248 assertThat(this.eiProducers.get("eiProducerId").eiTypes().iterator().next().getId().equals("typeId")).isTrue();
250 resp = restClient().putForEntity(url, body).block();
251 assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
255 void putEiProducerExistingJob() throws Exception {
256 this.addEiJob("typeId", "jobId");
257 String url = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId";
258 String body = gson.toJson(producerEiRegistratioInfo());
260 ResponseEntity<String> resp = restClient().putForEntity(url, body).block();
261 assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.CREATED);
263 ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults();
264 await().untilAsserted(() -> assertThat(simulatorResults.jobsStarted.size()).isEqualTo(1));
265 ProducerJobInfo request = simulatorResults.jobsStarted.get(0);
266 assertThat(request.id).isEqualTo("jobId");
270 void getEiJobsForProducer() {
271 this.addEiJob("typeId", "jobId1");
272 this.addEiJob("typeId", "jobId2");
275 String url = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId";
276 String body = gson.toJson(producerEiRegistratioInfo());
277 restClient().putForEntity(url, body).block();
279 url = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId/eijobs";
280 ResponseEntity<String> resp = restClient().getForEntity(url).block();
281 assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
283 ProducerJobInfo[] parsedResp = gson.fromJson(resp.getBody(), ProducerJobInfo[].class);
284 assertThat(parsedResp[0].typeId).isEqualTo("typeId");
285 assertThat(parsedResp[1].typeId).isEqualTo("typeId");
289 void deleteEiProducer() throws Exception {
290 String url = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId";
291 String url2 = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId2";
292 String body = gson.toJson(producerEiRegistratioInfo());
293 restClient().putForEntity(url, body).block();
294 restClient().putForEntity(url2, body).block();
295 assertThat(this.eiProducers.size()).isEqualTo(2);
296 EiType type = this.eiTypes.getType("typeId");
297 assertThat(type.getProducerIds().contains("eiProducerId")).isTrue();
298 assertThat(type.getProducerIds().contains("eiProducerId2")).isTrue();
300 restClient().deleteForEntity(url).block();
301 assertThat(this.eiProducers.size()).isEqualTo(1);
302 assertThat(this.eiTypes.getType("typeId").getProducerIds().contains("eiProducerId")).isFalse();
304 restClient().deleteForEntity(url2).block();
305 assertThat(this.eiProducers.size()).isEqualTo(0);
306 assertThat(this.eiTypes.size()).isEqualTo(0);
309 ProducerEiTypeRegistrationInfo producerEiTypeRegistrationInfo() {
310 return new ProducerEiTypeRegistrationInfo(jsonObject(), "typeId");
313 ProducerRegistrationInfo producerEiRegistratioInfo() {
314 Collection<ProducerEiTypeRegistrationInfo> types = new ArrayList<>();
315 types.add(producerEiTypeRegistrationInfo());
316 return new ProducerRegistrationInfo(types, baseUrl() + ProducerSimulatorController.JOB_CREATED_URL,
317 baseUrl() + ProducerSimulatorController.JOB_DELETED_URL);
320 ConsumerEiJobInfo eiJobInfo() {
321 return new ConsumerEiJobInfo(jsonObject(), "owner");
324 JsonObject jsonObject() {
325 JsonObject jsonObj = new JsonObject();
326 JsonElement e = new JsonPrimitive(111);
327 jsonObj.add("param", e);
331 private EiJob addEiJob(String typeId, String jobId) {
332 EiType type = addEiType(typeId);
333 EiJob job = ImmutableEiJob.builder() //
337 .jobData(jsonObject()) //
339 this.eiJobs.put(job);
343 private EiType addEiType(String typeId) {
344 EiType eiType = new EiType(typeId, jsonObject());
345 this.eiTypes.put(eiType); //
346 EiProducer producer = ImmutableEiProducer.builder() //
348 .eiTypes(Arrays.asList(eiType)) //
349 .jobCreationCallbackUrl(baseUrl() + ProducerSimulatorController.JOB_CREATED_URL) //
350 .jobDeletionCallbackUrl(baseUrl() + ProducerSimulatorController.JOB_DELETED_URL) //
352 this.eiProducers.put(producer);
353 eiType.addProducer(producer);
357 private String baseUrl() {
358 return "https://localhost:" + this.port;
361 private AsyncRestClient restClient(boolean useTrustValidation) {
362 WebClientConfig config = this.applicationConfig.getWebClientConfig();
363 config = ImmutableWebClientConfig.builder() //
364 .keyStoreType(config.keyStoreType()) //
365 .keyStorePassword(config.keyStorePassword()) //
366 .keyStore(config.keyStore()) //
367 .keyPassword(config.keyPassword()) //
368 .isTrustStoreUsed(useTrustValidation) //
369 .trustStore(config.trustStore()) //
370 .trustStorePassword(config.trustStorePassword()) //
373 return new AsyncRestClient(baseUrl(), config);
376 private AsyncRestClient restClient() {
377 return restClient(false);
380 private void testErrorCode(Mono<?> request, HttpStatus expStatus, String responseContains) {
381 testErrorCode(request, expStatus, responseContains, true);
384 private void testErrorCode(Mono<?> request, HttpStatus expStatus, String responseContains,
385 boolean expectApplicationProblemJsonMediaType) {
386 StepVerifier.create(request) //
387 .expectSubscription() //
389 t -> checkWebClientError(t, expStatus, responseContains, expectApplicationProblemJsonMediaType)) //
393 private boolean checkWebClientError(Throwable throwable, HttpStatus expStatus, String responseContains,
394 boolean expectApplicationProblemJsonMediaType) {
395 assertTrue(throwable instanceof WebClientResponseException);
396 WebClientResponseException responseException = (WebClientResponseException) throwable;
397 assertThat(responseException.getStatusCode()).isEqualTo(expStatus);
398 assertThat(responseException.getResponseBodyAsString()).contains(responseContains);
399 if (expectApplicationProblemJsonMediaType) {
400 assertThat(responseException.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_PROBLEM_JSON);