NONRTRIC - Bugfix 94/10194/1
authorPatrikBuhr <patrik.buhr@est.tech>
Mon, 19 Dec 2022 09:27:28 +0000 (10:27 +0100)
committerPatrikBuhr <patrik.buhr@est.tech>
Mon, 19 Dec 2022 14:39:41 +0000 (15:39 +0100)
If a dataproducer was restarted and a data job was updated, the producer
could get the old job definition after restart.

Updated springboot version.

Signed-off-by: PatrikBuhr <patrik.buhr@est.tech>
Issue-ID: NONRTRIC-815
Change-Id: Ida53df635ac596570e3763cbae211853a9294391

14 files changed:
pom.xml
src/main/java/org/oransc/ics/controllers/a1e/A1eCallbacks.java
src/main/java/org/oransc/ics/controllers/a1e/A1eController.java
src/main/java/org/oransc/ics/controllers/authorization/AuthorizationCheck.java
src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerCallbacks.java
src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerController.java
src/main/java/org/oransc/ics/controllers/r1producer/ProducerCallbacks.java
src/main/java/org/oransc/ics/controllers/r1producer/ProducerController.java
src/main/java/org/oransc/ics/repository/InfoJob.java
src/main/java/org/oransc/ics/repository/InfoJobs.java
src/main/java/org/oransc/ics/repository/InfoProducers.java
src/main/java/org/oransc/ics/tasks/ProducerSupervision.java
src/test/java/org/oransc/ics/ApplicationTest.java
src/test/java/org/oransc/ics/MockInformationService.java

diff --git a/pom.xml b/pom.xml
index 1bf53ad..1e7b43a 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
-        <version>2.6.6</version>
+        <version>2.7.6</version>
         <relativePath />
     </parent>
     <groupId>org.o-ran-sc.nonrtric.plt</groupId>
             <artifactId>s3</artifactId>
             <version>2.17.292</version>
         </dependency>
-     
         <!-- TEST -->
         <dependency>
             <groupId>org.springdoc</groupId>
         <system>JIRA</system>
         <url>https://jira.o-ran-sc.org/</url>
     </issueManagement>
-</project>
+</project>
\ No newline at end of file
index 288c31a..e5b3313 100644 (file)
@@ -36,7 +36,6 @@ import org.oransc.ics.repository.InfoProducers;
 import org.oransc.ics.repository.InfoType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import reactor.core.publisher.Flux;
