summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvasraz <vasyl.razinkov@est.tech>2021-07-08 18:54:19 +0100
committerMichael Morris <michael.morris@est.tech>2021-07-21 14:01:01 +0000
commit8278b79c92f5149813f0161670a0eb76c33db322 (patch)
treec70bc2078111faa5cc5e29c071598ed1e11a5898
parent5cb26d5eb1ab5d04319624f1ffb49f7f26d55315 (diff)
Support handling of 'Large CSARs'
If artifact storage is enabled, stores original onboarded package, leaving a reference in the VSP, instead of the original onboarded package itself. Strips files from configured folders in order to reduce the package size and onboard it. To retrieve the package, one needs to read the reference and go to the artifact storage to retrieve. If disabled, it just goes through the current onboarding process. Change-Id: I3dce0ab8422ea736c8a1ffaeb1136cf8b12a2af4 Signed-off-by: Vasyl Razinkov <vasyl.razinkov@est.tech> Signed-off-by: André Schmid <andre.schmid@est.tech> Issue-ID: SDC-3635
-rw-r--r--common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/ArtifactInfo.java32
-rw-r--r--common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/ArtifactStorageConfig.java28
-rw-r--r--common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/ArtifactStorageManager.java57
-rw-r--r--common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/PackageSizeReducer.java32
-rw-r--r--common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/PackageSizeReducerConfig.java28
-rw-r--r--common-be/pom.xml11
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/csar/storage/CsarPackageReducerConfiguration.java33
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/csar/storage/CsarSizeReducer.java109
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/csar/storage/PersistentStorageArtifactInfo.java33
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/csar/storage/PersistentVolumeArtifactStorageConfig.java32
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/csar/storage/PersistentVolumeArtifactStorageManager.java161
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/csar/storage/exception/CsarSizeReducerException.java30
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/csar/storage/exception/PersistentVolumeArtifactStorageException.java34
-rw-r--r--common-be/src/test/java/org/openecomp/sdc/be/csar/storage/CsarSizeReducerTest.java87
-rw-r--r--common-be/src/test/java/org/openecomp/sdc/be/csar/storage/PersistentVolumeArtifactStorageManagerTest.java118
-rw-r--r--common-be/src/test/resources/csarSizeReducer/dummy.csarbin0 -> 25876 bytes
-rw-r--r--common-be/src/test/resources/persistentVolumeArtifactStorageManager/dummy.csarbin0 -> 25876 bytes
-rw-r--r--onboarding/pom.xml1
-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/OrchestrationTemplateCandidateException.java6
-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.java119
-rw-r--r--openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImplTest.java173
-rw-r--r--openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessor.java8
-rw-r--r--openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateCSARHandler.java9
-rw-r--r--openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateZipHandler.java3
-rw-r--r--openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/types/OnboardPackageInfo.java4
-rw-r--r--openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessorTest.java2
-rw-r--r--openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessorUnitTest.java3
-rw-r--r--openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/CsarSecurityValidatorTest.java2
-rw-r--r--openecomp-be/dist/sdc-onboard-backend-docker/artifacts/chef-repo/cookbooks/sdc-onboard-backend/templates/default/configuration.yaml.erb9
-rw-r--r--openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java7
-rw-r--r--openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/type/OrchestrationTemplateCandidateData.java11
-rw-r--r--openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/impl/zusammen/OrchestrationTemplateCandidateDaoZusammenException.java28
-rw-r--r--openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/impl/zusammen/OrchestrationTemplateCandidateDaoZusammenImpl.java68
-rw-r--r--pom.xml1
34 files changed, 1141 insertions, 138 deletions
diff --git a/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/ArtifactInfo.java b/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/ArtifactInfo.java
new file mode 100644
index 0000000000..75847704c8
--- /dev/null
+++ b/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/ArtifactInfo.java
@@ -0,0 +1,32 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage;
+
+import java.nio.file.Path;
+
+/**
+ * Represents the stored artifact
+ */
+public interface ArtifactInfo {
+
+ Path getPath();
+
+}
diff --git a/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/ArtifactStorageConfig.java b/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/ArtifactStorageConfig.java
new file mode 100644
index 0000000000..edac694933
--- /dev/null
+++ b/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/ArtifactStorageConfig.java
@@ -0,0 +1,28 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage;
+
+/**
+ * Configurations for the {@link ArtifactStorageManager}
+ */
+public interface ArtifactStorageConfig {
+
+}
diff --git a/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/ArtifactStorageManager.java b/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/ArtifactStorageManager.java
new file mode 100644
index 0000000000..da06db0e68
--- /dev/null
+++ b/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/ArtifactStorageManager.java
@@ -0,0 +1,57 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage;
+
+import java.io.InputStream;
+
+/**
+ * Manages the artifact storage and handles operations on the artifacts
+ */
+public interface ArtifactStorageManager {
+
+ /**
+ * Persists the uploaded artifact in the storage.
+ *
+ * @param vspId the VSP id
+ * @param versionId the VSP version id
+ * @param uploadedArtifactInfo the uploaded
+ * @return the information about the persisted artifact
+ */
+ ArtifactInfo persist(String vspId, String versionId, ArtifactInfo uploadedArtifactInfo);
+
+ /**
+ * Uploads a file to the Artifact Storage. This file will be temporary until persisted by {@link #persist(String, String, ArtifactInfo)}.
+ *
+ * @param vspId the VSP id
+ * @param versionId the VSP version id
+ * @param fileToUpload the file input stream
+ * @return the information about the uploaded artifact
+ */
+ ArtifactInfo upload(String vspId, String versionId, InputStream fileToUpload);
+
+ /**
+ * Checks if the Artifact Storage is enabled.
+ *
+ * @return {@code true} if enable, {@code false} otherwise
+ */
+ boolean isEnabled();
+
+}
diff --git a/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/PackageSizeReducer.java b/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/PackageSizeReducer.java
new file mode 100644
index 0000000000..290ca08d00
--- /dev/null
+++ b/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/PackageSizeReducer.java
@@ -0,0 +1,32 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage;
+
+import java.nio.file.Path;
+
+/**
+ * Handles operations to reduce the package size
+ */
+public interface PackageSizeReducer {
+
+ byte[] reduce(Path path);
+
+}
diff --git a/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/PackageSizeReducerConfig.java b/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/PackageSizeReducerConfig.java
new file mode 100644
index 0000000000..b45396fb72
--- /dev/null
+++ b/common-app-api/src/main/java/org/openecomp/sdc/be/csar/storage/PackageSizeReducerConfig.java
@@ -0,0 +1,28 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage;
+
+/**
+ * Configuration for the {@link PackageSizeReducer}
+ */
+public interface PackageSizeReducerConfig {
+
+}
diff --git a/common-be/pom.xml b/common-be/pom.xml
index 2f5464a956..452ff4b9a0 100644
--- a/common-be/pom.xml
+++ b/common-be/pom.xml
@@ -161,6 +161,17 @@
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+ <version>${cxf.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.jboss.spec.javax.rmi</groupId>
+ <artifactId>jboss-rmi-api_1.0_spec</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
</dependencies>
<build>
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/CsarPackageReducerConfiguration.java b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/CsarPackageReducerConfiguration.java
new file mode 100644
index 0000000000..a14222ab17
--- /dev/null
+++ b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/CsarPackageReducerConfiguration.java
@@ -0,0 +1,33 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage;
+
+import java.nio.file.Path;
+import java.util.Set;
+import lombok.Data;
+
+@Data
+public class CsarPackageReducerConfiguration implements PackageSizeReducerConfig {
+
+ private final Set<Path> foldersToStrip;
+ private final long sizeLimit;
+
+}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/CsarSizeReducer.java b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/CsarSizeReducer.java
new file mode 100644
index 0000000000..cf35c8c4d7
--- /dev/null
+++ b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/CsarSizeReducer.java
@@ -0,0 +1,109 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.UUID;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+import org.openecomp.sdc.be.csar.storage.exception.CsarSizeReducerException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CsarSizeReducer implements PackageSizeReducer {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CsarSizeReducer.class);
+
+ private final CsarPackageReducerConfiguration configuration;
+
+ public CsarSizeReducer(final CsarPackageReducerConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ @Override
+ public byte[] reduce(final Path csarPackagePath) {
+ final var reducedCsarPath = Path.of(csarPackagePath + "." + UUID.randomUUID());
+
+ try (final var zf = new ZipFile(csarPackagePath.toString());
+ final var zos = new ZipOutputStream(new BufferedOutputStream(Files.newOutputStream(reducedCsarPath)))) {
+
+ zf.entries().asIterator().forEachRemaining(entry -> {
+ final var entryName = entry.getName();
+ try {
+ if (!entry.isDirectory()) {
+ zos.putNextEntry(new ZipEntry(entryName));
+ if (isCandidateToRemove(entry)) {
+ // replace with EMPTY string to avoid package description inconsistency/validation errors
+ zos.write("".getBytes());
+ } else {
+ zos.write(zf.getInputStream(entry).readAllBytes());
+ }
+ }
+ zos.closeEntry();
+ } catch (final IOException ei) {
+ final var errorMsg = String.format("Failed to extract '%s' from zip '%s'", entryName, csarPackagePath);
+ throw new CsarSizeReducerException(errorMsg, ei);
+ }
+ });
+
+ } catch (final IOException ex1) {
+ rollback(reducedCsarPath);
+ final var errorMsg = String.format("An unexpected problem happened while reading the CSAR '%s'", csarPackagePath);
+ throw new CsarSizeReducerException(errorMsg, ex1);
+ }
+ final byte[] reducedCsarBytes;
+ try {
+ reducedCsarBytes = Files.readAllBytes(reducedCsarPath);
+ } catch (final IOException e) {
+ final var errorMsg = String.format("Could not read bytes of file '%s'", csarPackagePath);
+ throw new CsarSizeReducerException(errorMsg, e);
+ }
+ try {
+ Files.delete(reducedCsarPath);
+ } catch (final IOException e) {
+ final var errorMsg = String.format("Could not delete temporary file '%s'", reducedCsarPath);
+ throw new CsarSizeReducerException(errorMsg, e);
+ }
+
+ return reducedCsarBytes;
+ }
+
+ private void rollback(final Path reducedCsarPath) {
+ if (Files.exists(reducedCsarPath)) {
+ try {
+ Files.delete(reducedCsarPath);
+ } catch (final Exception ex2) {
+ LOGGER.warn("Could not delete temporary file '{}'", reducedCsarPath, ex2);
+ }
+ }
+ }
+
+ private boolean isCandidateToRemove(final ZipEntry zipEntry) {
+ final String zipEntryName = zipEntry.getName();
+ return configuration.getFoldersToStrip().stream().anyMatch(Path.of(zipEntryName)::startsWith)
+ || zipEntry.getSize() > configuration.getSizeLimit();
+ }
+
+}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/PersistentStorageArtifactInfo.java b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/PersistentStorageArtifactInfo.java
new file mode 100644
index 0000000000..0472661fd9
--- /dev/null
+++ b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/PersistentStorageArtifactInfo.java
@@ -0,0 +1,33 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage;
+
+import java.nio.file.Path;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+public class PersistentStorageArtifactInfo implements ArtifactInfo {
+
+ @Getter
+ private final Path path;
+
+}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/PersistentVolumeArtifactStorageConfig.java b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/PersistentVolumeArtifactStorageConfig.java
new file mode 100644
index 0000000000..d3cd6fb302
--- /dev/null
+++ b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/PersistentVolumeArtifactStorageConfig.java
@@ -0,0 +1,32 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage;
+
+import java.nio.file.Path;
+import lombok.Data;
+
+@Data
+public class PersistentVolumeArtifactStorageConfig implements ArtifactStorageConfig {
+
+ private final boolean isEnabled;
+ private final Path storagePath;
+
+}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/PersistentVolumeArtifactStorageManager.java b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/PersistentVolumeArtifactStorageManager.java
new file mode 100644
index 0000000000..10629b3edb
--- /dev/null
+++ b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/PersistentVolumeArtifactStorageManager.java
@@ -0,0 +1,161 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.Optional;
+import java.util.UUID;
+import org.openecomp.sdc.be.csar.storage.exception.PersistentVolumeArtifactStorageException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PersistentVolumeArtifactStorageManager implements ArtifactStorageManager {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(PersistentVolumeArtifactStorageManager.class);
+
+ private final PersistentVolumeArtifactStorageConfig storageConfiguration;
+
+ public PersistentVolumeArtifactStorageManager(final ArtifactStorageConfig storageConfiguration) {
+ this.storageConfiguration = (PersistentVolumeArtifactStorageConfig) storageConfiguration;
+ }
+
+ @Override
+ public ArtifactInfo persist(final String vspId, final String versionId, final ArtifactInfo uploadedArtifactInfo) {
+ final var temporaryPath = uploadedArtifactInfo.getPath();
+ if (!Files.exists(temporaryPath)) {
+ throw new PersistentVolumeArtifactStorageException(String.format("Given artifact does not exist '%s'", uploadedArtifactInfo.getPath()));
+ }
+
+ final var filePath = buildFilePath(vspId, versionId);
+ final var backupPath = backupPreviousVersion(filePath).orElse(null);
+ try {
+ moveFile(temporaryPath, filePath);
+ } catch (final Exception e) {
+ rollback(backupPath, filePath);
+ final var errorMsg = String.format("Could not persist artifact for VSP '%s', version '%s'", vspId, versionId);
+ throw new PersistentVolumeArtifactStorageException(errorMsg, e);
+ }
+
+ removePreviousVersion(backupPath);
+
+ return new PersistentStorageArtifactInfo(filePath);
+ }
+
+ @Override
+ public ArtifactInfo upload(final String vspId, final String versionId, final InputStream artifactInputStream) {
+ final var destinationFolder = buildDestinationFolder(vspId, versionId);
+ try {
+ Files.createDirectories(destinationFolder);
+ } catch (final IOException e) {
+ throw new PersistentVolumeArtifactStorageException(String.format("Could not create directory '%s'", destinationFolder), e);
+ }
+
+ final var filePath = createTempFilePath(destinationFolder);
+ try {
+ persist(artifactInputStream, filePath);
+ } catch (final IOException e) {
+ throw new PersistentVolumeArtifactStorageException(String.format("Could not persist artifact '%s'", filePath), e);
+ }
+
+ return new PersistentStorageArtifactInfo(filePath);
+ }
+
+ private Path buildFilePath(final String vspId, final String versionId) {
+ return buildDestinationFolder(vspId, versionId).resolve(versionId);
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return storageConfiguration != null && storageConfiguration.isEnabled();
+ }
+
+ private Optional<Path> backupPreviousVersion(final Path filePath) {
+ if (!Files.exists(filePath)) {
+ return Optional.empty();
+ }
+
+ final var backupPath = Path.of(filePath + UUID.randomUUID().toString());
+ moveFile(filePath, backupPath);
+ return Optional.ofNullable(backupPath);
+ }
+
+ private void rollback(final Path backupPath, final Path filePath) {
+ try {
+ moveFile(backupPath, filePath);
+ } catch (final Exception ex) {
+ LOGGER.warn("Could not rollback the backup file '{}' to the original '{}'", backupPath, filePath, ex);
+ }
+ }
+
+ private void removePreviousVersion(final Path filePath) {
+ if (filePath == null || !Files.exists(filePath)) {
+ return;
+ }
+
+ try {
+ Files.delete(filePath);
+ } catch (final IOException e) {
+ throw new PersistentVolumeArtifactStorageException(String.format("Could not delete previous version '%s'", filePath), e);
+ }
+ }
+
+ private Path createTempFilePath(final Path destinationFolder) {
+ final var retries = 10;
+ return createTempFilePath(destinationFolder, retries).orElseThrow(() -> {
+ throw new PersistentVolumeArtifactStorageException(String.format("Could not generate upload file path after '%s' retries", retries));
+ });
+ }
+
+ private Optional<Path> createTempFilePath(final Path destinationFolder, int retries) {
+ for (var i = 0; i < retries; i++) {
+ final var filePath = destinationFolder.resolve(UUID.randomUUID().toString());
+ if (Files.notExists(filePath)) {
+ return Optional.of(filePath);
+ }
+ }
+ return Optional.empty();
+ }
+
+ private Path buildDestinationFolder(final String vspId, final String versionId) {
+ return storageConfiguration.getStoragePath().resolve(vspId).resolve(versionId);
+ }
+
+ private void persist(final InputStream artifactInputStream, final Path filePath) throws IOException {
+ try (final var inputStream = artifactInputStream;
+ final var fileOutputStream = new FileOutputStream(filePath.toFile());) {
+ inputStream.transferTo(fileOutputStream);
+ }
+ }
+
+ private void moveFile(final Path from, final Path to) {
+ try {
+ Files.move(from, to, StandardCopyOption.REPLACE_EXISTING);
+ } catch (final IOException e) {
+ throw new PersistentVolumeArtifactStorageException(String.format("Could not move file '%s' to '%s'", from, to), e);
+ }
+ }
+
+}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/exception/CsarSizeReducerException.java b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/exception/CsarSizeReducerException.java
new file mode 100644
index 0000000000..f57666ac70
--- /dev/null
+++ b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/exception/CsarSizeReducerException.java
@@ -0,0 +1,30 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage.exception;
+
+import org.openecomp.sdc.be.exception.BusinessException;
+
+public class CsarSizeReducerException extends BusinessException {
+
+ public CsarSizeReducerException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/exception/PersistentVolumeArtifactStorageException.java b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/exception/PersistentVolumeArtifactStorageException.java
new file mode 100644
index 0000000000..28fff65bb6
--- /dev/null
+++ b/common-be/src/main/java/org/openecomp/sdc/be/csar/storage/exception/PersistentVolumeArtifactStorageException.java
@@ -0,0 +1,34 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage.exception;
+
+import org.openecomp.sdc.be.exception.BusinessException;
+
+public class PersistentVolumeArtifactStorageException extends BusinessException {
+
+ public PersistentVolumeArtifactStorageException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ public PersistentVolumeArtifactStorageException(final String message) {
+ super(message);
+ }
+}
diff --git a/common-be/src/test/java/org/openecomp/sdc/be/csar/storage/CsarSizeReducerTest.java b/common-be/src/test/java/org/openecomp/sdc/be/csar/storage/CsarSizeReducerTest.java
new file mode 100644
index 0000000000..c7586446f7
--- /dev/null
+++ b/common-be/src/test/java/org/openecomp/sdc/be/csar/storage/CsarSizeReducerTest.java
@@ -0,0 +1,87 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.openecomp.sdc.common.zip.ZipUtils;
+import org.openecomp.sdc.common.zip.exception.ZipException;
+
+class CsarSizeReducerTest {
+
+ @Mock
+ private CsarPackageReducerConfiguration csarPackageReducerConfiguration;
+ @InjectMocks
+ private CsarSizeReducer csarSizeReducer;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ }
+
+ @Test
+ void reduceByPathAndSizeTest() throws ZipException {
+ final var pathToReduce1 = Path.of("Files/images");
+ final var pathToReduce2 = Path.of("Files/Scripts/my_script.sh");
+ final var sizeLimit = 150000L;
+ when(csarPackageReducerConfiguration.getSizeLimit()).thenReturn(sizeLimit);
+ when(csarPackageReducerConfiguration.getFoldersToStrip()).thenReturn(Set.of(pathToReduce1, pathToReduce2));
+
+ final var csarPath = Path.of("src/test/resources/csarSizeReducer/dummy.csar");
+
+ final Map<String, byte[]> originalCsar = ZipUtils.readZip(csarPath.toFile(), false);
+
+ final byte[] reduce = csarSizeReducer.reduce(csarPath);
+
+ final Map<String, byte[]> reducedCsar = ZipUtils.readZip(reduce, false);
+
+ assertEquals(originalCsar.keySet().size(), reducedCsar.keySet().size(), "No file should be removed");
+ for (final Entry<String, byte[]> originalEntry : originalCsar.entrySet()) {
+ final var originalFilePath = originalEntry.getKey();
+ final byte[] originalBytes = originalEntry.getValue();
+ assertTrue(reducedCsar.containsKey(originalFilePath),
+ String.format("No file should be removed, but it is missing original file '%s'", originalFilePath));
+
+ if (originalFilePath.startsWith(pathToReduce1.toString()) || originalFilePath.startsWith(pathToReduce2.toString())
+ || originalBytes.length > sizeLimit) {
+ assertArrayEquals("".getBytes(StandardCharsets.UTF_8), reducedCsar.get(originalFilePath),
+ String.format("File '%s' expected to be reduced to empty string", originalFilePath));
+ } else {
+ assertArrayEquals(originalBytes, reducedCsar.get(originalFilePath),
+ String.format("File '%s' expected to be equal", originalFilePath));
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/common-be/src/test/java/org/openecomp/sdc/be/csar/storage/PersistentVolumeArtifactStorageManagerTest.java b/common-be/src/test/java/org/openecomp/sdc/be/csar/storage/PersistentVolumeArtifactStorageManagerTest.java
new file mode 100644
index 0000000000..ab8c11c7c1
--- /dev/null
+++ b/common-be/src/test/java/org/openecomp/sdc/be/csar/storage/PersistentVolumeArtifactStorageManagerTest.java
@@ -0,0 +1,118 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.be.csar.storage;
+
+import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Objects;
+import javax.activation.DataHandler;
+import org.apache.commons.io.IOUtils;
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.mockito.ArgumentMatchers;
+import org.mockito.Mockito;
+
+@TestMethodOrder(OrderAnnotation.class)
+class PersistentVolumeArtifactStorageManagerTest {
+
+ private static final String SRC_TEST_RESOURCES = "src/test/resources/";
+
+ private PersistentVolumeArtifactStorageManager testSubject;
+
+ @BeforeEach
+ void setUp() {
+ testSubject = new PersistentVolumeArtifactStorageManager(new PersistentVolumeArtifactStorageConfig(true, Path.of(SRC_TEST_RESOURCES)));
+ }
+
+ @AfterAll
+ static void tearDown() throws IOException {
+ Files.move(Path.of(SRC_TEST_RESOURCES + "vspId/versionId/versionId"),
+ Path.of(SRC_TEST_RESOURCES + "persistentVolumeArtifactStorageManager/dummy.csar"));
+ Files.list(Path.of("src/test/resources/vspId/versionId/")).forEach(path -> {
+ try {
+ Files.deleteIfExists(path);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ });
+ Files.deleteIfExists(Path.of(SRC_TEST_RESOURCES + "vspId/versionId/"));
+ Files.deleteIfExists(Path.of(SRC_TEST_RESOURCES + "vspId/"));
+ }
+
+ @Test
+ @Order(1)
+ void testUpload() throws IOException {
+ final Attachment attachment = mockAttachment("dummy.csar", this.getClass().getResource("/persistentVolumeArtifactStorageManager/dummy.csar"));
+ final ArtifactInfo result = testSubject.upload("vspId", "versionId", attachment.getDataHandler().getInputStream());
+ Assertions.assertNotNull(result);
+ Assertions.assertNotNull(result.getPath());
+ Assertions.assertTrue(result.getPath().startsWith(Path.of(SRC_TEST_RESOURCES + "vspId/versionId/")));
+ }
+
+ @Test
+ @Order(2)
+ void testPersist() {
+ final ArtifactInfo result = testSubject.persist("vspId", "versionId",
+ new PersistentStorageArtifactInfo(Path.of(SRC_TEST_RESOURCES + "persistentVolumeArtifactStorageManager/dummy.csar")));
+ Assertions.assertNotNull(result);
+ Assertions.assertNotNull(result.getPath());
+ Assertions.assertTrue(result.getPath().startsWith(Path.of(SRC_TEST_RESOURCES + "vspId/versionId/")));
+ }
+
+ @Test
+ void testIsEnabled() {
+ Assertions.assertTrue(testSubject.isEnabled());
+ }
+
+ private Attachment mockAttachment(final String fileName, final URL fileToUpload) throws IOException {
+ final Attachment attachment = Mockito.mock(Attachment.class);
+ when(attachment.getContentDisposition()).thenReturn(new ContentDisposition("test"));
+ final DataHandler dataHandler = Mockito.mock(DataHandler.class);
+ when(dataHandler.getName()).thenReturn(fileName);
+ final InputStream inputStream = Mockito.mock(InputStream.class);
+ when(dataHandler.getInputStream()).thenReturn(inputStream);
+ when(attachment.getDataHandler()).thenReturn(dataHandler);
+ byte[] bytes = "upload package Test".getBytes();
+ if (Objects.nonNull(fileToUpload)) {
+ try {
+ bytes = IOUtils.toByteArray(fileToUpload);
+ } catch (final IOException e) {
+ fail("Not able to convert file to byte array");
+ }
+ }
+ when(attachment.getObject(ArgumentMatchers.any())).thenReturn(bytes);
+ return attachment;
+ }
+
+}
diff --git a/common-be/src/test/resources/csarSizeReducer/dummy.csar b/common-be/src/test/resources/csarSizeReducer/dummy.csar
new file mode 100644
index 0000000000..73b28f52fd
--- /dev/null
+++ b/common-be/src/test/resources/csarSizeReducer/dummy.csar
Binary files differ
diff --git a/common-be/src/test/resources/persistentVolumeArtifactStorageManager/dummy.csar b/common-be/src/test/resources/persistentVolumeArtifactStorageManager/dummy.csar
new file mode 100644
index 0000000000..73b28f52fd
--- /dev/null
+++ b/common-be/src/test/resources/persistentVolumeArtifactStorageManager/dummy.csar
Binary files differ
diff --git a/onboarding/pom.xml b/onboarding/pom.xml
index e04f4b5b25..8cf7eb4b7e 100644
--- a/onboarding/pom.xml
+++ b/onboarding/pom.xml
@@ -65,7 +65,6 @@
<commons.codec.version>1.10</commons.codec.version>
<commons.digester.version>2.1</commons.digester.version>
<commons.lang3.version>${lang3.version}</commons.lang3.version>
- <cxf.version>3.4.3</cxf.version>
<datastax.cassandra.version>3.8.0</datastax.cassandra.version>
<groovy.minimal.version>1.5.8</groovy.minimal.version>
<http.client.version>4.5.3</http.client.version>
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/OrchestrationTemplateCandidateException.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/OrchestrationTemplateCandidateException.java
index 1e20d1ced7..abe227c745 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/OrchestrationTemplateCandidateException.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/OrchestrationTemplateCandidateException.java
@@ -19,9 +19,9 @@
*/
package org.openecomp.sdcrests.vsp.rest.services;
-public class OrchestrationTemplateCandidateException extends Exception {
+public class OrchestrationTemplateCandidateException extends RuntimeException {
- public OrchestrationTemplateCandidateException(String message, Throwable t) {
- super(message, t);
+ public OrchestrationTemplateCandidateException(final String message) {
+ super(message);
}
}
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 cd18cf973b..10f6012a76 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
@@ -16,30 +16,52 @@
* limitations under the License.
* ============LICENSE_END=========================================================
* Modifications copyright (c) 2019 Nokia
+ * Modifications copyright (c) 2021 Nordix Foundation
* ================================================================================
*/
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;
+import static org.openecomp.sdc.common.errors.Messages.ERROR_HAS_OCCURRED_WHILE_PERSISTING_THE_ARTIFACT;
+import static org.openecomp.sdc.common.errors.Messages.ERROR_HAS_OCCURRED_WHILE_REDUCING_THE_ARTIFACT_SIZE;
+import static org.openecomp.sdc.common.errors.Messages.EXTERNAL_CSAR_STORE_CONFIGURATION_FAILURE_MISSING_FULL_PATH;
+import static org.openecomp.sdc.common.errors.Messages.NO_FILE_WAS_UPLOADED_OR_FILE_NOT_EXIST;
+import static org.openecomp.sdc.common.errors.Messages.PACKAGE_PROCESS_ERROR;
+import static org.openecomp.sdc.common.errors.Messages.UNEXPECTED_PROBLEM_HAPPENED_WHILE_GETTING;
import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import javax.activation.DataHandler;
+import java.util.Set;
+import java.util.stream.Collectors;
import javax.inject.Named;
import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.openecomp.sdc.activitylog.ActivityLogManager;
import org.openecomp.sdc.activitylog.ActivityLogManagerFactory;
import org.openecomp.sdc.activitylog.dao.type.ActivityLogEntity;
import org.openecomp.sdc.activitylog.dao.type.ActivityType;
-import org.openecomp.sdc.common.errors.Messages;
+import org.openecomp.sdc.be.csar.storage.ArtifactInfo;
+import org.openecomp.sdc.be.csar.storage.ArtifactStorageConfig;
+import org.openecomp.sdc.be.csar.storage.ArtifactStorageManager;
+import org.openecomp.sdc.be.csar.storage.CsarPackageReducerConfiguration;
+import org.openecomp.sdc.be.csar.storage.CsarSizeReducer;
+import org.openecomp.sdc.be.csar.storage.PackageSizeReducer;
+import org.openecomp.sdc.be.csar.storage.PersistentVolumeArtifactStorageConfig;
+import org.openecomp.sdc.be.csar.storage.PersistentVolumeArtifactStorageManager;
+import org.openecomp.sdc.be.exception.BusinessException;
+import org.openecomp.sdc.common.CommonConfigurationManager;
import org.openecomp.sdc.common.util.ValidationUtils;
import org.openecomp.sdc.common.utils.SdcCommon;
import org.openecomp.sdc.datatypes.error.ErrorLevel;
@@ -76,49 +98,100 @@ import org.springframework.stereotype.Service;
public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplateCandidate {
private static final Logger LOGGER = LoggerFactory.getLogger(OrchestrationTemplateCandidateImpl.class);
+ private static final String EXTERNAL_CSAR_STORE = "externalCsarStore";
private final OrchestrationTemplateCandidateManager candidateManager;
private final VendorSoftwareProductManager vendorSoftwareProductManager;
private final ActivityLogManager activityLogManager;
+ private final ArtifactStorageManager artifactStorageManager;
+ private final PackageSizeReducer packageSizeReducer;
public OrchestrationTemplateCandidateImpl() {
this.candidateManager = OrchestrationTemplateCandidateManagerFactory.getInstance().createInterface();
this.vendorSoftwareProductManager = VspManagerFactory.getInstance().createInterface();
this.activityLogManager = ActivityLogManagerFactory.getInstance().createInterface();
+ LOGGER.info("Instantiating artifactStorageManager");
+ this.artifactStorageManager = new PersistentVolumeArtifactStorageManager(readArtifactStorageConfiguration());
+ LOGGER.info("Instantiating packageSizeReducer");
+ this.packageSizeReducer = new CsarSizeReducer(readPackageReducerConfiguration());
}
// Constructor used in test to avoid mock static
- public OrchestrationTemplateCandidateImpl(OrchestrationTemplateCandidateManager candidateManager,
- VendorSoftwareProductManager vendorSoftwareProductManager, ActivityLogManager activityLogManager) {
+ public OrchestrationTemplateCandidateImpl(final OrchestrationTemplateCandidateManager candidateManager,
+ final VendorSoftwareProductManager vendorSoftwareProductManager,
+ final ActivityLogManager activityLogManager,
+ final ArtifactStorageManager artifactStorageManager,
+ final PackageSizeReducer packageSizeReducer) {
this.candidateManager = candidateManager;
this.vendorSoftwareProductManager = vendorSoftwareProductManager;
this.activityLogManager = activityLogManager;
+ this.artifactStorageManager = artifactStorageManager;
+ this.packageSizeReducer = packageSizeReducer;
+ }
+
+ private CsarPackageReducerConfiguration readPackageReducerConfiguration() {
+ final var commonConfigurationManager = CommonConfigurationManager.getInstance();
+ final List<String> foldersToStrip = commonConfigurationManager.getConfigValue(EXTERNAL_CSAR_STORE, "foldersToStrip", new ArrayList<>());
+ final int sizeLimit = commonConfigurationManager.getConfigValue(EXTERNAL_CSAR_STORE, "sizeLimit", 1000000);
+ LOGGER.info("Folders to strip: '{}'", String.join(", ", foldersToStrip));
+ final Set<Path> foldersToStripPathSet = foldersToStrip.stream().map(Path::of).collect(Collectors.toSet());
+ return new CsarPackageReducerConfiguration(foldersToStripPathSet, sizeLimit);
+ }
+
+ private ArtifactStorageConfig readArtifactStorageConfiguration() {
+ final var commonConfigurationManager = CommonConfigurationManager.getInstance();
+ final boolean isEnabled = commonConfigurationManager.getConfigValue(EXTERNAL_CSAR_STORE, "storeCsarsExternally", false);
+ LOGGER.info("ArtifactConfig.isEnabled: '{}'", isEnabled);
+ final String storagePathString = commonConfigurationManager.getConfigValue(EXTERNAL_CSAR_STORE, "fullPath", null);
+ LOGGER.info("ArtifactConfig.storagePath: '{}'", storagePathString);
+ if (isEnabled && storagePathString == null) {
+ throw new OrchestrationTemplateCandidateException(EXTERNAL_CSAR_STORE_CONFIGURATION_FAILURE_MISSING_FULL_PATH.getErrorMessage());
+ }
+ final var storagePath = storagePathString == null ? null : Path.of(storagePathString);
+ return new PersistentVolumeArtifactStorageConfig(isEnabled, storagePath);
}
@Override
public Response upload(final String vspId, final String versionId, final Attachment fileToUpload, final String user) {
- final byte[] fileToUploadBytes = fileToUpload.getObject(byte[].class);
- final DataHandler dataHandler = fileToUpload.getDataHandler();
- final String filename = ValidationUtils.sanitizeInputString(dataHandler.getName());
- final OnboardingPackageProcessor onboardingPackageProcessor =
- new OnboardingPackageProcessor(filename, fileToUploadBytes, new CnfPackageValidator());
+ final byte[] fileToUploadBytes;
+ final var filename = ValidationUtils.sanitizeInputString(fileToUpload.getDataHandler().getName());
+ ArtifactInfo artifactInfo = null;
+ if (artifactStorageManager.isEnabled()) {
+ final InputStream packageInputStream;
+ try {
+ packageInputStream = fileToUpload.getDataHandler().getInputStream();
+ } catch (final IOException e) {
+ return Response.status(INTERNAL_SERVER_ERROR).entity(buildUploadResponseWithError(new ErrorMessage(ErrorLevel.ERROR, UNEXPECTED_PROBLEM_HAPPENED_WHILE_GETTING.formatMessage(filename)))).build();
+ }
+ try {
+ artifactInfo = artifactStorageManager.upload(vspId, versionId, packageInputStream);
+ } catch (final BusinessException e) {
+ return Response.status(INTERNAL_SERVER_ERROR).entity(buildUploadResponseWithError(new ErrorMessage(ErrorLevel.ERROR, ERROR_HAS_OCCURRED_WHILE_PERSISTING_THE_ARTIFACT.formatMessage(filename)))).build();
+ }
+ try {
+ fileToUploadBytes = packageSizeReducer.reduce(artifactInfo.getPath());
+ } catch (final BusinessException e) {
+ return Response.status(INTERNAL_SERVER_ERROR).entity(buildUploadResponseWithError(new ErrorMessage(ErrorLevel.ERROR, ERROR_HAS_OCCURRED_WHILE_REDUCING_THE_ARTIFACT_SIZE.formatMessage(artifactInfo.getPath())))).build();
+ }
+ } else {
+ fileToUploadBytes = fileToUpload.getObject(byte[].class);
+ }
+
+ final var onboardingPackageProcessor = new OnboardingPackageProcessor(filename, fileToUploadBytes, new CnfPackageValidator(), artifactInfo);
final ErrorMessage[] errorMessages = onboardingPackageProcessor.getErrorMessages().toArray(new ErrorMessage[0]);
if (onboardingPackageProcessor.hasErrors()) {
- final UploadFileResponseDto uploadFileResponseDto = buildUploadResponseWithError(
- errorMessages);
- return Response.status(Status.NOT_ACCEPTABLE).entity(uploadFileResponseDto).build();
+ return Response.status(NOT_ACCEPTABLE).entity(buildUploadResponseWithError(errorMessages)).build();
}
- final OnboardPackageInfo onboardPackageInfo = onboardingPackageProcessor.getOnboardPackageInfo().orElse(null);
+ final var onboardPackageInfo = onboardingPackageProcessor.getOnboardPackageInfo().orElse(null);
if (onboardPackageInfo == null) {
- final UploadFileResponseDto uploadFileResponseDto = buildUploadResponseWithError(
- new ErrorMessage(ErrorLevel.ERROR, Messages.PACKAGE_PROCESS_ERROR.formatMessage(filename)));
- return Response.ok(uploadFileResponseDto).build();
+ return Response.ok(buildUploadResponseWithError(new ErrorMessage(ErrorLevel.ERROR, PACKAGE_PROCESS_ERROR.formatMessage(filename)))).build();
}
- final VspDetails vspDetails = new VspDetails(ValidationUtils.sanitizeInputString(vspId),
+ final var vspDetails = new VspDetails(ValidationUtils.sanitizeInputString(vspId),
new Version(ValidationUtils.sanitizeInputString(versionId)));
return processOnboardPackage(onboardPackageInfo, vspDetails, errorMessages);
}
- private Response processOnboardPackage(final OnboardPackageInfo onboardPackageInfo, final VspDetails vspDetails, final ErrorMessage... errorMessages) {
+ private Response processOnboardPackage(final OnboardPackageInfo onboardPackageInfo, final VspDetails vspDetails,
+ final ErrorMessage... errorMessages) {
final UploadFileResponse uploadFileResponse = candidateManager.upload(vspDetails, onboardPackageInfo);
final UploadFileResponseDto uploadFileResponseDto = new MapUploadFileResponseToUploadFileResponseDto()
.applyMapping(uploadFileResponse, UploadFileResponseDto.class);
@@ -151,10 +224,9 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate
} else {
zipFile = vendorSoftwareProductManager.get(vspId, new Version((versionId)));
if (!zipFile.isPresent()) {
- ErrorMessage errorMessage = new ErrorMessage(ErrorLevel.ERROR,
- getErrorWithParameters(Messages.NO_FILE_WAS_UPLOADED_OR_FILE_NOT_EXIST.getErrorMessage(), ""));
+ ErrorMessage errorMessage = new ErrorMessage(ErrorLevel.ERROR, getErrorWithParameters(NO_FILE_WAS_UPLOADED_OR_FILE_NOT_EXIST.getErrorMessage(), ""));
LOGGER.error(errorMessage.getMessage());
- return Response.status(Response.Status.NOT_FOUND).build();
+ return Response.status(NOT_FOUND).build();
}
fileName = "Processed." + zipFile.get().getLeft();
}
@@ -183,8 +255,7 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate
FilesDataStructure fileDataStructure = copyFilesDataStructureDtoToFilesDataStructure(fileDataStructureDto);
ValidationResponse response = candidateManager.updateFilesDataStructure(vspId, new Version(versionId), fileDataStructure);
if (!response.isValid()) {
- return Response.status(Response.Status.EXPECTATION_FAILED)
- .entity(new MapValidationResponseToDto().applyMapping(response, ValidationResponseDto.class)).build();
+ return Response.status(EXPECTATION_FAILED).entity(new MapValidationResponseToDto().applyMapping(response, ValidationResponseDto.class)).build();
}
return Response.ok(fileDataStructureDto).build();
}
diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImplTest.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImplTest.java
index 41891dea74..b89756e501 100644
--- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImplTest.java
+++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImplTest.java
@@ -7,9 +7,9 @@
* 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.
@@ -20,15 +20,21 @@
package org.openecomp.sdcrests.vsp.rest.services;
-import static junit.framework.TestCase.assertEquals;
-import static junit.framework.TestCase.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.MockitoAnnotations.initMocks;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
@@ -40,14 +46,17 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
import org.openecomp.sdc.activitylog.ActivityLogManager;
+import org.openecomp.sdc.be.csar.storage.ArtifactStorageManager;
+import org.openecomp.sdc.be.csar.storage.PackageSizeReducer;
+import org.openecomp.sdc.be.csar.storage.PersistentStorageArtifactInfo;
import org.openecomp.sdc.logging.api.Logger;
import org.openecomp.sdc.logging.api.LoggerFactory;
import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManager;
@@ -62,17 +71,20 @@ import org.openecomp.sdcrests.vendorsoftwareproducts.types.FileDataStructureDto;
import org.openecomp.sdcrests.vendorsoftwareproducts.types.OrchestrationTemplateActionResponseDto;
import org.openecomp.sdcrests.vendorsoftwareproducts.types.UploadFileResponseDto;
-public class OrchestrationTemplateCandidateImplTest {
+class OrchestrationTemplateCandidateImplTest {
- private Logger logger = LoggerFactory.getLogger(OrchestrationTemplateCandidateImplTest.class);
+ private final Logger logger = LoggerFactory.getLogger(OrchestrationTemplateCandidateImplTest.class);
@Mock
private OrchestrationTemplateCandidateManager candidateManager;
@Mock
private VendorSoftwareProductManager vendorSoftwareProductManager;
-
@Mock
private ActivityLogManager activityLogManager;
+ @Mock
+ private ArtifactStorageManager artifactStorageManager;
+ @Mock
+ private PackageSizeReducer packageSizeReducer;
private OrchestrationTemplateCandidateImpl orchestrationTemplateCandidate;
@@ -82,64 +94,59 @@ public class OrchestrationTemplateCandidateImplTest {
private final String user = "cs0008";
- @Before
- public void setUp(){
+ @BeforeEach
+ public void setUp() {
try {
- initMocks(this);
+ MockitoAnnotations.openMocks(this);
UploadFileResponse uploadFileResponse = new UploadFileResponse();
uploadFileResponse.setOnboardingType(OnboardingTypesEnum.ZIP);
uploadFileResponse.setNetworkPackageName("test");
when(candidateManager.upload(any(), any())).thenReturn(uploadFileResponse);
-
// get using the candidate manager.
- Optional<Pair<String,byte[]>> zipFile =
- Optional.of(Pair.of("Hello", "World".getBytes()));
+ Optional<Pair<String, byte[]>> zipFile = Optional.of(Pair.of("Hello", "World".getBytes()));
when(candidateManager.get(
- ArgumentMatchers.eq(candidateId),
- ArgumentMatchers.any())).thenReturn(zipFile);
+ ArgumentMatchers.eq(candidateId),
+ ArgumentMatchers.any())).thenReturn(zipFile);
when(vendorSoftwareProductManager.get(
- ArgumentMatchers.eq(softwareProductId),
- ArgumentMatchers.any())).thenReturn(zipFile);
-
+ ArgumentMatchers.eq(softwareProductId),
+ ArgumentMatchers.any())).thenReturn(zipFile);
- OrchestrationTemplateActionResponse processResponse =
- new OrchestrationTemplateActionResponse();
+ OrchestrationTemplateActionResponse processResponse = new OrchestrationTemplateActionResponse();
processResponse.setStatus(UploadFileStatus.Success);
when(candidateManager.process(
- ArgumentMatchers.eq(candidateId),
- ArgumentMatchers.any())).thenReturn(processResponse);
-
+ ArgumentMatchers.eq(candidateId),
+ ArgumentMatchers.any())).thenReturn(processResponse);
ValidationResponse vr = new ValidationResponse();
when(candidateManager.updateFilesDataStructure(
- ArgumentMatchers.eq(candidateId),
- ArgumentMatchers.any(),
- ArgumentMatchers.any())).thenReturn(vr);
+ ArgumentMatchers.eq(candidateId),
+ ArgumentMatchers.any(),
+ ArgumentMatchers.any())).thenReturn(vr);
FilesDataStructure fds = new FilesDataStructure();
- fds.setArtifacts(Arrays.asList("a","b"));
+ fds.setArtifacts(Arrays.asList("a", "b"));
fds.setNested(Arrays.asList("foo", "bar"));
fds.setUnassigned(Arrays.asList("c", "d"));
fds.setModules(Arrays.asList(new Module(), new Module()));
when(candidateManager.getFilesDataStructure(
- ArgumentMatchers.eq(candidateId),
- ArgumentMatchers.any())).thenReturn(Optional.of(fds));
+ ArgumentMatchers.eq(candidateId),
+ ArgumentMatchers.any())).thenReturn(Optional.of(fds));
orchestrationTemplateCandidate =
- new OrchestrationTemplateCandidateImpl(candidateManager, vendorSoftwareProductManager, activityLogManager);
-
+ new OrchestrationTemplateCandidateImpl(candidateManager, vendorSoftwareProductManager, activityLogManager,
+ artifactStorageManager, packageSizeReducer);
- }catch (Exception e){
- logger.error(e.getMessage(), e);
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
}
}
@Test
- public void uploadSignedTest() {
+ void uploadSignedTest() {
Response response = orchestrationTemplateCandidate
.upload("1", "1", mockAttachment("filename.zip", this.getClass().getResource("/files/sample-signed.zip")),
"1");
@@ -148,7 +155,21 @@ public class OrchestrationTemplateCandidateImplTest {
}
@Test
- public void uploadNotSignedTest() {
+ void uploadNotSignedTest() throws IOException {
+ Response response = orchestrationTemplateCandidate.upload("1", "1",
+ mockAttachment("filename.csar", this.getClass().getResource("/files/sample-not-signed.csar")), "1");
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+ assertTrue(((UploadFileResponseDto) response.getEntity()).getErrors().isEmpty());
+ }
+
+ @Test
+ void uploadNotSignedArtifactStorageManagerIsEnabledTest() throws IOException {
+ when(artifactStorageManager.isEnabled()).thenReturn(true);
+ final Path path = Path.of("src/test/resources/files/sample-not-signed.csar");
+ when(artifactStorageManager.upload(anyString(), anyString(), any())).thenReturn(new PersistentStorageArtifactInfo(path));
+ final byte[] bytes = Files.readAllBytes(path);
+ when(packageSizeReducer.reduce(any())).thenReturn(bytes);
+
Response response = orchestrationTemplateCandidate.upload("1", "1",
mockAttachment("filename.csar", this.getClass().getResource("/files/sample-not-signed.csar")), "1");
assertEquals(Status.OK.getStatusCode(), response.getStatus());
@@ -167,7 +188,7 @@ public class OrchestrationTemplateCandidateImplTest {
bytes = IOUtils.toByteArray(fileToUpload);
} catch (final IOException e) {
logger.error("unexpected exception", e);
- Assert.fail("Not able to convert file to byte array");
+ fail("Not able to convert file to byte array");
}
}
when(attachment.getObject(ArgumentMatchers.any())).thenReturn(bytes);
@@ -175,7 +196,7 @@ public class OrchestrationTemplateCandidateImplTest {
}
@Test
- public void uploadSignNotValidTest() {
+ void uploadSignNotValidTest() {
Response response = orchestrationTemplateCandidate
.upload("1", "1", mockAttachment("filename.zip", null), "1");
assertEquals(Status.NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
@@ -183,82 +204,78 @@ public class OrchestrationTemplateCandidateImplTest {
}
@Test
- public void testCandidateGet() throws IOException {
+ void testCandidateGet() throws IOException {
Response rsp = orchestrationTemplateCandidate.get(candidateId, versionId, user);
- Assert.assertEquals("Response status equals", Response.Status.OK.getStatusCode(), rsp.getStatus());
- Assert.assertNotEquals(rsp.getHeaderString("Content-Disposition").indexOf("Candidate"),-1);
- byte[] content = (byte[])rsp.getEntity();
- Assert.assertEquals("World", new String(content));
+ assertEquals(Response.Status.OK.getStatusCode(), rsp.getStatus(), "Response status equals");
+ assertNotEquals(rsp.getHeaderString("Content-Disposition").indexOf("Candidate"), -1);
+ byte[] content = (byte[]) rsp.getEntity();
+ assertEquals("World", new String(content));
}
@Test
- public void testVendorSoftwareProductGet() throws IOException {
+ void testVendorSoftwareProductGet() throws IOException {
Response rsp = orchestrationTemplateCandidate.get(softwareProductId, versionId, user);
- Assert.assertEquals("Response status equals", Response.Status.OK.getStatusCode(), rsp.getStatus());
- Assert.assertNotEquals(rsp.getHeaderString("Content-Disposition").indexOf("Processed"),-1);
- byte[] content = (byte[])rsp.getEntity();
- Assert.assertEquals("World", new String(content));
+ assertEquals(Response.Status.OK.getStatusCode(), rsp.getStatus(), "Response status equals");
+ assertNotEquals(rsp.getHeaderString("Content-Disposition").indexOf("Processed"), -1);
+ byte[] content = (byte[]) rsp.getEntity();
+ assertEquals("World", new String(content));
}
@Test
- public void testMissingGet() throws IOException {
+ void testMissingGet() throws IOException {
Response rsp = orchestrationTemplateCandidate.get(UUID.randomUUID().toString(), versionId, user);
- Assert.assertEquals("Response status equals", Response.Status.NOT_FOUND.getStatusCode(), rsp.getStatus());
+ assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rsp.getStatus(), "Response status equals");
}
@Test
- public void testAbort() {
+ void testAbort() {
try {
Response rsp = orchestrationTemplateCandidate.abort(candidateId, versionId);
- Assert.assertEquals("Response status equals", Response.Status.OK.getStatusCode(), rsp.getStatus());
- Assert.assertNull(rsp.getEntity());
- }
- catch (Exception ex) {
+ assertEquals(Response.Status.OK.getStatusCode(), rsp.getStatus(), "Response status equals");
+ assertNull(rsp.getEntity());
+ } catch (Exception ex) {
logger.error("unexpected exception", ex);
- Assert.fail("abort should not throw an exception");
+ fail("abort should not throw an exception");
}
}
@Test
- public void testProcess() {
+ void testProcess() {
try {
Response rsp = orchestrationTemplateCandidate.process(candidateId, versionId, user);
- Assert.assertEquals("Response status equals", Response.Status.OK.getStatusCode(), rsp.getStatus());
- Assert.assertNotNull(rsp.getEntity());
- OrchestrationTemplateActionResponseDto dto = (OrchestrationTemplateActionResponseDto)rsp.getEntity();
- Assert.assertEquals("status check", UploadFileStatus.Success, dto.getStatus());
- }
- catch (Exception ex) {
+ assertEquals(Response.Status.OK.getStatusCode(), rsp.getStatus(), "Response status equals");
+ assertNotNull(rsp.getEntity());
+ OrchestrationTemplateActionResponseDto dto = (OrchestrationTemplateActionResponseDto) rsp.getEntity();
+ assertEquals(UploadFileStatus.Success, dto.getStatus(), "status check");
+ } catch (Exception ex) {
logger.error("unexpected exception", ex);
- Assert.fail("abort should not throw an exception");
+ fail("abort should not throw an exception");
}
}
@Test
- public void testFilesDataStructureUpload() {
+ void testFilesDataStructureUpload() {
try {
FileDataStructureDto dto = new FileDataStructureDto();
dto.setArtifacts(Arrays.asList("a", "b", "c"));
Response rsp = orchestrationTemplateCandidate.updateFilesDataStructure(candidateId, versionId, dto, user);
- Assert.assertEquals("Response status equals", Response.Status.OK.getStatusCode(), rsp.getStatus());
- }
- catch (Exception ex) {
+ assertEquals(Response.Status.OK.getStatusCode(), rsp.getStatus(), "Response status equals");
+ } catch (Exception ex) {
logger.error("unexpected exception", ex);
- Assert.fail("abort should not throw an exception");
+ fail("abort should not throw an exception");
}
}
@Test
- public void testFilesDataStructureGet() {
+ void testFilesDataStructureGet() {
try {
FileDataStructureDto dto = new FileDataStructureDto();
dto.setArtifacts(Arrays.asList("a", "b", "c"));
Response rsp = orchestrationTemplateCandidate.getFilesDataStructure(candidateId, versionId, user);
- Assert.assertEquals("Response status equals", Response.Status.OK.getStatusCode(), rsp.getStatus());
- }
- catch (Exception ex) {
+ assertEquals(Response.Status.OK.getStatusCode(), rsp.getStatus(), "Response status equals");
+ } catch (Exception ex) {
logger.error("unexpected exception", ex);
- Assert.fail("abort should not throw an exception");
+ fail("abort should not throw an exception");
}
}
diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessor.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessor.java
index e5b68cb917..14b839e3af 100644
--- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessor.java
+++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessor.java
@@ -49,6 +49,7 @@ import org.apache.commons.io.FilenameUtils;
import org.openecomp.core.utilities.file.FileContentHandler;
import org.openecomp.core.utilities.json.JsonUtil;
import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
+import org.openecomp.sdc.be.csar.storage.ArtifactInfo;
import org.openecomp.sdc.common.CommonConfigurationManager;
import org.openecomp.sdc.common.utils.CommonUtil;
import org.openecomp.sdc.common.utils.SdcCommon;
@@ -76,12 +77,15 @@ public class OnboardingPackageProcessor {
private final CnfPackageValidator cnfPackageValidator;
private FileContentHandler packageContent;
- public OnboardingPackageProcessor(final String packageFileName, final byte[] packageFileContent,
- final CnfPackageValidator cnfPackageValidator) {
+ public OnboardingPackageProcessor(final String packageFileName, final byte[] packageFileContent, final CnfPackageValidator cnfPackageValidator,
+ final ArtifactInfo artifactInfo) {
this.packageFileName = packageFileName;
this.packageFileContent = packageFileContent;
this.cnfPackageValidator = cnfPackageValidator;
onboardPackageInfo = processPackage();
+ if (onboardPackageInfo != null) {
+ onboardPackageInfo.setArtifactInfo(artifactInfo);
+ }
}
public Optional<OnboardPackageInfo> getOnboardPackageInfo() {
diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateCSARHandler.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateCSARHandler.java
index e7367c2a49..f1062395af 100644
--- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateCSARHandler.java
+++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateCSARHandler.java
@@ -42,7 +42,7 @@ import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardPackageInfo;
import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardSignedPackage;
import org.openecomp.sdc.vendorsoftwareproduct.types.UploadFileResponse;
-public class OrchestrationTemplateCSARHandler extends BaseOrchestrationTemplateHandler implements OrchestrationTemplateFileHandler {
+public class OrchestrationTemplateCSARHandler extends BaseOrchestrationTemplateHandler {
@Override
public UploadFileResponse validate(final OnboardPackageInfo onboardPackageInfo) {
@@ -100,9 +100,10 @@ public class OrchestrationTemplateCSARHandler extends BaseOrchestrationTemplateH
final OnboardPackage csarPackage = onboardPackageInfo.getOnboardPackage();
final OnboardPackage originalOnboardPackage = onboardPackageInfo.getOriginalOnboardPackage();
try {
- candidateService.updateCandidateUploadData(vspDetails.getId(), vspDetails.getVersion(),
- new OrchestrationTemplateCandidateData(csarPackage.getFileContent(), "", csarPackage.getFileExtension(), csarPackage.getFilename(),
- originalOnboardPackage.getFilename(), originalOnboardPackage.getFileExtension(), originalOnboardPackage.getFileContent()));
+ final var candidateData = new OrchestrationTemplateCandidateData(csarPackage.getFileContent(), csarPackage.getFileExtension(),
+ csarPackage.getFilename(), originalOnboardPackage.getFilename(), originalOnboardPackage.getFileExtension(),
+ originalOnboardPackage.getFileContent(), onboardPackageInfo.getArtifactInfo());
+ candidateService.updateCandidateUploadData(vspDetails.getId(), vspDetails.getVersion(), candidateData);
} catch (final Exception exception) {
logger.error(getErrorWithParameters(Messages.FILE_LOAD_CONTENT_ERROR.getErrorMessage(), getHandlerType().toString()), exception);
uploadFileResponse.addStructureError(SdcCommon.UPLOAD_FILE, new ErrorMessage(ErrorLevel.ERROR, exception.getMessage()));
diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateZipHandler.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateZipHandler.java
index 65ce2f5397..e534eded02 100644
--- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateZipHandler.java
+++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateZipHandler.java
@@ -34,7 +34,7 @@ import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardPackage;
import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardPackageInfo;
import org.openecomp.sdc.vendorsoftwareproduct.types.UploadFileResponse;
-public class OrchestrationTemplateZipHandler extends BaseOrchestrationTemplateHandler implements OrchestrationTemplateFileHandler {
+public class OrchestrationTemplateZipHandler extends BaseOrchestrationTemplateHandler {
@Override
public UploadFileResponse validate(final OnboardPackageInfo onboardPackageInfo) {
@@ -55,6 +55,7 @@ public class OrchestrationTemplateZipHandler extends BaseOrchestrationTemplateHa
uploadFileResponse.getErrors());
candidateData.setFileName(zipPackage.getFilename());
candidateData.setFileSuffix(zipPackage.getFileExtension());
+ candidateData.setArtifactInfo(onboardPackageInfo.getArtifactInfo());
candidateService.updateCandidateUploadData(vspDetails.getId(), vspDetails.getVersion(), candidateData);
} catch (final Exception exception) {
logger.error(getErrorWithParameters(Messages.FILE_LOAD_CONTENT_ERROR.getErrorMessage(), getHandlerType().toString()), exception);
diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/types/OnboardPackageInfo.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/types/OnboardPackageInfo.java
index a78185e89f..4bb1d98f3f 100644
--- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/types/OnboardPackageInfo.java
+++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/types/OnboardPackageInfo.java
@@ -20,7 +20,9 @@ package org.openecomp.sdc.vendorsoftwareproduct.types;
import java.nio.ByteBuffer;
import lombok.Getter;
+import lombok.Setter;
import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
+import org.openecomp.sdc.be.csar.storage.ArtifactInfo;
import org.openecomp.sdc.vendorsoftwareproduct.exception.OnboardPackageException;
@Getter
@@ -29,6 +31,8 @@ public class OnboardPackageInfo {
private final OnboardingTypesEnum packageType;
private final OnboardPackage originalOnboardPackage;
private final OnboardPackage onboardPackage;
+ @Setter
+ private ArtifactInfo artifactInfo;
public OnboardPackageInfo(final OnboardPackage onboardPackage, final OnboardingTypesEnum packageType) {
this(onboardPackage, onboardPackage, packageType);
diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessorTest.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessorTest.java
index 6c847a713e..80e257c636 100644
--- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessorTest.java
+++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessorTest.java
@@ -118,7 +118,7 @@ public class OnboardingPackageProcessorTest {
@Test
public void processPackage() {
final OnboardingPackageProcessor onboardingPackageProcessor = new OnboardingPackageProcessor(packageName,
- packageBytes, cnfPackageValidator);
+ packageBytes, cnfPackageValidator, null);
assertThat("Should contains errors", onboardingPackageProcessor.hasErrors(), is(!expectedErrorSet.isEmpty()));
assertThat("Should have the same number of errors", onboardingPackageProcessor.getErrorMessages().size(),
equalTo(expectedErrorSet.size()));
diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessorUnitTest.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessorUnitTest.java
index 795da7780f..d9cd72e198 100644
--- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessorUnitTest.java
+++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessorUnitTest.java
@@ -34,8 +34,7 @@ import org.openecomp.sdc.vendorsoftwareproduct.impl.onboarding.validation.CnfPac
public class OnboardingPackageProcessorUnitTest {
- private OnboardingPackageProcessor processor = new OnboardingPackageProcessor("unitTestPackage",
- null, new CnfPackageValidator());
+ private final OnboardingPackageProcessor processor = new OnboardingPackageProcessor("unitTestPackage", null, new CnfPackageValidator(), null);
@Test
public void shouldValidateZipPackage_helmWithoutHeat() {
diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/CsarSecurityValidatorTest.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/CsarSecurityValidatorTest.java
index 27d80412bf..5f5f9eb7dc 100644
--- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/CsarSecurityValidatorTest.java
+++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/CsarSecurityValidatorTest.java
@@ -90,7 +90,7 @@ public class CsarSecurityValidatorTest {
private OnboardSignedPackage loadSignedPackage(final String packageName, final byte[] packageBytes,
CnfPackageValidator cnfPackageValidator) {
final OnboardingPackageProcessor onboardingPackageProcessor =
- new OnboardingPackageProcessor(packageName, packageBytes, cnfPackageValidator);
+ new OnboardingPackageProcessor(packageName, packageBytes, cnfPackageValidator, null);
final OnboardPackageInfo onboardPackageInfo = onboardingPackageProcessor.getOnboardPackageInfo().orElse(null);
if (onboardPackageInfo == null) {
fail("Unexpected error. Could not load original package");
diff --git a/openecomp-be/dist/sdc-onboard-backend-docker/artifacts/chef-repo/cookbooks/sdc-onboard-backend/templates/default/configuration.yaml.erb b/openecomp-be/dist/sdc-onboard-backend-docker/artifacts/chef-repo/cookbooks/sdc-onboard-backend/templates/default/configuration.yaml.erb
index 474dd48326..56951377ec 100644
--- a/openecomp-be/dist/sdc-onboard-backend-docker/artifacts/chef-repo/cookbooks/sdc-onboard-backend/templates/default/configuration.yaml.erb
+++ b/openecomp-be/dist/sdc-onboard-backend-docker/artifacts/chef-repo/cookbooks/sdc-onboard-backend/templates/default/configuration.yaml.erb
@@ -52,4 +52,11 @@ basicAuth:
excludedUrls: "/v1.0/healthcheck"
zipValidation:
- ignoreManifest: false \ No newline at end of file
+ ignoreManifest: false
+
+externalCsarStore:
+ storeCsarsExternally: false
+ fullPath: "/home/onap/temp/"
+ foldersToStrip:
+ - Files/images
+ sizeLimit: 10000000 \ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java b/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java
index 91ed6ae2f8..28ce5d2a62 100644
--- a/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java
+++ b/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java
@@ -201,7 +201,12 @@ public enum Messages {
/* Notifications */
FAILED_TO_MARK_NOTIFICATION_AS_READ("Failed to mark notifications as read"),
FAILED_TO_UPDATE_LAST_SEEN_NOTIFICATION("Failed to update last seen notification for user %s"),
- FAILED_TO_VERIFY_SIGNATURE("Could not verify signature of signed package.");
+ FAILED_TO_VERIFY_SIGNATURE("Could not verify signature of signed package."),
+ EXTERNAL_CSAR_STORE_CONFIGURATION_FAILURE_MISSING_FULL_PATH("externalCsarStore configuration failure, missing 'fullPath'"),
+ ERROR_HAS_OCCURRED_WHILE_PERSISTING_THE_ARTIFACT("An error has occurred while persisting the artifact: %s"),
+ ERROR_HAS_OCCURRED_WHILE_REDUCING_THE_ARTIFACT_SIZE("An error has occurred while reducing the artifact's size: %s"),
+ UNEXPECTED_PROBLEM_HAPPENED_WHILE_GETTING("An unexpected problem happened while getting '%s'"),
+ PERSISTENCE_STORE_IS_DOWN_OR_NOT_AVAILABLE("Persistence store is down or not available. Error: '%s'");
// @formatter:on
private String errorMessage;
diff --git a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/type/OrchestrationTemplateCandidateData.java b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/type/OrchestrationTemplateCandidateData.java
index fdd143d1d2..b079474d1e 100644
--- a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/type/OrchestrationTemplateCandidateData.java
+++ b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/type/OrchestrationTemplateCandidateData.java
@@ -20,6 +20,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.openecomp.core.utilities.json.JsonUtil;
+import org.openecomp.sdc.be.csar.storage.ArtifactInfo;
import org.openecomp.sdc.heat.datatypes.structure.ValidationStructureList;
@Getter
@@ -35,17 +36,19 @@ public class OrchestrationTemplateCandidateData {
private ByteBuffer originalFileContentData;
private String originalFileName;
private String originalFileSuffix;
+ private ArtifactInfo artifactInfo;
- public OrchestrationTemplateCandidateData(final ByteBuffer contentData, final String dataStructureJson, final String fileSuffix,
- final String fileName, final String originalFileName, final String originalFileSuffix,
- final ByteBuffer originalFileContentData) {
+ public OrchestrationTemplateCandidateData(final ByteBuffer contentData, final String fileSuffix, final String fileName,
+ final String originalFileName, final String originalFileSuffix,
+ final ByteBuffer originalFileContentData, final ArtifactInfo artifactInfo) {
this.contentData = contentData;
- this.filesDataStructure = dataStructureJson;
+ this.filesDataStructure = "";
this.fileSuffix = fileSuffix;
this.fileName = fileName;
this.originalFileName = originalFileName;
this.originalFileSuffix = originalFileSuffix;
this.originalFileContentData = originalFileContentData;
+ this.artifactInfo = artifactInfo;
}
public ValidationStructureList getValidationDataStructure() {
diff --git a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/impl/zusammen/OrchestrationTemplateCandidateDaoZusammenException.java b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/impl/zusammen/OrchestrationTemplateCandidateDaoZusammenException.java
new file mode 100644
index 0000000000..5a0a53a182
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/impl/zusammen/OrchestrationTemplateCandidateDaoZusammenException.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.sdc.vendorsoftwareproduct.dao.impl.zusammen;
+
+public class OrchestrationTemplateCandidateDaoZusammenException extends RuntimeException {
+
+ public OrchestrationTemplateCandidateDaoZusammenException(final String message) {
+ super(message);
+ }
+}
diff --git a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/impl/zusammen/OrchestrationTemplateCandidateDaoZusammenImpl.java b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/impl/zusammen/OrchestrationTemplateCandidateDaoZusammenImpl.java
index fb26714375..e5c59968fa 100644
--- a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/impl/zusammen/OrchestrationTemplateCandidateDaoZusammenImpl.java
+++ b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/impl/zusammen/OrchestrationTemplateCandidateDaoZusammenImpl.java
@@ -12,6 +12,9 @@
* 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.
+ * ============LICENSE_END=========================================================
+ * Modifications copyright (c) 2021 Nordix Foundation
+ * ================================================================================
*/
package org.openecomp.sdc.vendorsoftwareproduct.dao.impl.zusammen;
@@ -27,10 +30,21 @@ import com.amdocs.zusammen.datatypes.item.ElementContext;
import com.amdocs.zusammen.utils.fileutils.FileUtils;
import java.io.ByteArrayInputStream;
import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
import java.util.Optional;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
import org.openecomp.core.utilities.json.JsonUtil;
import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
import org.openecomp.core.zusammen.api.ZusammenAdaptor;
+import org.openecomp.sdc.be.csar.storage.ArtifactInfo;
+import org.openecomp.sdc.be.csar.storage.ArtifactStorageConfig;
+import org.openecomp.sdc.be.csar.storage.ArtifactStorageManager;
+import org.openecomp.sdc.be.csar.storage.PersistentVolumeArtifactStorageConfig;
+import org.openecomp.sdc.be.csar.storage.PersistentVolumeArtifactStorageManager;
+import org.openecomp.sdc.common.CommonConfigurationManager;
+import org.openecomp.sdc.common.errors.Messages;
import org.openecomp.sdc.datatypes.model.ElementType;
import org.openecomp.sdc.heat.datatypes.structure.ValidationStructureList;
import org.openecomp.sdc.logging.api.Logger;
@@ -44,10 +58,13 @@ public class OrchestrationTemplateCandidateDaoZusammenImpl implements Orchestrat
private static final Logger logger = LoggerFactory.getLogger(OrchestrationTemplateCandidateDaoZusammenImpl.class);
private static final String EMPTY_DATA = "{}";
+ private static final String EXTERNAL_CSAR_STORE = "externalCsarStore";
private final ZusammenAdaptor zusammenAdaptor;
+ private final ArtifactStorageManager artifactStorageManager;
- public OrchestrationTemplateCandidateDaoZusammenImpl(ZusammenAdaptor zusammenAdaptor) {
+ public OrchestrationTemplateCandidateDaoZusammenImpl(final ZusammenAdaptor zusammenAdaptor) {
this.zusammenAdaptor = zusammenAdaptor;
+ this.artifactStorageManager = new PersistentVolumeArtifactStorageManager(readArtifactStorageConfiguration());
}
@Override
@@ -139,11 +156,24 @@ public class OrchestrationTemplateCandidateDaoZusammenImpl implements Orchestrat
candidateContentElement.setData(new ByteArrayInputStream(candidateData.getContentData().array()));
candidateContentElement.getInfo().addProperty(InfoPropertyName.FILE_SUFFIX.getVal(), candidateData.getFileSuffix());
candidateContentElement.getInfo().addProperty(InfoPropertyName.FILE_NAME.getVal(), candidateData.getFileName());
+ final String versionId = version.getId();
if (OnboardingTypesEnum.CSAR.toString().equalsIgnoreCase(candidateData.getFileSuffix())) {
final ZusammenElement originalPackageElement = buildStructuralElement(ElementType.ORIGINAL_ONBOARDED_PACKAGE, Action.UPDATE);
- originalPackageElement.getInfo().addProperty(InfoPropertyName.ORIGINAL_FILE_NAME.getVal(), candidateData.getOriginalFileName());
- originalPackageElement.getInfo().addProperty(InfoPropertyName.ORIGINAL_FILE_SUFFIX.getVal(), candidateData.getOriginalFileSuffix());
- originalPackageElement.setData(new ByteArrayInputStream(candidateData.getOriginalFileContentData().array()));
+ final String originalFileName = candidateData.getOriginalFileName();
+ final String originalFileSuffix = candidateData.getOriginalFileSuffix();
+ originalPackageElement.getInfo().addProperty(InfoPropertyName.ORIGINAL_FILE_NAME.getVal(), originalFileName);
+ originalPackageElement.getInfo().addProperty(InfoPropertyName.ORIGINAL_FILE_SUFFIX.getVal(), originalFileSuffix);
+ originalPackageElement.getInfo().addProperty("storeCsarsExternally", artifactStorageManager.isEnabled());
+ if (artifactStorageManager.isEnabled()) {
+ final ArtifactInfo candidateArtifactInfo = candidateData.getArtifactInfo();
+ if (candidateArtifactInfo == null) {
+ throw new OrchestrationTemplateCandidateDaoZusammenException("No artifact info provided");
+ }
+ final ArtifactInfo artifactInfo = artifactStorageManager.persist(vspId, versionId, candidateArtifactInfo);
+ originalPackageElement.setData(new ByteArrayInputStream(artifactInfo.getPath().toString().getBytes(StandardCharsets.UTF_8)));
+ } else {
+ originalPackageElement.setData(new ByteArrayInputStream(candidateData.getOriginalFileContentData().array()));
+ }
candidateElement.addSubElement(originalPackageElement);
}
final ZusammenElement validationData = buildStructuralElement(ElementType.OrchestrationTemplateCandidateValidationData, Action.UPDATE);
@@ -152,8 +182,8 @@ public class OrchestrationTemplateCandidateDaoZusammenImpl implements Orchestrat
}
candidateElement.addSubElement(validationData);
candidateElement.addSubElement(candidateContentElement);
- SessionContext context = createSessionContext();
- ElementContext elementContext = new ElementContext(vspId, version.getId());
+ final var context = createSessionContext();
+ final var elementContext = new ElementContext(vspId, versionId);
zusammenAdaptor.saveElement(context, elementContext, candidateElement, "Update Orchestration Template Candidate");
logger.info("Finished uploading candidate data entity for vsp id {}", vspId);
}
@@ -197,16 +227,24 @@ public class OrchestrationTemplateCandidateDaoZusammenImpl implements Orchestrat
return Optional.empty();
}
- public enum InfoPropertyName {
- FILE_SUFFIX("fileSuffix"), FILE_NAME("fileName"), ORIGINAL_FILE_NAME("originalFilename"), ORIGINAL_FILE_SUFFIX("originalFileSuffix");
- private final String val;
-
- InfoPropertyName(String val) {
- this.val = val;
+ private ArtifactStorageConfig readArtifactStorageConfiguration() {
+ final var commonConfigurationManager = CommonConfigurationManager.getInstance();
+ final boolean isEnabled = commonConfigurationManager.getConfigValue(EXTERNAL_CSAR_STORE, "storeCsarsExternally", false);
+ logger.info("ArtifactConfig.isEnabled: '{}'", isEnabled);
+ final String storagePathString = commonConfigurationManager.getConfigValue(EXTERNAL_CSAR_STORE, "fullPath", null);
+ logger.info("ArtifactConfig.storagePath: '{}'", storagePathString);
+ if (isEnabled && storagePathString == null) {
+ throw new OrchestrationTemplateCandidateDaoZusammenException(
+ Messages.EXTERNAL_CSAR_STORE_CONFIGURATION_FAILURE_MISSING_FULL_PATH.getErrorMessage());
}
+ final var storagePath = storagePathString == null ? null : Path.of(storagePathString);
+ return new PersistentVolumeArtifactStorageConfig(isEnabled, storagePath);
+ }
- private String getVal() {
- return val;
- }
+ @Getter
+ @AllArgsConstructor
+ private enum InfoPropertyName {
+ FILE_SUFFIX("fileSuffix"), FILE_NAME("fileName"), ORIGINAL_FILE_NAME("originalFilename"), ORIGINAL_FILE_SUFFIX("originalFileSuffix");
+ private final String val;
}
}
diff --git a/pom.xml b/pom.xml
index b12ec7bfba..1d9a2c91da 100644
--- a/pom.xml
+++ b/pom.xml
@@ -73,6 +73,7 @@ Modifications copyright (c) 2018-2019 Nokia
<ws.rs.version>2.1</ws.rs.version>
<jetty.version>9.4.41.v20210516</jetty.version>
+ <cxf.version>3.4.3</cxf.version>
<!-- JSON and YAML Parsing -->
<jackson.version>2.12.1</jackson.version>