summaryrefslogtreecommitdiffstats
path: root/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services
diff options
context:
space:
mode:
authorandre.schmid <andre.schmid@est.tech>2021-12-15 19:44:06 +0000
committerMichael Morris <michael.morris@est.tech>2022-01-21 13:25:16 +0000
commit049d078d8abbe637b213a2f14c2192379208c168 (patch)
tree3fb61e7fe7a95684499329cfa120c82de0c533b5 /openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services
parentb3761a858f0ec676dd0236101b29f8948d5d6a2e (diff)
Onboarding upload control
Brings the initial structure to control asynchronously a VSP package upload during the onboarding. Instead of blocking the UI, the upload and processing status will be controlled by the backend, so the frontend can query it and control the behaviour of the UI. Updates the upload endpoint to obtain/verify an upload lock, and creates a second endpoint to check for the upload status. Change-Id: If1c43fb4f0b11e1d8a5627578bafc75f266393c2 Issue-ID: SDC-3826, SDC-3827 Signed-off-by: andre.schmid <andre.schmid@est.tech>
Diffstat (limited to 'openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services')
-rw-r--r--openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImpl.java144
-rw-r--r--openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateUploadManager.java63
-rw-r--r--openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateUploadManagerImpl.java171
3 files changed, 319 insertions, 59 deletions
diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImpl.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImpl.java
index e8ee6b3c4b..1477ce1414 100644
--- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImpl.java
+++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImpl.java
@@ -22,7 +22,6 @@
package org.openecomp.sdcrests.vsp.rest.services;
import static javax.ws.rs.core.Response.Status.EXPECTATION_FAILED;
-import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
import static javax.ws.rs.core.Response.Status.NOT_ACCEPTABLE;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder.getErrorWithParameters;
@@ -59,6 +58,7 @@ import org.openecomp.sdc.be.csar.storage.ArtifactStorageConfig;
import org.openecomp.sdc.be.csar.storage.ArtifactStorageManager;
import org.openecomp.sdc.be.csar.storage.PackageSizeReducer;
import org.openecomp.sdc.be.csar.storage.StorageFactory;
+import org.openecomp.sdc.be.csar.storage.exception.ArtifactStorageException;
import org.openecomp.sdc.common.util.ValidationUtils;
import org.openecomp.sdc.common.utils.SdcCommon;
import org.openecomp.sdc.datatypes.error.ErrorLevel;
@@ -70,6 +70,7 @@ import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateMan
import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager;
import org.openecomp.sdc.vendorsoftwareproduct.VspManagerFactory;
import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails;
+import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspUploadStatus;
import org.openecomp.sdc.vendorsoftwareproduct.impl.onboarding.OnboardingPackageProcessor;
import org.openecomp.sdc.vendorsoftwareproduct.impl.onboarding.validation.CnfPackageValidator;
import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardPackageInfo;
@@ -82,10 +83,12 @@ import org.openecomp.sdcrests.vendorsoftwareproducts.types.FileDataStructureDto;
import org.openecomp.sdcrests.vendorsoftwareproducts.types.OrchestrationTemplateActionResponseDto;
import org.openecomp.sdcrests.vendorsoftwareproducts.types.UploadFileResponseDto;
import org.openecomp.sdcrests.vendorsoftwareproducts.types.ValidationResponseDto;
+import org.openecomp.sdcrests.vendorsoftwareproducts.types.VspUploadStatusDto;
import org.openecomp.sdcrests.vsp.rest.OrchestrationTemplateCandidate;
import org.openecomp.sdcrests.vsp.rest.mapping.MapFilesDataStructureToDto;
import org.openecomp.sdcrests.vsp.rest.mapping.MapUploadFileResponseToUploadFileResponseDto;
import org.openecomp.sdcrests.vsp.rest.mapping.MapValidationResponseToDto;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@@ -100,8 +103,10 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate
private final ActivityLogManager activityLogManager;
private final ArtifactStorageManager artifactStorageManager;
private final PackageSizeReducer packageSizeReducer;
+ private final OrchestrationTemplateCandidateUploadManager orchestrationTemplateCandidateUploadManager;
- public OrchestrationTemplateCandidateImpl() {
+ @Autowired
+ public OrchestrationTemplateCandidateImpl(final OrchestrationTemplateCandidateUploadManager orchestrationTemplateCandidateUploadManager) {
this.candidateManager = OrchestrationTemplateCandidateManagerFactory.getInstance().createInterface();
this.vendorSoftwareProductManager = VspManagerFactory.getInstance().createInterface();
this.activityLogManager = ActivityLogManagerFactory.getInstance().createInterface();
@@ -110,6 +115,7 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate
this.artifactStorageManager = storageFactory.createArtifactStorageManager();
LOGGER.info("Instantiating packageSizeReducer");
this.packageSizeReducer = storageFactory.createPackageSizeReducer().orElse(null);
+ this.orchestrationTemplateCandidateUploadManager = orchestrationTemplateCandidateUploadManager;
}
// Constructor used in test to avoid mock static
@@ -117,81 +123,101 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate
final VendorSoftwareProductManager vendorSoftwareProductManager,
final ActivityLogManager activityLogManager,
final ArtifactStorageManager artifactStorageManager,
- final PackageSizeReducer packageSizeReducer) {
+ final PackageSizeReducer packageSizeReducer,
+ final OrchestrationTemplateCandidateUploadManager orchestrationTemplateCandidateUploadManager) {
this.candidateManager = candidateManager;
this.vendorSoftwareProductManager = vendorSoftwareProductManager;
this.activityLogManager = activityLogManager;
this.artifactStorageManager = artifactStorageManager;
this.packageSizeReducer = packageSizeReducer;
+ this.orchestrationTemplateCandidateUploadManager = orchestrationTemplateCandidateUploadManager;
}
@Override
public Response upload(String vspId, String versionId, final Attachment fileToUpload, final String user) {
vspId = ValidationUtils.sanitizeInputString(vspId);
versionId = ValidationUtils.sanitizeInputString(versionId);
- final byte[] fileToUploadBytes;
- final DataHandler dataHandler = fileToUpload.getDataHandler();
- final var filename = ValidationUtils.sanitizeInputString(dataHandler.getName());
- ArtifactInfo artifactInfo = null;
- if (artifactStorageManager.isEnabled()) {
- final Path tempArtifactPath;
- try {
- final ArtifactStorageConfig storageConfiguration = artifactStorageManager.getStorageConfiguration();
+ final Response response;
+ VspUploadStatusDto vspUploadStatus = null;
+ try {
+ vspUploadStatus = orchestrationTemplateCandidateUploadManager.putUploadInProgress(vspId, versionId, user);
+ final byte[] fileToUploadBytes;
+ final DataHandler dataHandler = fileToUpload.getDataHandler();
+ final var filename = ValidationUtils.sanitizeInputString(dataHandler.getName());
+ ArtifactInfo artifactInfo = null;
+ if (artifactStorageManager.isEnabled()) {
+ artifactInfo = handleArtifactStorage(vspId, versionId, filename, dataHandler);
+ fileToUploadBytes = artifactInfo.getBytes();
+ } else {
+ fileToUploadBytes = fileToUpload.getObject(byte[].class);
+ }
- final Path folder = Path.of(storageConfiguration.getTempPath()).resolve(vspId).resolve(versionId);
- tempArtifactPath = folder.resolve(UUID.randomUUID().toString());
- Files.createDirectories(folder);
- try (final InputStream packageInputStream = dataHandler.getInputStream();
- final var fileOutputStream = new FileOutputStream(tempArtifactPath.toFile())) {
- packageInputStream.transferTo(fileOutputStream);
- }
- } catch (final Exception e) {
- return Response.status(INTERNAL_SERVER_ERROR).entity(buildUploadResponseWithError(
- new ErrorMessage(ErrorLevel.ERROR, UNEXPECTED_PROBLEM_HAPPENED_WHILE_GETTING.formatMessage(filename)))).build();
+ final var onboardingPackageProcessor =
+ new OnboardingPackageProcessor(filename, fileToUploadBytes, new CnfPackageValidator(), artifactInfo);
+ final ErrorMessage[] errorMessages = onboardingPackageProcessor.getErrorMessages().toArray(new ErrorMessage[0]);
+ if (onboardingPackageProcessor.hasErrors()) {
+ return Response.status(NOT_ACCEPTABLE).entity(buildUploadResponseWithError(errorMessages)).build();
}
- try (final InputStream inputStream = Files.newInputStream(tempArtifactPath)) {
- artifactInfo = artifactStorageManager.upload(vspId, versionId, inputStream);
- } catch (final Exception e) {
- LOGGER.error("Package Size Reducer not configured", e);
- return Response.status(INTERNAL_SERVER_ERROR).entity(buildUploadResponseWithError(
- new ErrorMessage(ErrorLevel.ERROR, ERROR_HAS_OCCURRED_WHILE_PERSISTING_THE_ARTIFACT.formatMessage(filename)))).build();
+ final var onboardPackageInfo = onboardingPackageProcessor.getOnboardPackageInfo().orElse(null);
+ if (onboardPackageInfo == null) {
+ final UploadFileResponseDto uploadFileResponseDto = buildUploadResponseWithError(
+ new ErrorMessage(ErrorLevel.ERROR, PACKAGE_PROCESS_ERROR.formatMessage(filename)));
+ return Response.ok(uploadFileResponseDto).build();
}
- try {
- fileToUploadBytes = packageSizeReducer.reduce(tempArtifactPath);
- Files.delete(tempArtifactPath);
- } catch (final Exception e) {
- LOGGER.error("Package Size Reducer not configured", e);
- return Response.status(INTERNAL_SERVER_ERROR).entity(buildUploadResponseWithError(
- new ErrorMessage(ErrorLevel.ERROR,
- ERROR_HAS_OCCURRED_WHILE_REDUCING_THE_ARTIFACT_SIZE.formatMessage(tempArtifactPath.toString())))).build();
+ final var version = new Version(versionId);
+ final var vspDetails = vendorSoftwareProductManager.getVsp(vspId, version);
+ response = processOnboardPackage(onboardPackageInfo, vspDetails, errorMessages);
+ final UploadFileResponseDto entity = (UploadFileResponseDto) response.getEntity();
+ if (artifactStorageManager.isEnabled()) {
+ if (!entity.getErrors().isEmpty()) {
+ artifactStorageManager.delete(artifactInfo);
+ } else {
+ artifactStorageManager.put(vspId, versionId + ".reduced", new ByteArrayInputStream(fileToUploadBytes));
+ }
}
- } else {
- fileToUploadBytes = fileToUpload.getObject(byte[].class);
+ orchestrationTemplateCandidateUploadManager
+ .putUploadAsFinished(vspId, versionId, vspUploadStatus.getLockId(), VspUploadStatus.SUCCESS, user);
+ } catch (final Exception ex) {
+ if (vspUploadStatus != null) {
+ orchestrationTemplateCandidateUploadManager
+ .putUploadAsFinished(vspId, versionId, vspUploadStatus.getLockId(), VspUploadStatus.ERROR, user);
+ }
+ throw ex;
}
+ return response;
+ }
+
+ private ArtifactInfo handleArtifactStorage(final String vspId, final String versionId, final String filename,
+ final DataHandler artifactDataHandler) {
+ final Path tempArtifactPath;
+ try {
+ final ArtifactStorageConfig storageConfiguration = artifactStorageManager.getStorageConfiguration();
- final var onboardingPackageProcessor = new OnboardingPackageProcessor(filename, fileToUploadBytes, new CnfPackageValidator(), artifactInfo);
- final ErrorMessage[] errorMessages = onboardingPackageProcessor.getErrorMessages().toArray(new ErrorMessage[0]);
- if (onboardingPackageProcessor.hasErrors()) {
- return Response.status(NOT_ACCEPTABLE).entity(buildUploadResponseWithError(errorMessages)).build();
+ final Path folder = Path.of(storageConfiguration.getTempPath()).resolve(vspId).resolve(versionId);
+ tempArtifactPath = folder.resolve(UUID.randomUUID().toString());
+ Files.createDirectories(folder);
+ try (final InputStream packageInputStream = artifactDataHandler.getInputStream();
+ final var fileOutputStream = new FileOutputStream(tempArtifactPath.toFile())) {
+ packageInputStream.transferTo(fileOutputStream);
+ }
+ } catch (final Exception e) {
+ throw new ArtifactStorageException(UNEXPECTED_PROBLEM_HAPPENED_WHILE_GETTING.formatMessage(filename));
}
- final var onboardPackageInfo = onboardingPackageProcessor.getOnboardPackageInfo().orElse(null);
- if (onboardPackageInfo == null) {
- final UploadFileResponseDto uploadFileResponseDto = buildUploadResponseWithError(
- new ErrorMessage(ErrorLevel.ERROR, PACKAGE_PROCESS_ERROR.formatMessage(filename)));
- return Response.ok(uploadFileResponseDto).build();
+ final ArtifactInfo artifactInfo;
+ try (final InputStream inputStream = Files.newInputStream(tempArtifactPath)) {
+ artifactInfo = artifactStorageManager.upload(vspId, versionId, inputStream);
+ } catch (final Exception e) {
+ LOGGER.error("Package Size Reducer not configured", e);
+ throw new ArtifactStorageException(ERROR_HAS_OCCURRED_WHILE_PERSISTING_THE_ARTIFACT.formatMessage(filename));
}
- final var version = new Version(versionId);
- final var vspDetails = vendorSoftwareProductManager.getVsp(vspId, version);
- final Response response = processOnboardPackage(onboardPackageInfo, vspDetails, errorMessages);
- final UploadFileResponseDto entity = (UploadFileResponseDto) response.getEntity();
- if (artifactStorageManager.isEnabled()) {
- if (!entity.getErrors().isEmpty()) {
- artifactStorageManager.delete(artifactInfo);
- } else {
- artifactStorageManager.put(vspId, versionId + ".reduced", new ByteArrayInputStream(fileToUploadBytes));
- }
+ try {
+ artifactInfo.setBytes(packageSizeReducer.reduce(tempArtifactPath));
+ Files.delete(tempArtifactPath);
+ } catch (final Exception e) {
+ LOGGER.error("Package Size Reducer not configured", e);
+ throw new ArtifactStorageException(ERROR_HAS_OCCURRED_WHILE_REDUCING_THE_ARTIFACT_SIZE.formatMessage(filename));
}
- return response;
+ return artifactInfo;
}
private Response processOnboardPackage(final OnboardPackageInfo onboardPackageInfo, final VspDetails vspDetails,
@@ -227,7 +253,7 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate
fileName = "Candidate." + zipFile.get().getLeft();
} else {
zipFile = vendorSoftwareProductManager.get(vspId, new Version((versionId)));
- if (!zipFile.isPresent()) {
+ if (zipFile.isEmpty()) {
ErrorMessage errorMessage = new ErrorMessage(ErrorLevel.ERROR,
getErrorWithParameters(NO_FILE_WAS_UPLOADED_OR_FILE_NOT_EXIST.getErrorMessage(), ""));
LOGGER.error(errorMessage.getMessage());
@@ -270,7 +296,7 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate
@Override
public Response getFilesDataStructure(String vspId, String versionId, String user) {
Optional<FilesDataStructure> filesDataStructure = candidateManager.getFilesDataStructure(vspId, new Version(versionId));
- if (!filesDataStructure.isPresent()) {
+ if (filesDataStructure.isEmpty()) {
filesDataStructure = vendorSoftwareProductManager.getOrchestrationTemplateStructure(vspId, new Version(versionId));
}
FileDataStructureDto fileDataStructureDto = filesDataStructure
diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateUploadManager.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateUploadManager.java
new file mode 100644
index 0000000000..0f33580099
--- /dev/null
+++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateUploadManager.java
@@ -0,0 +1,63 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdcrests.vsp.rest.services;
+
+import java.util.Optional;
+import java.util.UUID;
+import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspUploadStatus;
+import org.openecomp.sdcrests.vendorsoftwareproducts.types.VspUploadStatusDto;
+
+public interface OrchestrationTemplateCandidateUploadManager {
+
+ /**
+ * Creates a lock to start uploading a package.
+ *
+ * @param vspId the Vendor Software Product id
+ * @param vspVersionId the Vendor Software Product version id
+ * @param user the current user
+ * @return a new upload status containing the lock
+ */
+ VspUploadStatusDto putUploadInProgress(String vspId, String vspVersionId, String user);
+
+ /**
+ * Finishes the upload process, applying the given VspUploadStatusType completion status.
+ *
+ * @param vspId the Vendor Software Product id
+ * @param vspVersionId the Vendor Software Product version id
+ * @param lockId the upload lock id
+ * @param completionStatus any status that represents a completion
+ * @param user the current user
+ * @return the updated status
+ */
+ VspUploadStatusDto putUploadAsFinished(final String vspId, final String vspVersionId, final UUID lockId, final VspUploadStatus completionStatus,
+ final String user);
+
+ /**
+ * Finds the latest upload status for a given Vendor Software Product version.
+ *
+ * @param vspId the Vendor Software Product id
+ * @param vspVersionId the Vendor Software Product version id
+ * @param user the current user
+ * @return the latest upload status for the requested Vendor Software Product version
+ */
+ Optional<VspUploadStatusDto> findLatestStatus(String vspId, String vspVersionId, String user);
+}
diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateUploadManagerImpl.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateUploadManagerImpl.java
new file mode 100644
index 0000000000..d7cfe041c2
--- /dev/null
+++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateUploadManagerImpl.java
@@ -0,0 +1,171 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdcrests.vsp.rest.services;
+
+import static org.openecomp.sdcrests.vsp.rest.exception.OrchestrationTemplateCandidateUploadManagerExceptionSupplier.couldNotCreateLock;
+import static org.openecomp.sdcrests.vsp.rest.exception.OrchestrationTemplateCandidateUploadManagerExceptionSupplier.couldNotFindLock;
+import static org.openecomp.sdcrests.vsp.rest.exception.OrchestrationTemplateCandidateUploadManagerExceptionSupplier.couldNotUpdateLock;
+import static org.openecomp.sdcrests.vsp.rest.exception.OrchestrationTemplateCandidateUploadManagerExceptionSupplier.uploadAlreadyFinished;
+import static org.openecomp.sdcrests.vsp.rest.exception.OrchestrationTemplateCandidateUploadManagerExceptionSupplier.vspUploadAlreadyInProgress;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.openecomp.sdc.common.errors.CoreException;
+import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager;
+import org.openecomp.sdc.vendorsoftwareproduct.VspManagerFactory;
+import org.openecomp.sdc.vendorsoftwareproduct.dao.VspUploadStatusRecordDao;
+import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails;
+import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspUploadStatus;
+import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspUploadStatusRecord;
+import org.openecomp.sdc.versioning.dao.types.Version;
+import org.openecomp.sdcrests.vendorsoftwareproducts.types.VspUploadStatusDto;
+import org.openecomp.sdcrests.vsp.rest.exception.OrchestrationTemplateCandidateUploadManagerExceptionSupplier;
+import org.openecomp.sdcrests.vsp.rest.mapping.VspUploadStatusRecordMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+/**
+ * Manages the package upload process status.
+ */
+@Service
+public class OrchestrationTemplateCandidateUploadManagerImpl implements OrchestrationTemplateCandidateUploadManager {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(OrchestrationTemplateCandidateUploadManagerImpl.class);
+
+ private final VspUploadStatusRecordDao uploadManagerDao;
+ private final VspUploadStatusRecordMapper vspUploadStatusRecordMapper;
+ private final VendorSoftwareProductManager vendorSoftwareProductManager;
+ private final Lock startUploadLock;
+
+ @Autowired
+ public OrchestrationTemplateCandidateUploadManagerImpl(
+ @Qualifier("vsp-upload-status-record-dao-impl") final VspUploadStatusRecordDao uploadManagerDao) {
+
+ this.uploadManagerDao = uploadManagerDao;
+ this.vendorSoftwareProductManager = VspManagerFactory.getInstance().createInterface();
+ this.vspUploadStatusRecordMapper = new VspUploadStatusRecordMapper();
+ startUploadLock = new ReentrantLock();
+ }
+
+ //for tests purpose
+ OrchestrationTemplateCandidateUploadManagerImpl(final VspUploadStatusRecordDao uploadManagerDao,
+ final VendorSoftwareProductManager vendorSoftwareProductManager) {
+ this.uploadManagerDao = uploadManagerDao;
+ this.vendorSoftwareProductManager = vendorSoftwareProductManager;
+ this.vspUploadStatusRecordMapper = new VspUploadStatusRecordMapper();
+ startUploadLock = new ReentrantLock();
+ }
+
+ @Override
+ public VspUploadStatusDto putUploadInProgress(final String vspId, final String vspVersionId, final String user) {
+ checkVspExists(vspId, vspVersionId);
+ LOGGER.debug("Start uploading for VSP id '{}', version '{}', triggered by user '{}'", vspId, vspVersionId, user);
+
+ final VspUploadStatusRecord vspUploadStatusRecord;
+ startUploadLock.lock();
+ try {
+ final List<VspUploadStatusRecord> uploadInProgressList = uploadManagerDao.findAllInProgress(vspId, vspVersionId);
+ if (!uploadInProgressList.isEmpty()) {
+ throw vspUploadAlreadyInProgress(vspId, vspVersionId).get();
+ }
+
+ vspUploadStatusRecord = new VspUploadStatusRecord();
+ vspUploadStatusRecord.setStatus(VspUploadStatus.UPLOADING);
+ vspUploadStatusRecord.setVspId(vspId);
+ vspUploadStatusRecord.setVspVersionId(vspVersionId);
+ vspUploadStatusRecord.setLockId(UUID.randomUUID());
+ vspUploadStatusRecord.setCreated(new Date());
+
+ uploadManagerDao.create(vspUploadStatusRecord);
+ LOGGER.debug("Upload lock '{}' created for VSP id '{}', version '{}'", vspUploadStatusRecord.getLockId(), vspId, vspVersionId);
+ } catch (final CoreException e) {
+ throw e;
+ } catch (final Exception e) {
+ throw couldNotCreateLock(vspId, vspVersionId, e).get();
+ } finally {
+ startUploadLock.unlock();
+ }
+
+ return vspUploadStatusRecordMapper.applyMapping(vspUploadStatusRecord, VspUploadStatusDto.class);
+ }
+
+ @Override
+ public VspUploadStatusDto putUploadAsFinished(final String vspId, final String vspVersionId, final UUID lockId, final VspUploadStatus completionStatus,
+ final String user) {
+
+ if (!completionStatus.isCompleteStatus()) {
+ throw OrchestrationTemplateCandidateUploadManagerExceptionSupplier.invalidCompleteStatus(completionStatus).get();
+ }
+ final Optional<VspUploadStatusRecord> vspUploadStatusOptional =
+ uploadManagerDao.findByVspIdAndVersionIdAndLockId(vspId, vspVersionId, lockId);
+ if (vspUploadStatusOptional.isEmpty()) {
+ throw couldNotFindLock(lockId, vspId, vspVersionId).get();
+ }
+ final VspUploadStatusRecord vspUploadStatusRecord = vspUploadStatusOptional.get();
+ if (vspUploadStatusRecord.getIsComplete()) {
+ throw uploadAlreadyFinished(lockId, vspId, vspVersionId).get();
+ }
+ LOGGER.debug("Finishing the upload for VSP id '{}', version '{}', lock '{}', triggered by user '{}'",
+ vspUploadStatusRecord.getVspId(), vspUploadStatusRecord.getVspVersionId(), vspUploadStatusRecord.getLockId(), user);
+ vspUploadStatusRecord.setStatus(completionStatus);
+ vspUploadStatusRecord.setUpdated(new Date());
+ vspUploadStatusRecord.setIsComplete(true);
+
+ try {
+ uploadManagerDao.update(vspUploadStatusRecord);
+ LOGGER.debug("Upload complete for VSP '{}', version '{}', lock '{}'",
+ vspUploadStatusRecord.getLockId(), vspUploadStatusRecord.getVspId(), vspUploadStatusRecord.getVspVersionId());
+ } catch (final Exception e) {
+ throw couldNotUpdateLock(vspUploadStatusRecord.getLockId(), vspUploadStatusRecord.getVspId(), vspUploadStatusRecord.getVspVersionId(), e)
+ .get();
+ }
+
+ return vspUploadStatusRecordMapper.applyMapping(vspUploadStatusRecord, VspUploadStatusDto.class);
+ }
+
+ private void checkVspExists(final String vspId, final String vspVersionId) {
+ final VspDetails vspDetails = vendorSoftwareProductManager.getVsp(vspId, new Version(vspVersionId));
+ if (vspDetails == null) {
+ throw OrchestrationTemplateCandidateUploadManagerExceptionSupplier.vspNotFound(vspId, vspVersionId).get();
+ }
+ }
+
+ @Override
+ public Optional<VspUploadStatusDto> findLatestStatus(final String vspId, final String vspVersionId, final String user) {
+ checkVspExists(vspId, vspVersionId);
+
+ final Optional<VspUploadStatusRecord> vspUploadStatus = uploadManagerDao.findLatest(vspId, vspVersionId);
+ if (vspUploadStatus.isEmpty()) {
+ return Optional.empty();
+ }
+
+ return Optional.of(vspUploadStatusRecordMapper.applyMapping(vspUploadStatus.get(), VspUploadStatusDto.class));
+ }
+
+}