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