108d9c06aa7683ee65e3bf2e1003eb2a1f568270
[vid.git] / vid-app-common / src / main / java / org / onap / vid / asdc / local / LocalAsdcClient.java
1 package org.onap.vid.asdc.local;
2
3 import org.codehaus.jackson.JsonParseException;
4 import org.codehaus.jackson.map.JsonMappingException;
5 import org.codehaus.jackson.map.ObjectMapper;
6 import org.json.JSONArray;
7 import org.json.JSONObject;
8 import org.onap.vid.asdc.AsdcCatalogException;
9 import org.onap.vid.asdc.AsdcClient;
10 import org.onap.vid.asdc.beans.Service;
11 import org.onap.vid.asdc.beans.tosca.ToscaCsar;
12 import org.onap.vid.asdc.beans.tosca.ToscaMeta;
13 import org.onap.vid.asdc.beans.tosca.ToscaModel;
14 import org.onap.vid.exceptions.GenericUncheckedException;
15 import org.yaml.snakeyaml.Yaml;
16
17 import java.io.File;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.UnsupportedEncodingException;
21 import java.net.URLDecoder;
22 import java.nio.file.Files;
23 import java.nio.file.Path;
24 import java.nio.file.Paths;
25 import java.nio.file.StandardCopyOption;
26 import java.util.Map;
27 import java.util.UUID;
28 import java.util.zip.ZipFile;
29
30 /**
31  * The Class LocalAsdcClient.
32  */
33 public class LocalAsdcClient implements AsdcClient {
34
35
36     public static final String SERVICES = "services";
37     /**
38      * The catalog.
39      */
40     private final JSONObject catalog;
41
42     /**
43      * The mapper.
44      */
45     private final ObjectMapper mapper;
46
47     /**
48      * Instantiates a new in local sdc client.
49      *
50      * @param builder the builder
51      */
52     public LocalAsdcClient(org.onap.vid.asdc.local.LocalAsdcClient.Builder builder) {
53         catalog = builder.catalog;
54         mapper = builder.mapper;
55     }
56
57     /**
58      * Gets the catalog.
59      *
60      * @return the catalog
61      */
62     private JSONObject getCatalog() {
63         return catalog;
64     }
65
66     /**
67      * Gets the mapper.
68      *
69      * @return the mapper
70      */
71     private ObjectMapper getMapper() {
72         return mapper;
73     }
74
75     /**
76      * Convert.
77      *
78      * @param <T>   the generic type
79      * @param json  the json
80      * @param clazz the clazz
81      * @return the t
82      * @throws AsdcCatalogException the sdc catalog exception
83      */
84     private <T> T convert(JSONObject json, Class<T> clazz) throws AsdcCatalogException {
85         try {
86             return getMapper().readValue(json.toString(), clazz);
87         } catch (JsonParseException e) {
88             throw new AsdcCatalogException("Failed to parse SDC response (bad data)", e);
89         } catch (JsonMappingException e) {
90             throw new AsdcCatalogException("Failed to map SDC response to internal VID data structure(s)", e);
91         } catch (IOException e) {
92             throw new AsdcCatalogException("Failed to get a response from SDC", e);
93         }
94     }
95
96     /* (non-Javadoc)
97      * @see org.onap.vid.asdc.AsdcClient#getService(java.util.UUID)
98      */
99     public Service getService(UUID uuid) throws AsdcCatalogException {
100
101         JSONObject serviceJsonObject = null;
102         final JSONArray categoryJsonArray = getCatalog().getJSONArray(SERVICES);
103
104         for (int i = 0; i < categoryJsonArray.length(); i++) {
105             JSONObject jsonServiceObject = categoryJsonArray.getJSONObject(i);
106             if (jsonServiceObject.get("uuid").equals(uuid.toString())) {
107                 serviceJsonObject = jsonServiceObject;
108                 break;
109             }
110         }
111
112         if (serviceJsonObject != null)
113             return convert(serviceJsonObject, Service.class);
114         else return null;
115     }
116
117     /* (non-Javadoc)
118      * @see org.onap.vid.asdc.AsdcClient#getServiceToscaModel(java.util.UUID)
119      */
120     public Path getServiceToscaModel(UUID serviceUuid) throws AsdcCatalogException {
121
122         String toscaModelURL = null;
123
124         final JSONArray categoryJsonArray = getCatalog().getJSONArray(SERVICES);
125
126         for (int i = 0; i < categoryJsonArray.length(); i++) {
127
128             JSONObject jsonServiceObject = categoryJsonArray.getJSONObject(i);
129             if (jsonServiceObject.get("uuid").equals(serviceUuid.toString())) {
130                 toscaModelURL = jsonServiceObject.getString("toscaModelURL");
131             }
132         }
133         if (toscaModelURL == null) {
134             return null;
135         }
136         ClassLoader classLoader = getClass().getClassLoader();
137         File file = new File(classLoader.getResource(toscaModelURL).getFile());
138
139         try {
140             //using URLDecoder.decode to convert special characters from %XX to real character
141             //see https://stackoverflow.com/questions/32251251/java-classloader-getresource-with-special-characters-in-path
142             return Paths.get(URLDecoder.decode(file.getPath(), "UTF-8"));
143         } catch (UnsupportedEncodingException e) {
144             throw new GenericUncheckedException(e);
145         }
146     }
147
148     /**
149      * Gets the tosca model.
150      *
151      * @param csarInputStream the csar input stream
152      * @return the tosca model
153      * @throws AsdcCatalogException the asdc catalog exception
154      */
155     private ToscaCsar getToscaModel(InputStream csarInputStream) throws AsdcCatalogException {
156         final Path csarFile;
157
158         try {
159             csarFile = Files.createTempFile("csar", ".zip");
160             Files.copy(csarInputStream, csarFile, StandardCopyOption.REPLACE_EXISTING);
161         } catch (IOException e) {
162             throw new AsdcCatalogException("Caught IOException while creating CSAR", e);
163         }
164
165         try (final ZipFile csar = new ZipFile(csarFile.toFile())) {
166
167             final InputStream toscaMetaStream = csar.getInputStream(csar.getEntry("TOSCA-Metadata/TOSCA.meta"));
168             final ToscaMeta toscaMeta = new ToscaMeta.Builder(toscaMetaStream).build();
169             final String entryDefinitions = toscaMeta.get("Entry-Definitions");
170             final InputStream toscaParentEntryYamlStream = csar.getInputStream(csar.getEntry(entryDefinitions));
171
172             final Yaml yaml = new Yaml();
173             final ToscaModel parentModel = yaml.loadAs(toscaParentEntryYamlStream, ToscaModel.class);
174
175             final ToscaCsar.Builder csarBuilder = new ToscaCsar.Builder(parentModel);
176
177             for (Map<String, Map<String, String>> imports : parentModel.getImports()) {
178                 for (Map.Entry<String, Map<String, String>> entry : imports.entrySet()) {
179                     final InputStream toscaChildEntryYamlStream = csar.getInputStream(csar.getEntry("Definitions/" + entry.getValue().get("file")));
180                     final ToscaModel childModel = yaml.loadAs(toscaChildEntryYamlStream, ToscaModel.class);
181                     csarBuilder.addVnf(childModel);
182                 }
183             }
184
185             return csarBuilder.build();
186         } catch (IOException e) {
187             throw new AsdcCatalogException("Caught IOException while processing CSAR", e);
188         }
189     }
190
191     /**
192      * The Class Builder.
193      */
194     public static class Builder {
195
196         /**
197          * The catalog.
198          */
199         private JSONObject catalog = new JSONObject()
200                 .put("resources", new JSONObject())
201                 .put(SERVICES, new JSONObject());
202
203         /**
204          * The mapper.
205          */
206         private ObjectMapper mapper = new ObjectMapper();
207
208         /**
209          * Instantiates a new builder.
210          */
211         public Builder() {
212         }
213
214         /**
215          * Catalog.
216          *
217          * @param catalog the catalog
218          * @return the builder
219          */
220         public org.onap.vid.asdc.local.LocalAsdcClient.Builder catalog(JSONObject catalog) {
221             this.catalog = catalog;
222             return this;
223         }
224
225         /**
226          * Mapper.
227          *
228          * @param mapper the mapper
229          * @return the builder
230          */
231         public org.onap.vid.asdc.local.LocalAsdcClient.Builder mapper(ObjectMapper mapper) {
232             this.mapper = mapper;
233             return this;
234         }
235
236         /**
237          * Builds the.
238          *
239          * @return the in local sdc client
240          */
241         public org.onap.vid.asdc.local.LocalAsdcClient build() {
242             return new org.onap.vid.asdc.local.LocalAsdcClient(this);
243         }
244     }
245
246 }