--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 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.onap.so.sdcsimulator.providers;
+
+import static org.onap.so.sdcsimulator.utils.Constants.CATALOG_URL;
+import static org.onap.so.sdcsimulator.utils.Constants.DOT_CSAR;
+import static org.onap.so.sdcsimulator.utils.Constants.DOT_JSON;
+import static org.onap.so.sdcsimulator.utils.Constants.FORWARD_SLASH;
+import static org.onap.so.sdcsimulator.utils.Constants.MAIN_RESOURCE_FOLDER;
+import static org.onap.so.sdcsimulator.utils.Constants.WILD_CARD_REGEX;
+import static org.springframework.core.io.support.ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+import org.onap.so.sdcsimulator.models.AssetInfo;
+import org.onap.so.sdcsimulator.models.AssetType;
+import org.onap.so.sdcsimulator.models.Metadata;
+import org.onap.so.sdcsimulator.models.ResourceAssetInfo;
+import org.onap.so.sdcsimulator.models.ServiceAssetInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StreamUtils;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ */
+@Service
+public class AssetProviderImpl implements AssetProvider {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AssetProvider.class);
+
+ private final ObjectMapper mapper =
+ new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);;
+
+ private final String resourceLocation;
+
+ private final ResourcePatternResolver resourcePatternResolver;
+
+ @Autowired
+ public AssetProviderImpl(@Value("${sdc.resource.location:/app/csars/}") final String resourceLocation,
+ final ResourcePatternResolver resourcePatternResolver) {
+ this.resourceLocation = resourceLocation;
+ this.resourcePatternResolver = resourcePatternResolver;
+ }
+
+ @Override
+ public Optional<byte[]> getAsset(final String csarId, final AssetType assetType) {
+ try {
+ final Optional<InputStream> optionalInputStream = getInputStream(csarId, assetType);
+ if (optionalInputStream.isPresent()) {
+ return Optional.of(StreamUtils.copyToByteArray(optionalInputStream.get()));
+ }
+ } catch (final IOException ioException) {
+ LOGGER.warn("Unable to create file stream ...", ioException);
+ }
+
+ return Optional.empty();
+ }
+
+ @Override
+ public Set<AssetInfo> getAssetInfo(final AssetType assetType) {
+ final Set<AssetInfo> result = new HashSet<>();
+
+ final Path dir = Paths.get(resourceLocation).resolve(assetType.toString());
+ if (Files.exists(dir)) {
+ try (final DirectoryStream<Path> stream = Files.newDirectoryStream(dir, WILD_CARD_REGEX + DOT_CSAR)) {
+ for (final Path entry : stream) {
+ final String filename = getFilenameWithoutExtension(entry);
+ result.add(getAssetInfo(assetType, filename, entry));
+ }
+ } catch (final IOException ioException) {
+ LOGGER.error("Unable to find assetInfo on filesystem", ioException);
+ }
+ }
+
+ try {
+ final String classPathdir = MAIN_RESOURCE_FOLDER + assetType.toString() + FORWARD_SLASH;
+ final String csarFileLocationPattern = CLASSPATH_ALL_URL_PREFIX + classPathdir + WILD_CARD_REGEX + DOT_CSAR;
+ final Resource[] resources = resourcePatternResolver.getResources(csarFileLocationPattern);
+ if (resources != null) {
+
+ for (final Resource resource : resources) {
+ final String filename = getFilenameWithoutExtension(resource.getFilename());
+ result.add(getAssetInfo(assetType, filename, resource));
+ }
+ }
+
+ } catch (final IOException ioException) {
+ LOGGER.error("Unable to find assetInfo in classpath", ioException);
+ }
+
+ return result;
+ }
+
+ @Override
+ public Optional<Metadata> getMetadata(final String csarId, final AssetType assetType) {
+ final Path dir = Paths.get(resourceLocation).resolve(assetType.toString());
+ final Path metadataFilePath = dir.resolve(csarId + DOT_JSON);
+ try {
+ if (Files.exists(metadataFilePath)) {
+ LOGGER.info("Found metadata file on file system using path: {}", metadataFilePath);
+
+ return Optional.of(mapper.readValue(metadataFilePath.toFile(), Metadata.class));
+
+ }
+ } catch (final IOException ioException) {
+ LOGGER.error("Unable to find metadata file on filesystem", ioException);
+ }
+
+
+ try {
+ final String path = MAIN_RESOURCE_FOLDER + assetType.toString() + FORWARD_SLASH + csarId + DOT_JSON;
+ LOGGER.warn("Couldn't find metadata file on file system '{}', will search it in classpath", path);
+ final ClassPathResource classPathResource = getClassPathResource(path);
+ if (classPathResource.exists()) {
+ LOGGER.info("Found metadata file in classpath using path: {}", path);
+ return Optional.of(mapper.readValue(classPathResource.getInputStream(), Metadata.class));
+ }
+ } catch (final IOException ioException) {
+ LOGGER.error("Unable to find metadata file in classpath", ioException);
+ }
+ LOGGER.error("Couldn't find metadata file in classpath ....");
+ return Optional.empty();
+ }
+
+ private AssetInfo getAssetInfo(final AssetType assetType, final String filename, final Resource resource)
+ throws IOException {
+ final Resource jsonResource = resource.createRelative(filename + DOT_JSON);
+
+ if (jsonResource != null && jsonResource.exists()) {
+ final AssetInfo assetInfo = getJsonAssetInfo(assetType, jsonResource);
+ assetInfo.setUuid(filename);
+ assetInfo.setToscaModelUrl(getToscaModelUrl(filename, assetType));
+ LOGGER.info("Found AssetInfo file in classpath: {}", assetInfo);
+ return assetInfo;
+
+ }
+
+ final AssetInfo assetInfo = getAssetInfo(filename, assetType);
+ LOGGER.info("Returning AssetInfo: {}", assetInfo);
+ return assetInfo;
+
+ }
+
+ private AssetInfo getAssetInfo(final AssetType assetType, final String filename, final Path entry)
+ throws IOException {
+ final Path assetJsonFilePath = entry.getParent().resolve(filename + DOT_JSON);
+ if (Files.exists(assetJsonFilePath)) {
+ final AssetInfo assetInfo = getJsonAssetInfo(assetType, assetJsonFilePath.toFile());
+ assetInfo.setUuid(filename);
+ assetInfo.setToscaModelUrl(getToscaModelUrl(filename, assetType));
+ LOGGER.info("Found AssetInfo file on file system: {}", assetInfo);
+ return assetInfo;
+
+ }
+ final AssetInfo assetInfo = getAssetInfo(filename, assetType);
+ LOGGER.info("Returning AssetInfo: {}", assetInfo);
+ return assetInfo;
+ }
+
+
+ private AssetInfo getJsonAssetInfo(final AssetType assetType, final Resource jsonResource) throws IOException {
+ if (AssetType.RESOURCES.equals(assetType)) {
+ return mapper.readValue(jsonResource.getInputStream(), ResourceAssetInfo.class);
+ }
+
+ if (AssetType.SERVICES.equals(assetType)) {
+ return mapper.readValue(jsonResource.getInputStream(), ServiceAssetInfo.class);
+ }
+
+ return mapper.readValue(jsonResource.getInputStream(), AssetInfo.class);
+ }
+
+
+ private AssetInfo getJsonAssetInfo(final AssetType assetType, final File file) throws IOException {
+ if (AssetType.RESOURCES.equals(assetType)) {
+ return mapper.readValue(file, ResourceAssetInfo.class);
+ }
+
+ if (AssetType.SERVICES.equals(assetType)) {
+ return mapper.readValue(file, ServiceAssetInfo.class);
+ }
+
+ return mapper.readValue(file, AssetInfo.class);
+ }
+
+ private AssetInfo getAssetInfo(final String filename, final AssetType assetType) {
+ return getAssetInfoObject(assetType).uuid(filename).invariantUuid(filename).name(filename).version("1.0")
+ .toscaModelUrl(getToscaModelUrl(filename, assetType)).category("Generic").lifecycleState("CERTIFIED")
+ .lastUpdaterUserId("SDC_SIMULATOR");
+ }
+
+ private AssetInfo getAssetInfoObject(final AssetType assetType) {
+ if (AssetType.RESOURCES.equals(assetType)) {
+ return new ResourceAssetInfo().subCategory("Network Service");
+ }
+
+ if (AssetType.SERVICES.equals(assetType)) {
+ return new ServiceAssetInfo().distributionStatus("DISTRIBUTED");
+ }
+
+ return new AssetInfo();
+ }
+
+ private String getToscaModelUrl(final String filename, final AssetType assetType) {
+ return CATALOG_URL + FORWARD_SLASH + assetType.toString().toLowerCase() + FORWARD_SLASH + filename
+ + "/toscaModel";
+ }
+
+ private String getFilenameWithoutExtension(final String filename) {
+ return filename.substring(0, filename.lastIndexOf('.'));
+ }
+
+ private String getFilenameWithoutExtension(final Path file) {
+ return getFilenameWithoutExtension(file.getFileName().toString());
+ }
+
+ private Optional<InputStream> getInputStream(final String csarId, final AssetType assetType) throws IOException {
+ final Path filePath = Paths.get(resourceLocation, csarId + DOT_CSAR);
+ if (Files.exists(filePath)) {
+ LOGGER.info("Found csar on file system using path: {}", filePath);
+ return Optional.of(Files.newInputStream(filePath));
+ }
+ LOGGER.warn("Couldn't find file on file system '{}', will search it in classpath", filePath);
+
+ final String path = MAIN_RESOURCE_FOLDER + assetType.toString() + FORWARD_SLASH + csarId + DOT_CSAR;
+ final ClassPathResource classPathResource = getClassPathResource(path);
+ if (classPathResource.exists()) {
+ LOGGER.info("Found csar in classpath using path: {}", path);
+ return Optional.of(classPathResource.getInputStream());
+ }
+
+ LOGGER.error("Couldn't find csar in classpath ....");
+ return Optional.empty();
+ }
+
+ private ClassPathResource getClassPathResource(final String path) {
+ return new ClassPathResource(path, this.getClass());
+ }
+
+}