From deabb9bd3f5ba86cafa978954356e5d4ba8a4ab3 Mon Sep 17 00:00:00 2001 From: Stanislav Marszalek Date: Fri, 6 Aug 2021 11:12:26 +0200 Subject: O1 PM Bulk support - Unknown cell handling Issue-ID: INT-1945 Signed-off-by: Stanislav Marszalek Change-Id: I02d3684c98d563d7f386de2fdf032e930ac12b3f --- doc/resources/vnf.config | 2 ++ .../controller/RanCellController.java | 22 ++++++++++----- .../org/onap/a1pesimulator/data/VnfConfig.java | 4 +++ .../org/onap/a1pesimulator/exception/ApiError.java | 30 +++++++++++++++++++++ .../exception/CellNotFoundException.java | 25 +++++++++++++++++ .../exception/RestExceptionHandler.java | 31 ++++++++++++++++++++++ .../service/cell/RanCellStateService.java | 8 +----- .../a1pesimulator/service/cell/RanCellsHolder.java | 11 +++++--- .../service/fileready/FtpServerService.java | 18 +++++++------ .../a1pesimulator/service/ves/RanVesHolder.java | 6 +++-- src/main/resources/application.properties | 2 -- .../service/fileready/FtpServerServiceTest.java | 21 ++++++++++----- src/test/resources/application.properties | 2 -- src/test/resources/vnf.config | 2 ++ 14 files changed, 146 insertions(+), 38 deletions(-) create mode 100644 src/main/java/org/onap/a1pesimulator/exception/ApiError.java create mode 100644 src/main/java/org/onap/a1pesimulator/exception/CellNotFoundException.java create mode 100644 src/main/java/org/onap/a1pesimulator/exception/RestExceptionHandler.java diff --git a/doc/resources/vnf.config b/doc/resources/vnf.config index 25d05d3..d14fe7b 100644 --- a/doc/resources/vnf.config +++ b/doc/resources/vnf.config @@ -5,4 +5,6 @@ vesPassword=sample1 vnfId=de305d54-75b4-431b-adb2-eb6b9e546014 vnfName=ibcx0001vm002ssc001 vnfType=oran_sim_type +ftpHost=localhost +ftpPort=22222 repPeriod=90 \ No newline at end of file diff --git a/src/main/java/org/onap/a1pesimulator/controller/RanCellController.java b/src/main/java/org/onap/a1pesimulator/controller/RanCellController.java index ae20f1c..f79cb64 100644 --- a/src/main/java/org/onap/a1pesimulator/controller/RanCellController.java +++ b/src/main/java/org/onap/a1pesimulator/controller/RanCellController.java @@ -60,10 +60,6 @@ public class RanCellController { @GetMapping(value = "/{identifier}") public ResponseEntity getCellById(final @PathVariable String identifier) { - - if (!ranCellService.getCellIds().contains(identifier)) { - return ResponseEntity.notFound().build(); - } return ResponseEntity.ok(ranCellService.getCellById(identifier)); } @@ -71,7 +67,7 @@ public class RanCellController { @PostMapping(value = "/{identifier}/startFailure") public ResponseEntity startSendingFailureVesEvents(@ApiParam(value = "Cell Id") final @PathVariable String identifier, @ApiParam(value = "Reporting Method", defaultValue = "FILE_READY", required = true) final @RequestParam() ReportingMethodEnum reportingMethod) { - + checkIfCellExistOrThrowException(identifier); ranCellService.failure(identifier); ranVesBrokerService.startSendingFailureVesEvents(identifier, reportingMethod); ranCellStateService.failingState(identifier); @@ -82,7 +78,7 @@ public class RanCellController { @ApiOperation("Stop sending failure VES events for specific cell") @PostMapping(value = "/{identifier}/stopFailure") public ResponseEntity stopSendingFailureVesEvents(@ApiParam(value = "Cell Id") final @PathVariable String identifier) { - + checkIfCellExistOrThrowException(identifier); ranCellService.recoverFromFailure(identifier); Optional vesEvent = ranVesBrokerService.stopSendingVesEvents(identifier); @@ -101,8 +97,9 @@ public class RanCellController { @ApiParam(value = "Cell Id") final @PathVariable String identifier, @ApiParam(value = "Granularity period in seconds", example = "60") final @RequestParam(required = false) Integer interval, @ApiParam(value = "Reporting Method", defaultValue = "FILE_READY", required = true) final @RequestParam() ReportingMethodEnum reportingMethod) { - log.info("Start sending ves events every {} seconds for {} ", getInterval(interval), identifier); + checkIfCellExistOrThrowException(identifier); + log.info("Start sending ves events every {} seconds for {} ", getInterval(interval), identifier); VesEvent vesEvent = vesEventOpt.orElse(ranVesBrokerService.getGlobalPmVesStructure()); ResponseEntity responseEntity = @@ -118,6 +115,7 @@ public class RanCellController { @ApiOperation("Stop sending normal VES events for specific cell") @PostMapping(value = "/{identifier}/stop") public ResponseEntity stopSendingVesEvents(@ApiParam(value = "Cell Id") final @PathVariable String identifier) { + checkIfCellExistOrThrowException(identifier); log.info("Stop sending custom ves events for {}", identifier); Optional vesEvent = ranVesBrokerService.stopSendingVesEvents(identifier); if (!vesEvent.isPresent()) { @@ -130,6 +128,7 @@ public class RanCellController { @GetMapping(value = "/{identifier}/eventStructure") public ResponseEntity getVesEventStructure(final @PathVariable String identifier) { + checkIfCellExistOrThrowException(identifier); if (!ranVesBrokerService.getEnabledEventElementIdentifiers().contains(identifier)) { return ResponseEntity.notFound().build(); } @@ -142,4 +141,13 @@ public class RanCellController { } return requested; } + + /** + * Check if cell exists otherwise getCellById() throws CellNotFoundException which is catched by RestExceptionHandler.class + * + * @param identifier cellId + */ + private void checkIfCellExistOrThrowException(String identifier) { + ranCellService.getCellById(identifier); + } } diff --git a/src/main/java/org/onap/a1pesimulator/data/VnfConfig.java b/src/main/java/org/onap/a1pesimulator/data/VnfConfig.java index 9e59e9e..18ac422 100644 --- a/src/main/java/org/onap/a1pesimulator/data/VnfConfig.java +++ b/src/main/java/org/onap/a1pesimulator/data/VnfConfig.java @@ -40,6 +40,10 @@ public class VnfConfig { private String vnfId; @JsonProperty("vnfName") private String vnfName; + @JsonProperty("ftpHost") + private String ftpHost; + @JsonProperty("ftpPort") + private String ftpPort; @JsonProperty("repPeriod") private int repPeriod; diff --git a/src/main/java/org/onap/a1pesimulator/exception/ApiError.java b/src/main/java/org/onap/a1pesimulator/exception/ApiError.java new file mode 100644 index 0000000..13b2472 --- /dev/null +++ b/src/main/java/org/onap/a1pesimulator/exception/ApiError.java @@ -0,0 +1,30 @@ +package org.onap.a1pesimulator.exception; + +import java.time.LocalDateTime; + +import org.springframework.http.HttpStatus; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +class ApiError { + + private HttpStatus status; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss") + private LocalDateTime timestamp; + private String message; + private String debugMessage; + + private ApiError() { + timestamp = LocalDateTime.now(); + } + + ApiError(HttpStatus status) { + this(); + this.status = status; + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/a1pesimulator/exception/CellNotFoundException.java b/src/main/java/org/onap/a1pesimulator/exception/CellNotFoundException.java new file mode 100644 index 0000000..59562a2 --- /dev/null +++ b/src/main/java/org/onap/a1pesimulator/exception/CellNotFoundException.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2021 Samsung Electronics + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package org.onap.a1pesimulator.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(value = HttpStatus.NOT_FOUND) +public class CellNotFoundException extends RuntimeException { + + public CellNotFoundException(String errorMessage) { + super(errorMessage); + } +} diff --git a/src/main/java/org/onap/a1pesimulator/exception/RestExceptionHandler.java b/src/main/java/org/onap/a1pesimulator/exception/RestExceptionHandler.java new file mode 100644 index 0000000..95ec127 --- /dev/null +++ b/src/main/java/org/onap/a1pesimulator/exception/RestExceptionHandler.java @@ -0,0 +1,31 @@ +package org.onap.a1pesimulator.exception; + +import static org.springframework.http.HttpStatus.NOT_FOUND; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +@Order(Ordered.HIGHEST_PRECEDENCE) +@ControllerAdvice +public class RestExceptionHandler extends ResponseEntityExceptionHandler { + + private static final Logger log = LoggerFactory.getLogger(RestExceptionHandler.class); + + @ExceptionHandler(CellNotFoundException.class) + protected ResponseEntity handleEntityNotFound(CellNotFoundException ex) { + ApiError apiError = new ApiError(NOT_FOUND); + apiError.setMessage(ex.getMessage()); + return buildResponseEntity(apiError); + } + + private ResponseEntity buildResponseEntity(ApiError apiError) { + log.error(apiError.getMessage()); + return new ResponseEntity<>(apiError.getMessage(), apiError.getStatus()); + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/a1pesimulator/service/cell/RanCellStateService.java b/src/main/java/org/onap/a1pesimulator/service/cell/RanCellStateService.java index d69629e..274c6d1 100644 --- a/src/main/java/org/onap/a1pesimulator/service/cell/RanCellStateService.java +++ b/src/main/java/org/onap/a1pesimulator/service/cell/RanCellStateService.java @@ -105,13 +105,7 @@ public class RanCellStateService { } private Optional getCell(String identifier) { - CellDetails cell = null; - try { - cell = cellsHolder.getCellById(identifier); - } catch (RuntimeException e) { - log.info("Exception was thrown: ", e); - } - + CellDetails cell = cellsHolder.getCellById(identifier); if (cell == null) { return Optional.empty(); } diff --git a/src/main/java/org/onap/a1pesimulator/service/cell/RanCellsHolder.java b/src/main/java/org/onap/a1pesimulator/service/cell/RanCellsHolder.java index 86fa32c..5cc04b2 100644 --- a/src/main/java/org/onap/a1pesimulator/service/cell/RanCellsHolder.java +++ b/src/main/java/org/onap/a1pesimulator/service/cell/RanCellsHolder.java @@ -24,15 +24,18 @@ import java.util.TreeMap; import java.util.function.BinaryOperator; import java.util.function.Predicate; import java.util.stream.Collectors; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; + import org.onap.a1pesimulator.data.cell.CellDetails; import org.onap.a1pesimulator.data.cell.CellList.Cell; import org.onap.a1pesimulator.data.cell.CellList.CellData; +import org.onap.a1pesimulator.exception.CellNotFoundException; import org.onap.a1pesimulator.util.TopologyReader; import org.springframework.stereotype.Service; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + @Service public class RanCellsHolder { @@ -52,7 +55,7 @@ public class RanCellsHolder { public CellDetails getCellById(String id) { if (!cellDetailsById.containsKey(id)) { - throw new RuntimeException(MessageFormat.format("Cell not found: {0}", id)); + throw new CellNotFoundException(MessageFormat.format("Cell not found: {0}", id)); } return cellDetailsById.get(id); } diff --git a/src/main/java/org/onap/a1pesimulator/service/fileready/FtpServerService.java b/src/main/java/org/onap/a1pesimulator/service/fileready/FtpServerService.java index a4145d5..f5627d1 100644 --- a/src/main/java/org/onap/a1pesimulator/service/fileready/FtpServerService.java +++ b/src/main/java/org/onap/a1pesimulator/service/fileready/FtpServerService.java @@ -13,6 +13,7 @@ import java.util.zip.GZIPOutputStream; import org.onap.a1pesimulator.data.fileready.FileData; import org.onap.a1pesimulator.exception.NotUploadedToFtpException; +import org.onap.a1pesimulator.util.VnfConfigReader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -37,15 +38,9 @@ public class FtpServerService { @Value("${xml.pm.location}") private String xmlPmLocation; - @Value("${ftp.server.url}") - private String ftpServerUrl; - @Value("${ftp.server.protocol}") private String ftpServerProtocol; - @Value("${ftp.server.port}") - private String ftpServerPort; - @Value("${ftp.server.filepath}") private String ftpServerFilepath; @@ -55,6 +50,12 @@ public class FtpServerService { @Value("${ftp.server.password}") private String ftpServerPassword; + private VnfConfigReader vnfConfigReader; + + public FtpServerService(VnfConfigReader vnfConfigReader) { + this.vnfConfigReader = vnfConfigReader; + } + public Mono uploadFileToFtp(FileData fileData) { return Mono.just(fileData) .flatMap(this::tryToCompressFile) @@ -146,7 +147,7 @@ public class FtpServerService { SSHClient client = new SSHClient(); try { client.addHostKeyVerifier(new PromiscuousVerifier()); - client.connect(ftpServerUrl, Integer.parseInt(ftpServerPort)); + client.connect(vnfConfigReader.getVnfConfig().getFtpHost(), Integer.parseInt(vnfConfigReader.getVnfConfig().getFtpPort())); client.authPassword(ftpServerUsername, ftpServerPassword); return client; } catch (IOException e) { @@ -180,7 +181,8 @@ public class FtpServerService { * @return for example: "sftp://foo:pass@106.120.119.170:2222/upload/" */ public String getFtpPath() { - return ftpServerProtocol + "://" + ftpServerUsername + ":" + ftpServerPassword + "@" + ftpServerUrl + ":" + ftpServerPort + "/" + ftpServerFilepath + return ftpServerProtocol + "://" + ftpServerUsername + ":" + ftpServerPassword + "@" + vnfConfigReader.getVnfConfig().getFtpHost() + ":" + + vnfConfigReader.getVnfConfig().getFtpPort() + "/" + ftpServerFilepath + "/"; } diff --git a/src/main/java/org/onap/a1pesimulator/service/ves/RanVesHolder.java b/src/main/java/org/onap/a1pesimulator/service/ves/RanVesHolder.java index 131f792..c647811 100644 --- a/src/main/java/org/onap/a1pesimulator/service/ves/RanVesHolder.java +++ b/src/main/java/org/onap/a1pesimulator/service/ves/RanVesHolder.java @@ -99,8 +99,10 @@ public class RanVesHolder { * Sends the last report after specific cell was stopped */ private void sendLastReport(String cellId) { - log.trace("Send last report after stop for cell: {}", cellId); - ranFileReadyHolder.createPMBulkFileAndSendFileReadyMessageForCellId(cellId); + if (nonNull(threadSendReportFunction)) { + log.trace("Send last report after stop for cell: {}", cellId); + ranFileReadyHolder.createPMBulkFileAndSendFileReadyMessageForCellId(cellId); + } } Map getPeriodicEventsCache() { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 955bc41..581e0cf 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -24,8 +24,6 @@ ves.failing.latency=500 ves.failing.checkout.delay=15 ftp.server.upload=false ftp.server.protocol=sftp -ftp.server.url=localhost -ftp.server.port=22222 ftp.server.filepath=upload ftp.server.username=admin ftp.server.password=samsung diff --git a/src/test/java/org/onap/a1pesimulator/service/fileready/FtpServerServiceTest.java b/src/test/java/org/onap/a1pesimulator/service/fileready/FtpServerServiceTest.java index d984b20..5fc3d84 100644 --- a/src/test/java/org/onap/a1pesimulator/service/fileready/FtpServerServiceTest.java +++ b/src/test/java/org/onap/a1pesimulator/service/fileready/FtpServerServiceTest.java @@ -6,6 +6,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.onap.a1pesimulator.service.fileready.FtpServerService.deletePMBulkFile; @@ -16,10 +17,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.Spy; import org.onap.a1pesimulator.data.fileready.FileData; +import org.onap.a1pesimulator.util.VnfConfigReader; import org.springframework.test.util.ReflectionTestUtils; import ch.qos.logback.classic.spi.ILoggingEvent; @@ -31,8 +34,7 @@ import reactor.test.StepVerifier; class FtpServerServiceTest extends CommonFileReady { - @Spy - FtpServerService ftpServerService; + private FtpServerService ftpServerService; @Mock SSHClient sshClient; @@ -40,6 +42,16 @@ class FtpServerServiceTest extends CommonFileReady { @Mock SFTPClient sftpClient; + @InjectMocks + VnfConfigReader vnfConfigReader; + + @BeforeEach + void setUp() { + super.setUp(); + ReflectionTestUtils.setField(vnfConfigReader, "vnfConfigFile", "src/test/resources/vnf.config"); + ftpServerService = spy(new FtpServerService(vnfConfigReader)); + } + /** * Test to save archived PM Bulk File into specify directory */ @@ -85,7 +97,6 @@ class FtpServerServiceTest extends CommonFileReady { @Test void errorWhileUploadingFileToFtp() { ReflectionTestUtils.setField(ftpServerService, "ftpServerUpload", true); - ReflectionTestUtils.setField(ftpServerService, "ftpServerPort", "22"); FileData testFileData = getTestFileData(); StepVerifier.create(ftpServerService.uploadFileToFtp(testFileData)) .verifyComplete(); @@ -112,8 +123,6 @@ class FtpServerServiceTest extends CommonFileReady { ftpPathVars.add("ftpServerProtocol"); ftpPathVars.add("ftpServerUsername"); ftpPathVars.add("ftpServerPassword"); - ftpPathVars.add("ftpServerUrl"); - ftpPathVars.add("ftpServerPort"); ftpPathVars.add("ftpServerFilepath"); ftpPathVars.forEach(var -> ReflectionTestUtils.setField(ftpServerService, var, var)); diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 56a17cb..ff09a40 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -22,8 +22,6 @@ ves.failing.latency=500 # in sec ves.failing.checkout.delay=15 ftp.server.protocol=sftp -ftp.server.url=localhost -ftp.server.port=22222 ftp.server.filepath=upload ftp.server.username=admin ftp.server.password=samsung diff --git a/src/test/resources/vnf.config b/src/test/resources/vnf.config index dab5ee9..3929ed3 100644 --- a/src/test/resources/vnf.config +++ b/src/test/resources/vnf.config @@ -4,5 +4,7 @@ vesUser=someVesUser vesPassword=someVesPassword vnfId=someVnfId vnfName=someVnfName +ftpHost=localhost +ftpPort=22222 unknownProperty=doNotFail repPeriod=30 \ No newline at end of file -- cgit 1.2.3-korg