Adding endpoints to SDC simulator
[integration/csit.git] / plans / so / integration-etsi-testing / so-simulators / sdc-simulator / src / main / java / org / onap / so / sdcsimulator / providers / AssetProviderImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *   Copyright (C) 2019 Nordix Foundation.
4  * ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *  SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.sdcsimulator.providers;
22
23 import static org.onap.so.sdcsimulator.utils.Constants.CATALOG_URL;
24 import static org.onap.so.sdcsimulator.utils.Constants.DOT_CSAR;
25 import static org.onap.so.sdcsimulator.utils.Constants.DOT_JSON;
26 import static org.onap.so.sdcsimulator.utils.Constants.FORWARD_SLASH;
27 import static org.onap.so.sdcsimulator.utils.Constants.MAIN_RESOURCE_FOLDER;
28 import static org.onap.so.sdcsimulator.utils.Constants.WILD_CARD_REGEX;
29 import static org.springframework.core.io.support.ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX;
30 import java.io.File;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.nio.file.DirectoryStream;
34 import java.nio.file.Files;
35 import java.nio.file.Path;
36 import java.nio.file.Paths;
37 import java.util.HashSet;
38 import java.util.Optional;
39 import java.util.Set;
40 import org.onap.so.sdcsimulator.models.AssetInfo;
41 import org.onap.so.sdcsimulator.models.AssetType;
42 import org.onap.so.sdcsimulator.models.Metadata;
43 import org.onap.so.sdcsimulator.models.ResourceAssetInfo;
44 import org.onap.so.sdcsimulator.models.ServiceAssetInfo;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47 import org.springframework.beans.factory.annotation.Autowired;
48 import org.springframework.beans.factory.annotation.Value;
49 import org.springframework.core.io.ClassPathResource;
50 import org.springframework.core.io.Resource;
51 import org.springframework.core.io.support.ResourcePatternResolver;
52 import org.springframework.stereotype.Service;
53 import org.springframework.util.StreamUtils;
54 import com.fasterxml.jackson.databind.DeserializationFeature;
55 import com.fasterxml.jackson.databind.ObjectMapper;
56
57 /**
58  * @author Waqas Ikram (waqas.ikram@est.tech)
59  */
60 @Service
61 public class AssetProviderImpl implements AssetProvider {
62
63     private static final Logger LOGGER = LoggerFactory.getLogger(AssetProvider.class);
64
65     private final ObjectMapper mapper =
66             new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);;
67
68     private final String resourceLocation;
69
70     private final ResourcePatternResolver resourcePatternResolver;
71
72     @Autowired
73     public AssetProviderImpl(@Value("${sdc.resource.location:/app/csars/}") final String resourceLocation,
74             final ResourcePatternResolver resourcePatternResolver) {
75         this.resourceLocation = resourceLocation;
76         this.resourcePatternResolver = resourcePatternResolver;
77     }
78
79     @Override
80     public Optional<byte[]> getAsset(final String csarId, final AssetType assetType) {
81         try {
82             final Optional<InputStream> optionalInputStream = getInputStream(csarId, assetType);
83             if (optionalInputStream.isPresent()) {
84                 return Optional.of(StreamUtils.copyToByteArray(optionalInputStream.get()));
85             }
86         } catch (final IOException ioException) {
87             LOGGER.warn("Unable to create file stream ...", ioException);
88         }
89
90         return Optional.empty();
91     }
92
93     @Override
94     public Set<AssetInfo> getAssetInfo(final AssetType assetType) {
95         final Set<AssetInfo> result = new HashSet<>();
96
97         final Path dir = Paths.get(resourceLocation).resolve(assetType.toString());
98         if (Files.exists(dir)) {
99             try (final DirectoryStream<Path> stream = Files.newDirectoryStream(dir, WILD_CARD_REGEX + DOT_CSAR)) {
100                 for (final Path entry : stream) {
101                     final String filename = getFilenameWithoutExtension(entry);
102                     result.add(getAssetInfo(assetType, filename, entry));
103                 }
104             } catch (final IOException ioException) {
105                 LOGGER.error("Unable to find assetInfo on filesystem", ioException);
106             }
107         }
108
109         try {
110             final String classPathdir = MAIN_RESOURCE_FOLDER + assetType.toString() + FORWARD_SLASH;
111             final String csarFileLocationPattern = CLASSPATH_ALL_URL_PREFIX + classPathdir + WILD_CARD_REGEX + DOT_CSAR;
112             final Resource[] resources = resourcePatternResolver.getResources(csarFileLocationPattern);
113             if (resources != null) {
114
115                 for (final Resource resource : resources) {
116                     final String filename = getFilenameWithoutExtension(resource.getFilename());
117                     result.add(getAssetInfo(assetType, filename, resource));
118                 }
119             }
120
121         } catch (final IOException ioException) {
122             LOGGER.error("Unable to find assetInfo in classpath", ioException);
123         }
124
125         return result;
126     }
127
128     @Override
129     public Optional<Metadata> getMetadata(final String csarId, final AssetType assetType) {
130         final Path dir = Paths.get(resourceLocation).resolve(assetType.toString());
131         final Path metadataFilePath = dir.resolve(csarId + DOT_JSON);
132         try {
133             if (Files.exists(metadataFilePath)) {
134                 LOGGER.info("Found metadata file on file system using path: {}", metadataFilePath);
135
136                 return Optional.of(mapper.readValue(metadataFilePath.toFile(), Metadata.class));
137
138             }
139         } catch (final IOException ioException) {
140             LOGGER.error("Unable to find metadata file on filesystem", ioException);
141         }
142
143
144         try {
145             final String path = MAIN_RESOURCE_FOLDER + assetType.toString() + FORWARD_SLASH + csarId + DOT_JSON;
146             LOGGER.warn("Couldn't find metadata file on file system '{}', will search it in classpath", path);
147             final ClassPathResource classPathResource = getClassPathResource(path);
148             if (classPathResource.exists()) {
149                 LOGGER.info("Found metadata file in classpath using path: {}", path);
150                 return Optional.of(mapper.readValue(classPathResource.getInputStream(), Metadata.class));
151             }
152         } catch (final IOException ioException) {
153             LOGGER.error("Unable to find metadata file in classpath", ioException);
154         }
155         LOGGER.error("Couldn't find metadata file in classpath ....");
156         return Optional.empty();
157     }
158
159     private AssetInfo getAssetInfo(final AssetType assetType, final String filename, final Resource resource)
160             throws IOException {
161         final Resource jsonResource = resource.createRelative(filename + DOT_JSON);
162
163         if (jsonResource != null && jsonResource.exists()) {
164             final AssetInfo assetInfo = getJsonAssetInfo(assetType, jsonResource);
165             assetInfo.setUuid(filename);
166             assetInfo.setToscaModelUrl(getToscaModelUrl(filename, assetType));
167             LOGGER.info("Found AssetInfo file in classpath: {}", assetInfo);
168             return assetInfo;
169
170         }
171
172         final AssetInfo assetInfo = getAssetInfo(filename, assetType);
173         LOGGER.info("Returning AssetInfo: {}", assetInfo);
174         return assetInfo;
175
176     }
177
178     private AssetInfo getAssetInfo(final AssetType assetType, final String filename, final Path entry)
179             throws IOException {
180         final Path assetJsonFilePath = entry.getParent().resolve(filename + DOT_JSON);
181         if (Files.exists(assetJsonFilePath)) {
182             final AssetInfo assetInfo = getJsonAssetInfo(assetType, assetJsonFilePath.toFile());
183             assetInfo.setUuid(filename);
184             assetInfo.setToscaModelUrl(getToscaModelUrl(filename, assetType));
185             LOGGER.info("Found AssetInfo file on file system: {}", assetInfo);
186             return assetInfo;
187
188         }
189         final AssetInfo assetInfo = getAssetInfo(filename, assetType);
190         LOGGER.info("Returning AssetInfo: {}", assetInfo);
191         return assetInfo;
192     }
193
194
195     private AssetInfo getJsonAssetInfo(final AssetType assetType, final Resource jsonResource) throws IOException {
196         if (AssetType.RESOURCES.equals(assetType)) {
197             return mapper.readValue(jsonResource.getInputStream(), ResourceAssetInfo.class);
198         }
199
200         if (AssetType.SERVICES.equals(assetType)) {
201             return mapper.readValue(jsonResource.getInputStream(), ServiceAssetInfo.class);
202         }
203
204         return mapper.readValue(jsonResource.getInputStream(), AssetInfo.class);
205     }
206
207
208     private AssetInfo getJsonAssetInfo(final AssetType assetType, final File file) throws IOException {
209         if (AssetType.RESOURCES.equals(assetType)) {
210             return mapper.readValue(file, ResourceAssetInfo.class);
211         }
212
213         if (AssetType.SERVICES.equals(assetType)) {
214             return mapper.readValue(file, ServiceAssetInfo.class);
215         }
216
217         return mapper.readValue(file, AssetInfo.class);
218     }
219
220     private AssetInfo getAssetInfo(final String filename, final AssetType assetType) {
221         return getAssetInfoObject(assetType).uuid(filename).invariantUuid(filename).name(filename).version("1.0")
222                 .toscaModelUrl(getToscaModelUrl(filename, assetType)).category("Generic").lifecycleState("CERTIFIED")
223                 .lastUpdaterUserId("SDC_SIMULATOR");
224     }
225
226     private AssetInfo getAssetInfoObject(final AssetType assetType) {
227         if (AssetType.RESOURCES.equals(assetType)) {
228             return new ResourceAssetInfo().subCategory("Network Service");
229         }
230
231         if (AssetType.SERVICES.equals(assetType)) {
232             return new ServiceAssetInfo().distributionStatus("DISTRIBUTED");
233         }
234
235         return new AssetInfo();
236     }
237
238     private String getToscaModelUrl(final String filename, final AssetType assetType) {
239         return CATALOG_URL + FORWARD_SLASH + assetType.toString().toLowerCase() + FORWARD_SLASH + filename
240                 + "/toscaModel";
241     }
242
243     private String getFilenameWithoutExtension(final String filename) {
244         return filename.substring(0, filename.lastIndexOf('.'));
245     }
246
247     private String getFilenameWithoutExtension(final Path file) {
248         return getFilenameWithoutExtension(file.getFileName().toString());
249     }
250
251     private Optional<InputStream> getInputStream(final String csarId, final AssetType assetType) throws IOException {
252         final Path filePath = Paths.get(resourceLocation, csarId + DOT_CSAR);
253         if (Files.exists(filePath)) {
254             LOGGER.info("Found csar on file system using path: {}", filePath);
255             return Optional.of(Files.newInputStream(filePath));
256         }
257         LOGGER.warn("Couldn't find file on file system '{}', will search it in classpath", filePath);
258
259         final String path = MAIN_RESOURCE_FOLDER + assetType.toString() + FORWARD_SLASH + csarId + DOT_CSAR;
260         final ClassPathResource classPathResource = getClassPathResource(path);
261         if (classPathResource.exists()) {
262             LOGGER.info("Found csar in classpath using path: {}", path);
263             return Optional.of(classPathResource.getInputStream());
264         }
265
266         LOGGER.error("Couldn't find csar in classpath ....");
267         return Optional.empty();
268     }
269
270     private ClassPathResource getClassPathResource(final String path) {
271         return new ClassPathResource(path, this.getClass());
272     }
273
274 }