@@ -55,7 +54,6 @@ public class A1eCallbacks {
     private final AsyncRestClient restClient;
     private final InfoJobs eiJobs;
 
-    @Autowired
     public A1eCallbacks(ApplicationConfig config, InfoJobs eiJobs, SecurityContext securityContext) {
         AsyncRestClientFactory restClientFactory =
             new AsyncRestClientFactory(config.getWebClientConfig(), securityContext);
index ac0cd3d..491e0dd 100644 (file)
@@ -296,14 +296,19 @@ public class A1eController {
         @RequestHeader Map<String, String> headers) throws ServiceException {
 
         final boolean isNewJob = this.infoJobs.get(eiJobId) == null;
-        InfoType eiType = this.infoTypes.getCompatibleType(eiJobObject.eiTypeId);
-
-        return authorization.authorizeDataJob(headers, eiType, eiJobObject.jobDefinition, AccessType.WRITE) //
-            .flatMap(x -> validatePutEiJob(eiJobId, eiType, eiJobObject)) //
-            .flatMap(job -> startEiJob(job, eiType)) //
-            .doOnNext(newEiJob -> this.infoJobs.put(newEiJob)) //
-            .map(newEiJob -> new ResponseEntity<>(isNewJob ? HttpStatus.CREATED : HttpStatus.OK)) //
-            .onErrorResume(throwable -> Mono.just(ErrorResponse.create(throwable, HttpStatus.INTERNAL_SERVER_ERROR)));
+        try {
+            InfoType eiType = this.infoTypes.getCompatibleType(eiJobObject.eiTypeId);
+
+            return authorization.authorizeDataJob(headers, eiType, eiJobObject.jobDefinition, AccessType.WRITE) //
+                .flatMap(x -> validatePutEiJob(eiJobId, eiType, eiJobObject)) //
+                .flatMap(job -> startEiJob(job, eiType)) //
+                .doOnNext(newEiJob -> this.infoJobs.put(newEiJob)) //
+                .map(newEiJob -> new ResponseEntity<>(isNewJob ? HttpStatus.CREATED : HttpStatus.OK)) //
+                .onErrorResume(
+                    throwable -> Mono.just(ErrorResponse.create(throwable, HttpStatus.INTERNAL_SERVER_ERROR)));
+        } catch (Exception e) {
+            return Mono.just(ErrorResponse.create(e, HttpStatus.INTERNAL_SERVER_ERROR));
+        }
     }
 
     private Mono<InfoJob> startEiJob(InfoJob newEiJob, InfoType type) {
index de098c4..14b0291 100644 (file)
@@ -36,7 +36,6 @@ import org.oransc.ics.repository.InfoJob;
 import org.oransc.ics.repository.InfoType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Component;
 import reactor.core.publisher.Mono;
@@ -49,7 +48,6 @@ public class AuthorizationCheck {
     private final AsyncRestClient restClient;
     private static Gson gson = new GsonBuilder().disableHtmlEscaping().create();
 
-    @Autowired
     public AuthorizationCheck(ApplicationConfig applicationConfig, SecurityContext securityContext) {
 
         this.applicationConfig = applicationConfig;
index bc1316d..266170b 100644 (file)
@@ -29,7 +29,6 @@ import org.oransc.ics.clients.SecurityContext;
 import org.oransc.ics.configuration.ApplicationConfig;
 import org.oransc.ics.repository.InfoType;
 import org.oransc.ics.repository.InfoTypeSubscriptions;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import reactor.core.publisher.Mono;
 
@@ -46,7 +45,6 @@ public class ConsumerCallbacks implements InfoTypeSubscriptions.ConsumerCallback
 
     public static final String API_VERSION = "version_1";
 
-    @Autowired
     public ConsumerCallbacks(ApplicationConfig config, InfoTypeSubscriptions infoTypeSubscriptions,
         SecurityContext securityContext) {
         AsyncRestClientFactory restClientFactory =
index 1039ce3..cd557c1 100644 (file)
@@ -57,7 +57,6 @@ import org.oransc.ics.repository.InfoTypeSubscriptions;
 import org.oransc.ics.repository.InfoTypes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
@@ -89,7 +88,6 @@ public class ConsumerController {
     private static Gson gson = new GsonBuilder().disableHtmlEscaping().create();
     private final AuthorizationCheck authorization;
 
-    @Autowired
     public ConsumerController(InfoJobs jobs, InfoTypes infoTypes, InfoProducers infoProducers,
         ProducerCallbacks producerCallbacks, InfoTypeSubscriptions infoTypeSubscriptions,
         AuthorizationCheck authorization) {
@@ -332,19 +330,24 @@ public class ConsumerController {
     public Mono<ResponseEntity<Object>> putIndividualInfoJob( //
         @PathVariable(ConsumerConsts.INFO_JOB_ID_PATH) String jobId, //
         @RequestBody ConsumerJobInfo informationJobObject, //
-        @RequestHeader Map<String, String> headers) throws ServiceException {
+        @RequestHeader Map<String, String> headers) {
 
         final boolean isNewJob = this.infoJobs.get(jobId) == null;
 
         logger.debug("PUT info job, id: {}, obj: {}", jobId, informationJobObject);
-        InfoType infoType = this.infoTypes.getCompatibleType(informationJobObject.infoTypeId);
-
-        return authorization.authorizeDataJob(headers, infoType, informationJobObject.jobDefinition, AccessType.WRITE) //
-            .flatMap(x -> validatePutInfoJob(jobId, infoType, informationJobObject)) //
-            .flatMap(job -> startInfoSubscriptionJob(job, infoType)) //
-            .doOnNext(this.infoJobs::put) //
-            .map(newJob -> new ResponseEntity<>(isNewJob ? HttpStatus.CREATED : HttpStatus.OK)) //
-            .onErrorResume(ErrorResponse::createMono);
+        try {
+            InfoType infoType = this.infoTypes.getCompatibleType(informationJobObject.infoTypeId);
+
+            return authorization
+                .authorizeDataJob(headers, infoType, informationJobObject.jobDefinition, AccessType.WRITE) //
+                .flatMap(x -> validatePutInfoJob(jobId, infoType, informationJobObject)) //
+                .flatMap(job -> startInfoSubscriptionJob(job, infoType)) //
+                .doOnNext(this.infoJobs::put) //
+                .map(newJob -> new ResponseEntity<>(isNewJob ? HttpStatus.CREATED : HttpStatus.OK)) //
+                .onErrorResume(ErrorResponse::createMono);
+        } catch (Exception e) {
+            return ErrorResponse.createMono(e, HttpStatus.NOT_FOUND);
+        }
     }
 
     @GetMapping(path = "/info-type-subscription", produces = MediaType.APPLICATION_JSON_VALUE)
index 24c1044..25e20e3 100644 (file)
@@ -106,10 +106,7 @@ public class ProducerCallbacks {
     }
 
     public Mono<String> startInfoJob(InfoProducer producer, InfoJob infoJob, Retry retrySpec) {
-        ProducerJobInfo request = new ProducerJobInfo(infoJob);
-        String body = gson.toJson(request);
-
-        return restClient.post(producer.getJobCallbackUrl(), body) //
+        return restClient.post(producer.getJobCallbackUrl(), jobCallbackBody(infoJob)) //
             .retryWhen(retrySpec) //
             .doOnNext(resp -> logger.debug("Job subscription {} started OK {}", infoJob.getId(), producer.getId())) //
             .onErrorResume(throwable -> {
@@ -121,6 +118,11 @@ public class ProducerCallbacks {
             .doOnNext(resp -> producer.setJobEnabled(infoJob));
     }
 
+    private String jobCallbackBody(InfoJob infoJob) {
+        ProducerJobInfo request = new ProducerJobInfo(infoJob);
+        return gson.toJson(request);
+    }
+
     private Collection<InfoProducer> getProducersForJob(InfoType type, InfoProducers infoProducers) {
         return infoProducers.getProducersSupportingType(type);
     }
index 826b091..b2a7d52 100644 (file)
@@ -223,15 +223,18 @@ public class ProducerController {
             name = ProducerConsts.INFO_TYPE_ID_PARAM,
             required = false,
             description = "If given, only the producers for the Info Type is returned.") //
-        @RequestParam(name = ProducerConsts.INFO_TYPE_ID_PARAM, required = false) String typeId //
-    ) throws ServiceException {
+        @RequestParam(name = ProducerConsts.INFO_TYPE_ID_PARAM, required = false) String typeId) {
         logger.debug("GET producer identifiers");
-        List<String> result = new ArrayList<>();
-        for (InfoProducer infoProducer : getProducers(typeId)) {
-            result.add(infoProducer.getId());
-        }
+        try {
+            List<String> result = new ArrayList<>();
+            for (InfoProducer infoProducer : getProducers(typeId)) {
+                result.add(infoProducer.getId());
+            }
 
-        return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK);
+            return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK);
+        } catch (Exception e) {
+            return ErrorResponse.create(e, HttpStatus.INTERNAL_SERVER_ERROR);
+        }
     }
 
     private Collection<InfoProducer> getProducers(String typeId) throws ServiceException {
index 87187b2..e9a43e8 100644 (file)
@@ -44,16 +44,16 @@ public class InfoJob {
     private final InfoType type;
 
     @Getter
-    private final String owner;
+    private String owner;
 
     @Getter
-    private final Object jobData;
+    private Object jobData;
 
     @Getter
-    private final String targetUrl;
+    private String targetUrl;
 
     @Getter
-    private final String jobStatusUrl;
+    private String jobStatusUrl;
 
     @Getter
     @Builder.Default
@@ -106,4 +106,11 @@ public class InfoJob {
         return this.id.equals(o);
     }
 
+    public synchronized void update(InfoJob job) {
+        this.jobData = job.jobData;
+        this.owner = job.owner;
+        this.jobStatusUrl = job.jobStatusUrl;
+        this.targetUrl = job.targetUrl;
+    }
+
 }
index 8cb5448..ff5a403 100644 (file)
@@ -177,9 +177,14 @@ public class InfoJobs {
     }
 
     private void doPut(InfoJob job) {
-        allEiJobs.put(job.getId(), job);
-        jobsByType.put(job.getType().getId(), job);
-        jobsByOwner.put(job.getOwner(), job);
+        InfoJob prevDefinition = this.get(job.getId());
+        if (prevDefinition == null) {
+            allEiJobs.put(job.getId(), job);
+            jobsByType.put(job.getType().getId(), job);
+            jobsByOwner.put(job.getOwner(), job);
+        } else {
+            prevDefinition.update(job);
+        }
     }
 
     private void storeJob(InfoJob job) {
index e8e206a..aab4608 100644 (file)
@@ -32,7 +32,6 @@ import org.oransc.ics.controllers.r1producer.ProducerCallbacks;
 import org.oransc.ics.exceptions.ServiceException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Component;
 
@@ -44,18 +43,18 @@ import org.springframework.stereotype.Component;
 public class InfoProducers {
     private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
     private final Map<String, InfoProducer> allInfoProducers = new HashMap<>();
-
-    @Autowired
-    private ProducerCallbacks producerCallbacks;
-
-    @Autowired
-    private A1eCallbacks consumerCallbacks;
-
-    @Autowired
-    private InfoJobs infoJobs;
-
-    @Autowired
-    private InfoTypes infoTypes;
+    private final ProducerCallbacks producerCallbacks;
+    private final A1eCallbacks consumerCallbacks;
+    private final InfoJobs infoJobs;
+    private final InfoTypes infoTypes;
+
+    public InfoProducers(ProducerCallbacks producerCallbacks, A1eCallbacks consumerCallbacks, InfoJobs infoJobs,
+        InfoTypes infoTypes) {
+        this.producerCallbacks = producerCallbacks;
+        this.consumerCallbacks = consumerCallbacks;
+        this.infoJobs = infoJobs;
+        this.infoTypes = infoTypes;
+    }
 
     public InfoProducer registerProducer(InfoProducerRegistrationInfo producerInfo) {
         final String producerId = producerInfo.getId();
index 36ca28e..a42366e 100644 (file)
@@ -20,7 +20,6 @@
 
 package org.oransc.ics.tasks;
 
-import org.oransc.ics.configuration.ApplicationConfig;
 import org.oransc.ics.controllers.a1e.A1eCallbacks;
 import org.oransc.ics.controllers.r1producer.ProducerCallbacks;
 import org.oransc.ics.repository.InfoJob;
@@ -29,7 +28,6 @@ import org.oransc.ics.repository.InfoProducer;
 import org.oransc.ics.repository.InfoProducers;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
@@ -52,9 +50,8 @@ public class ProducerSupervision {
     private final ProducerCallbacks producerCallbacks;
     private final A1eCallbacks consumerCallbacks;
 
-    @Autowired
-    public ProducerSupervision(ApplicationConfig applicationConfig, InfoProducers infoProducers, InfoJobs infoJobs,
-        ProducerCallbacks producerCallbacks, A1eCallbacks consumerCallbacks) {
+    public ProducerSupervision(InfoProducers infoProducers, InfoJobs infoJobs, ProducerCallbacks producerCallbacks,
+        A1eCallbacks consumerCallbacks) {
         this.infoProducers = infoProducers;
         this.infoJobs = infoJobs;
         this.producerCallbacks = producerCallbacks;
index 0a2f4b1..d5f78fa 100644 (file)
@@ -88,8 +88,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
 import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.boot.test.web.server.LocalServerPort;
 import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
-import org.springframework.boot.web.server.LocalServerPort;
 import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
@@ -505,7 +505,7 @@ class ApplicationTest {
         putInfoProducerWithOneType(REG_TYPE_ID4, REG_TYPE_ID4);
         putInfoProducerWithOneType(REG_TYPE_ID5, REG_TYPE_ID5);
 
-        String url = A1eConsts.API_ROOT + "/eijobs/jobId";
+        String url = A1eConsts.API_ROOT + "/eijobs/" + EI_JOB_ID;
         String body = gson.toJson(eiJobInfo(PUT_TYPE_ID, EI_JOB_ID));
         ResponseEntity<String> resp = restClient().putForEntity(url, body).block();
         assertThat(this.infoJobs.size()).isEqualTo(1);
@@ -514,6 +514,25 @@ class ApplicationTest {
 
         resp = restClient().putForEntity(url, body).block();
         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
+
+        restClient().delete(url).block();
+
+    }
+
+    @Test
+    void testA1EPutJob_unknownType() throws Exception {
+        final String REG_TYPE_ID1 = "type_1.5.0"; // Compatible
+        putInfoProducerWithOneType(REG_TYPE_ID1, REG_TYPE_ID1);
+
+        String body = gson.toJson(eiJobInfo("junkTypeId", EI_JOB_ID));
+
+        String url = A1eConsts.API_ROOT + "/eijobs/jobId";
+        testErrorCode(restClient().put(url, body), HttpStatus.NOT_FOUND, "not found");
+
+        url = A1eConsts.API_ROOT + "/eijobs/" + EI_JOB_ID;
+        final String PUT_TYPE_ERROR_ID = "type_1.1";
+        body = gson.toJson(eiJobInfo(PUT_TYPE_ERROR_ID, EI_JOB_ID));
+        testErrorCode(restClient().put(url, body), HttpStatus.NOT_FOUND, "not found");
     }
 
     @Test
@@ -538,6 +557,9 @@ class ApplicationTest {
         assertThat(job.getOwner()).isEqualTo("owner");
 
         verifyJobStatus(EI_JOB_ID, "ENABLED");
+
+        body = gson.toJson(consumerJobInfo("junkTypeId", "jobId", ""));
+        testErrorCode(restClient().put(url, body), HttpStatus.NOT_FOUND, "not found");
     }
 
     @Test
@@ -591,8 +613,8 @@ class ApplicationTest {
 
         String url = A1eConsts.API_ROOT + "/eijobs/jobId";
         // The element with name "property1" is mandatory in the schema
-        A1eEiJobInfo jobInfo =
-            new A1eEiJobInfo(TYPE_ID, jsonObject("{ \"XXstring\" : \"value\" }"), "owner", "targetUri", "jobStatusUrl");
+        A1eEiJobInfo jobInfo = new A1eEiJobInfo(TYPE_ID, toJsonObject("{ \"XXstring\" : \"value\" }"), "owner",
+            "targetUri", "jobStatusUrl");
         String body = gson.toJson(jobInfo);
 
         testErrorCode(restClient().put(url, body), HttpStatus.BAD_REQUEST, "Json validation failure");
@@ -608,7 +630,7 @@ class ApplicationTest {
         String url = ConsumerConsts.API_ROOT + "/info-jobs/jobId";
         // The element with name "property1" is mandatory in the schema
         ConsumerJobInfo jobInfo =
-            new ConsumerJobInfo(TYPE_ID, jsonObject("{ \"XXstring\" : \"value\" }"), "owner", "targetUri", null);
+            new ConsumerJobInfo(TYPE_ID, toJsonObject("{ \"XXstring\" : \"value\" }"), "owner", "targetUri", null);
         String body = gson.toJson(jobInfo);
 
         testErrorCode(restClient().put(url, body), HttpStatus.BAD_REQUEST, "Json validation failure");
@@ -620,7 +642,7 @@ class ApplicationTest {
 
         String url = ConsumerConsts.API_ROOT + "/info-jobs/jobId";
 
-        ConsumerJobInfo jobInfo = new ConsumerJobInfo(TYPE_ID, jsonObject(), "owner", "junk", null);
+        ConsumerJobInfo jobInfo = new ConsumerJobInfo(TYPE_ID, jsonObject(""), "owner", "junk", null);
         String body = gson.toJson(jobInfo);
 
         testErrorCode(restClient().put(url, body), HttpStatus.BAD_REQUEST, "URI: junk is not absolute");
@@ -1302,7 +1324,7 @@ class ApplicationTest {
 
     ConsumerJobInfo consumerJobInfo(String typeId, String infoJobId, String owner)
         throws JsonMappingException, JsonProcessingException {
-        return new ConsumerJobInfo(typeId, jsonObject(), owner, "https://junk.com",
+        return new ConsumerJobInfo(typeId, jsonObject(owner), owner, "https://junk.com",
             baseUrl() + A1eCallbacksSimulatorController.getJobStatusUrl(infoJobId));
     }
 
@@ -1316,11 +1338,11 @@ class ApplicationTest {
     }
 
     A1eEiJobInfo eiJobInfo(String typeId, String infoJobId, String owner) throws Exception {
-        return new A1eEiJobInfo(typeId, jsonObject(), owner, "https://junk.com",
+        return new A1eEiJobInfo(typeId, jsonObject(owner), owner, "https://junk.com",
             baseUrl() + A1eCallbacksSimulatorController.getJobStatusUrl(infoJobId));
     }
 
-    private Object jsonObject(String json) {
+    private Object toJsonObject(String json) {
         try {
             return JsonParser.parseString(json).getAsJsonObject();
         } catch (Exception e) {
@@ -1328,8 +1350,12 @@ class ApplicationTest {
         }
     }
 
+    private Object jsonObject(String aValue) {
+        return toJsonObject("{ " + EI_JOB_PROPERTY + " : \"" + aValue + "\" }");
+    }
+
     private Object typeSpecifcInfoObject() {
-        return jsonObject("{ \"propertyName\" : \"value\" }");
+        return toJsonObject("{ \"propertyName\" : \"value\" }");
     }
 
     private Object jsonSchemaObject() {
@@ -1346,11 +1372,7 @@ class ApplicationTest {
             + EI_JOB_PROPERTY //
             + "]" //
             + "}"; //
-        return jsonObject(schemaStr);
-    }
-
-    private Object jsonObject() {
-        return jsonObject("{ " + EI_JOB_PROPERTY + " : \"value\" }");
+        return toJsonObject(schemaStr);
     }
 
     private InfoJob putEiJob(String infoTypeId, String jobId, String owner) throws Exception {
@@ -1402,7 +1424,9 @@ class ApplicationTest {
 
     private InfoType putInfoProducerWithOneType(String producerId, String infoTypeId)
         throws JsonMappingException, JsonProcessingException, ServiceException {
-        this.putInfoType(infoTypeId);
+        if (this.infoTypes.get(infoTypeId) == null) {
+            this.putInfoType(infoTypeId);
+        }
 
         String url = ProducerConsts.API_ROOT + "/info-producers/" + producerId;
         String body = gson.toJson(producerInfoRegistratioInfo(infoTypeId));
index fc21315..7d09a6a 100644 (file)
@@ -25,7 +25,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
-import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.boot.test.web.server.LocalServerPort;
 import org.springframework.test.context.TestPropertySource;
 
 @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)