Simulating producer errors
[nonrtric.git] / enrichment-coordinator-service / src / test / java / org / oransc / enrichment / ApplicationTest.java
1 /*-
2  * ========================LICENSE_START=================================
3  * ONAP : ccsdk oran
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
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.enrichment;
22
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;
26
27 import com.fasterxml.jackson.core.JsonProcessingException;
28 import com.fasterxml.jackson.databind.JsonMappingException;
29 import com.google.gson.Gson;
30 import com.google.gson.GsonBuilder;
31 import com.google.gson.JsonParser;
32
33 import java.util.ArrayList;
34 import java.util.Collection;
35
36 import org.junit.jupiter.api.AfterEach;
37 import org.junit.jupiter.api.BeforeEach;
38 import org.junit.jupiter.api.Test;
39 import org.junit.jupiter.api.extension.ExtendWith;
40 import org.oransc.enrichment.clients.AsyncRestClient;
41 import org.oransc.enrichment.clients.ProducerJobInfo;
42 import org.oransc.enrichment.configuration.ApplicationConfig;
43 import org.oransc.enrichment.configuration.ImmutableWebClientConfig;
44 import org.oransc.enrichment.configuration.WebClientConfig;
45 import org.oransc.enrichment.controller.ProducerSimulatorController;
46 import org.oransc.enrichment.controllers.consumer.ConsumerConsts;
47 import org.oransc.enrichment.controllers.consumer.ConsumerEiJobInfo;
48 import org.oransc.enrichment.controllers.consumer.ConsumerEiTypeInfo;
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.exceptions.ServiceException;
53 import org.oransc.enrichment.repository.EiJob;
54 import org.oransc.enrichment.repository.EiJobs;
55 import org.oransc.enrichment.repository.EiProducers;
56 import org.oransc.enrichment.repository.EiType;
57 import org.oransc.enrichment.repository.EiTypes;
58 import org.springframework.beans.factory.annotation.Autowired;
59 import org.springframework.boot.test.context.SpringBootTest;
60 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
61 import org.springframework.boot.test.context.TestConfiguration;
62 import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
63 import org.springframework.boot.web.server.LocalServerPort;
64 import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
65 import org.springframework.context.ApplicationContext;
66 import org.springframework.context.annotation.Bean;
67 import org.springframework.http.HttpStatus;
68 import org.springframework.http.MediaType;
69 import org.springframework.http.ResponseEntity;
70 import org.springframework.test.context.TestPropertySource;
71 import org.springframework.test.context.junit.jupiter.SpringExtension;
72 import org.springframework.web.reactive.function.client.WebClientResponseException;
73
74 import reactor.core.publisher.Mono;
75 import reactor.test.StepVerifier;
76
77 @ExtendWith(SpringExtension.class)
78 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
79 @TestPropertySource(
80     properties = { //
81         "server.ssl.key-store=./config/keystore.jks", //
82         "app.webclient.trust-store=./config/truststore.jks"})
83 class ApplicationTest {
84     private final String EI_TYPE_ID = "typeId";
85     private final String EI_PRODUCER_ID = "producerId";
86     private final String EI_JOB_PROPERTY = "\"property1\"";
87
88     @Autowired
89     ApplicationContext context;
90
91     @Autowired
92     EiJobs eiJobs;
93
94     @Autowired
95     EiTypes eiTypes;
96
97     @Autowired
98     EiProducers eiProducers;
99
100     @Autowired
101     ApplicationConfig applicationConfig;
102
103     @Autowired
104     ProducerSimulatorController producerSimulator;
105
106     private static Gson gson = new GsonBuilder() //
107         .serializeNulls() //
108         .create(); //
109
110     /**
111      * Overrides the BeanFactory.
112      */
113     @TestConfiguration
114     static class TestBeanFactory {
115         @Bean
116         public ServletWebServerFactory servletContainer() {
117             return new TomcatServletWebServerFactory();
118         }
119     }
120
121     @LocalServerPort
122     private int port;
123
124     @BeforeEach
125     void reset() {
126         this.eiJobs.clear();
127         this.eiTypes.clear();
128         this.eiProducers.clear();
129         this.producerSimulator.getTestResults().reset();
130     }
131
132     @AfterEach
133     void check() {
134         assertThat(this.producerSimulator.getTestResults().errorFound).isFalse();
135     }
136
137     @Test
138     void testGetEiTypes() throws Exception {
139         putEiProducerWithOneType(EI_PRODUCER_ID, "test");
140         String url = ConsumerConsts.API_ROOT + "/eitypes";
141         String rsp = restClient().get(url).block();
142         assertThat(rsp).isEqualTo("[\"test\"]");
143     }
144
145     @Test
146     void testGetEiType() throws Exception {
147         putEiProducerWithOneType(EI_PRODUCER_ID, "test");
148         String url = ConsumerConsts.API_ROOT + "/eitypes/test";
149         String rsp = restClient().get(url).block();
150         ConsumerEiTypeInfo info = gson.fromJson(rsp, ConsumerEiTypeInfo.class);
151         assertThat(info.jobParametersSchema).isNotNull();
152     }
153
154     @Test
155     void testGetEiTypeNotFound() throws Exception {
156         String url = ConsumerConsts.API_ROOT + "/eitypes/junk";
157         testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Could not find EI type: junk");
158     }
159
160     @Test
161     void testGetEiJobsIds() throws Exception {
162         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
163         putEiJob(EI_TYPE_ID, "jobId");
164         String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs";
165         String rsp = restClient().get(url).block();
166         assertThat(rsp).isEqualTo("[\"jobId\"]");
167     }
168
169     @Test
170     void testGetEiJobTypeNotFound() 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");
173     }
174
175     @Test
176     void testGetEiJob() throws Exception {
177         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
178         putEiJob(EI_TYPE_ID, "jobId");
179         String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
180         String rsp = restClient().get(url).block();
181         ConsumerEiJobInfo info = gson.fromJson(rsp, ConsumerEiJobInfo.class);
182         assertThat(info.owner).isEqualTo("owner");
183     }
184
185     @Test
186     void testGetEiJobNotFound() throws Exception {
187         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
188         String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/junk";
189         testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Could not find EI job: junk");
190     }
191
192     @Test
193     void testGetEiJobStatus() throws Exception {
194         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
195         putEiJob(EI_TYPE_ID, "jobId");
196         String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId/status";
197         String rsp = restClient().get(url).block();
198         assertThat(rsp).contains("ENABLED");
199     }
200
201     // Status TBD
202
203     @Test
204     void testDeleteEiJob() throws Exception {
205         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
206         putEiJob(EI_TYPE_ID, "jobId");
207         assertThat(this.eiJobs.size()).isEqualTo(1);
208         String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
209         restClient().delete(url).block();
210         assertThat(this.eiJobs.size()).isZero();
211
212         ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults();
213         await().untilAsserted(() -> assertThat(simulatorResults.jobsStopped.size()).isEqualTo(1));
214         assertThat(simulatorResults.jobsStopped.get(0).id).isEqualTo("jobId");
215     }
216
217     @Test
218     void testDeleteEiJobNotFound() throws Exception {
219         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
220         String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/junk";
221         testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Could not find EI job: junk");
222     }
223
224     @Test
225     void testPutEiJob() throws Exception {
226         // Test that one producer accepting a job is enough
227         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
228         putEiProducerWithOneTypeRejecting("simulateProducerError", EI_TYPE_ID);
229
230         String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
231         String body = gson.toJson(eiJobInfo());
232         ResponseEntity<String> resp = restClient().putForEntity(url, body).block();
233         assertThat(this.eiJobs.size()).isEqualTo(1);
234         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.CREATED);
235
236         ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults();
237         await().untilAsserted(() -> assertThat(simulatorResults.jobsStarted.size()).isEqualTo(1));
238         ProducerJobInfo request = simulatorResults.jobsStarted.get(0);
239         assertThat(request.id).isEqualTo("jobId");
240
241         assertThat(simulatorResults.noOfRejectedCreate).isEqualTo(1);
242
243         resp = restClient().putForEntity(url, body).block();
244         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
245         EiJob job = this.eiJobs.getJob("jobId");
246         assertThat(job.owner()).isEqualTo("owner");
247     }
248
249     @Test
250     void putEiProducerWithOneType_rejecting() throws JsonMappingException, JsonProcessingException, ServiceException {
251         putEiProducerWithOneTypeRejecting("simulateProducerError", EI_TYPE_ID);
252         String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
253         String body = gson.toJson(eiJobInfo());
254         testErrorCode(restClient().put(url, body), HttpStatus.CONFLICT, "Job not accepted by any producers");
255
256         ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults();
257         assertThat(simulatorResults.noOfRejectedCreate).isEqualTo(1);
258     }
259
260     @Test
261     void testPutEiJob_jsonSchemavalidationError() throws Exception {
262         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
263
264         String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
265         // The element with name "property1" is mandatory in the schema
266         ConsumerEiJobInfo jobInfo =
267             new ConsumerEiJobInfo(jsonObject("{ \"XXstring\" : \"value\" }"), "owner", "targetUri");
268         String body = gson.toJson(jobInfo);
269
270         testErrorCode(restClient().put(url, body), HttpStatus.CONFLICT, "Json validation failure");
271     }
272
273     @Test
274     void testGetEiProducerTypes() throws Exception {
275         final String EI_TYPE_ID_2 = EI_TYPE_ID + "_2";
276         putEiProducerWithOneType("producer1", EI_TYPE_ID);
277         putEiJob(EI_TYPE_ID, "jobId");
278         putEiProducerWithOneType("producer2", EI_TYPE_ID_2);
279         putEiJob(EI_TYPE_ID_2, "jobId2");
280         String url = ProducerConsts.API_ROOT + "/eitypes";
281
282         ResponseEntity<String> resp = restClient().getForEntity(url).block();
283         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
284         assertThat(resp.getBody()).contains(EI_TYPE_ID);
285         assertThat(resp.getBody()).contains(EI_TYPE_ID_2);
286     }
287
288     @Test
289     void testReplacingEiProducerTypes() throws Exception {
290         final String REPLACED_TYPE_ID = "replaced";
291         putEiProducerWithOneType(EI_PRODUCER_ID, REPLACED_TYPE_ID);
292         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
293
294         String url = ProducerConsts.API_ROOT + "/eitypes";
295
296         ResponseEntity<String> resp = restClient().getForEntity(url).block();
297         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
298         assertThat(resp.getBody()).contains(EI_TYPE_ID);
299         assertThat(resp.getBody()).doesNotContain(REPLACED_TYPE_ID);
300     }
301
302     @Test
303     void testChangingEiTypeGetRejected() throws Exception {
304         putEiProducerWithOneType("producer1", "typeId1");
305         putEiProducerWithOneType("producer2", "typeId2");
306         putEiJob("typeId1", "jobId");
307
308         String url = ConsumerConsts.API_ROOT + "/eitypes/typeId2/eijobs/jobId";
309         String body = gson.toJson(eiJobInfo());
310         testErrorCode(restClient().put(url, body), HttpStatus.CONFLICT,
311             "Not allowed to change type for existing EI job");
312     }
313
314     @Test
315     void testPutEiProducer() throws Exception {
316         String url = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId";
317         String body = gson.toJson(producerEiRegistratioInfo(EI_TYPE_ID));
318
319         ResponseEntity<String> resp = restClient().putForEntity(url, body).block();
320         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.CREATED);
321
322         assertThat(this.eiTypes.size()).isEqualTo(1);
323         EiType type = this.eiTypes.getType(EI_TYPE_ID);
324         assertThat(type.getProducerIds()).contains("eiProducerId");
325         assertThat(this.eiProducers.size()).isEqualTo(1);
326         assertThat(this.eiProducers.get("eiProducerId").eiTypes().iterator().next().getId()).isEqualTo(EI_TYPE_ID);
327
328         resp = restClient().putForEntity(url, body).block();
329         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
330
331         resp = restClient().getForEntity(url).block();
332         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
333         assertThat(resp.getBody()).isEqualTo(body);
334     }
335
336     @Test
337     void testPutEiProducerExistingJob() throws Exception {
338         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
339         putEiJob(EI_TYPE_ID, "jobId");
340         String url = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId";
341         String body = gson.toJson(producerEiRegistratioInfo(EI_TYPE_ID));
342         restClient().putForEntity(url, body).block();
343
344         ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults();
345         await().untilAsserted(() -> assertThat(simulatorResults.jobsStarted.size()).isEqualTo(2));
346         ProducerJobInfo request = simulatorResults.jobsStarted.get(0);
347         assertThat(request.id).isEqualTo("jobId");
348     }
349
350     @Test
351     void testPutProducerAndEiJob() throws Exception {
352         String url = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId";
353         String body = gson.toJson(producerEiRegistratioInfo(EI_TYPE_ID));
354         restClient().putForEntity(url, body).block();
355         assertThat(this.eiTypes.size()).isEqualTo(1);
356         this.eiTypes.getType(EI_TYPE_ID);
357
358         url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
359         body = gson.toJson(eiJobInfo());
360         restClient().putForEntity(url, body).block();
361
362         ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults();
363         await().untilAsserted(() -> assertThat(simulatorResults.jobsStarted.size()).isEqualTo(1));
364         ProducerJobInfo request = simulatorResults.jobsStarted.get(0);
365         assertThat(request.id).isEqualTo("jobId");
366     }
367
368     @Test
369     void testGetEiJobsForProducer() throws JsonMappingException, JsonProcessingException, ServiceException {
370         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
371         putEiJob(EI_TYPE_ID, "jobId1");
372         putEiJob(EI_TYPE_ID, "jobId2");
373
374         // PUT a consumer
375         String url = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId";
376         String body = gson.toJson(producerEiRegistratioInfo(EI_TYPE_ID));
377         restClient().putForEntity(url, body).block();
378
379         url = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId/eijobs";
380         ResponseEntity<String> resp = restClient().getForEntity(url).block();
381         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
382
383         ProducerJobInfo[] parsedResp = gson.fromJson(resp.getBody(), ProducerJobInfo[].class);
384         assertThat(parsedResp[0].typeId).isEqualTo(EI_TYPE_ID);
385         assertThat(parsedResp[1].typeId).isEqualTo(EI_TYPE_ID);
386     }
387
388     @Test
389     void testDeleteEiProducer() throws Exception {
390         putEiProducerWithOneType("eiProducerId", EI_TYPE_ID);
391         putEiProducerWithOneType("eiProducerId2", EI_TYPE_ID);
392
393         assertThat(this.eiProducers.size()).isEqualTo(2);
394         EiType type = this.eiTypes.getType(EI_TYPE_ID);
395         assertThat(type.getProducerIds()).contains("eiProducerId");
396         assertThat(type.getProducerIds()).contains("eiProducerId2");
397         putEiJob(EI_TYPE_ID, "jobId");
398         assertThat(this.eiJobs.size()).isEqualTo(1);
399
400         String url = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId";
401         restClient().deleteForEntity(url).block();
402         assertThat(this.eiProducers.size()).isEqualTo(1);
403         assertThat(this.eiTypes.getType(EI_TYPE_ID).getProducerIds()).doesNotContain("eiProducerId");
404         assertThat(this.eiJobs.size()).isEqualTo(1);
405
406         String url2 = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId2";
407         restClient().deleteForEntity(url2).block();
408         assertThat(this.eiProducers.size()).isZero();
409         assertThat(this.eiTypes.size()).isZero();
410         assertThat(this.eiJobs.size()).isZero();
411     }
412
413     @Test
414     void testGetProducerEiType() throws JsonMappingException, JsonProcessingException, ServiceException {
415         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
416         String url = ProducerConsts.API_ROOT + "/eitypes/" + EI_TYPE_ID;
417         ResponseEntity<String> resp = restClient().getForEntity(url).block();
418         assertThat(resp.getBody()).contains(EI_PRODUCER_ID);
419     }
420
421     @Test
422     void testGetProducerIdentifiers() throws JsonMappingException, JsonProcessingException, ServiceException {
423         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
424         String url = ProducerConsts.API_ROOT + "/eiproducers";
425         ResponseEntity<String> resp = restClient().getForEntity(url).block();
426         assertThat(resp.getBody()).contains(EI_PRODUCER_ID);
427     }
428
429     ProducerEiTypeRegistrationInfo producerEiTypeRegistrationInfo(String typeId)
430         throws JsonMappingException, JsonProcessingException {
431         return new ProducerEiTypeRegistrationInfo(jsonSchemaObject(), typeId);
432     }
433
434     ProducerRegistrationInfo producerEiRegistratioInfoRejecting(String typeId)
435         throws JsonMappingException, JsonProcessingException {
436         Collection<ProducerEiTypeRegistrationInfo> types = new ArrayList<>();
437         types.add(producerEiTypeRegistrationInfo(typeId));
438         return new ProducerRegistrationInfo(types, baseUrl() + ProducerSimulatorController.JOB_CREATED_ERROR_URL,
439             baseUrl() + ProducerSimulatorController.JOB_DELETED_ERROR_URL);
440     }
441
442     ProducerRegistrationInfo producerEiRegistratioInfo(String typeId)
443         throws JsonMappingException, JsonProcessingException {
444         Collection<ProducerEiTypeRegistrationInfo> types = new ArrayList<>();
445         types.add(producerEiTypeRegistrationInfo(typeId));
446         return new ProducerRegistrationInfo(types, baseUrl() + ProducerSimulatorController.JOB_CREATED_URL,
447             baseUrl() + ProducerSimulatorController.JOB_DELETED_URL);
448     }
449
450     ConsumerEiJobInfo eiJobInfo() throws JsonMappingException, JsonProcessingException {
451         return new ConsumerEiJobInfo(jsonObject(), "owner", "targetUri");
452     }
453
454     Object jsonObject(String json) {
455         try {
456             return JsonParser.parseString(json).getAsJsonObject();
457         } catch (Exception e) {
458             throw new NullPointerException(e.toString());
459         }
460     }
461
462     Object jsonSchemaObject() {
463         // a json schema with one mandatory property named "string"
464         String schemaStr = "{" //
465             + "\"$schema\": \"http://json-schema.org/draft-04/schema#\"," //
466             + "\"type\": \"object\"," //
467             + "\"properties\": {" //
468             + EI_JOB_PROPERTY + " : {" //
469             + "    \"type\": \"string\"" //
470             + "  }" //
471             + "}," //
472             + "\"required\": [" //
473             + EI_JOB_PROPERTY //
474             + "]" //
475             + "}"; //
476         return jsonObject(schemaStr);
477     }
478
479     Object jsonObject() {
480         return jsonObject("{ " + EI_JOB_PROPERTY + " : \"value\" }");
481     }
482
483     private EiJob putEiJob(String eiTypeId, String jobId)
484         throws JsonMappingException, JsonProcessingException, ServiceException {
485
486         String url = ConsumerConsts.API_ROOT + "/eitypes/" + eiTypeId + "/eijobs/" + jobId;
487         String body = gson.toJson(eiJobInfo());
488         restClient().putForEntity(url, body).block();
489
490         return this.eiJobs.getJob(jobId);
491     }
492
493     private EiType putEiProducerWithOneTypeRejecting(String producerId, String eiTypeId)
494         throws JsonMappingException, JsonProcessingException, ServiceException {
495         String url = ProducerConsts.API_ROOT + "/eiproducers/" + producerId;
496         String body = gson.toJson(producerEiRegistratioInfoRejecting(eiTypeId));
497
498         restClient().putForEntity(url, body).block();
499         return this.eiTypes.getType(eiTypeId);
500     }
501
502     private EiType putEiProducerWithOneType(String producerId, String eiTypeId)
503         throws JsonMappingException, JsonProcessingException, ServiceException {
504         String url = ProducerConsts.API_ROOT + "/eiproducers/" + producerId;
505         String body = gson.toJson(producerEiRegistratioInfo(eiTypeId));
506
507         restClient().putForEntity(url, body).block();
508         return this.eiTypes.getType(eiTypeId);
509     }
510
511     private String baseUrl() {
512         return "https://localhost:" + this.port;
513     }
514
515     private AsyncRestClient restClient(boolean useTrustValidation) {
516         WebClientConfig config = this.applicationConfig.getWebClientConfig();
517         config = ImmutableWebClientConfig.builder() //
518             .keyStoreType(config.keyStoreType()) //
519             .keyStorePassword(config.keyStorePassword()) //
520             .keyStore(config.keyStore()) //
521             .keyPassword(config.keyPassword()) //
522             .isTrustStoreUsed(useTrustValidation) //
523             .trustStore(config.trustStore()) //
524             .trustStorePassword(config.trustStorePassword()) //
525             .build();
526
527         return new AsyncRestClient(baseUrl(), config);
528     }
529
530     private AsyncRestClient restClient() {
531         return restClient(false);
532     }
533
534     private void testErrorCode(Mono<?> request, HttpStatus expStatus, String responseContains) {
535         testErrorCode(request, expStatus, responseContains, true);
536     }
537
538     private void testErrorCode(Mono<?> request, HttpStatus expStatus, String responseContains,
539         boolean expectApplicationProblemJsonMediaType) {
540         StepVerifier.create(request) //
541             .expectSubscription() //
542             .expectErrorMatches(
543                 t -> checkWebClientError(t, expStatus, responseContains, expectApplicationProblemJsonMediaType)) //
544             .verify();
545     }
546
547     private boolean checkWebClientError(Throwable throwable, HttpStatus expStatus, String responseContains,
548         boolean expectApplicationProblemJsonMediaType) {
549         assertTrue(throwable instanceof WebClientResponseException);
550         WebClientResponseException responseException = (WebClientResponseException) throwable;
551         assertThat(responseException.getStatusCode()).isEqualTo(expStatus);
552         assertThat(responseException.getResponseBodyAsString()).contains(responseContains);
553         if (expectApplicationProblemJsonMediaType) {
554             assertThat(responseException.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_PROBLEM_JSON);
555         }
556         return true;
557     }
558
559 }