7ac0fa3981471cf56981401100eb0a98baaaefbf
[vid.git] / vid-app-common / src / main / java / org / onap / vid / asdc / rest / RestfulAsdcClient.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * VID
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.vid.asdc.rest;
22
23 import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
24 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
25 import org.onap.portalsdk.core.util.SystemProperties;
26 import org.onap.vid.asdc.AsdcCatalogException;
27 import org.onap.vid.asdc.AsdcClient;
28 import org.onap.vid.asdc.beans.Artifact;
29 import org.onap.vid.asdc.beans.Resource;
30 import org.onap.vid.asdc.beans.Service;
31 import org.onap.vid.asdc.parser.ToscaParserImpl;
32 import org.onap.vid.model.ModelConstants;
33 import org.onap.vid.properties.VidProperties;
34
35 import javax.ws.rs.NotFoundException;
36 import javax.ws.rs.ProcessingException;
37 import javax.ws.rs.WebApplicationException;
38 import javax.ws.rs.client.Client;
39 import javax.ws.rs.client.ResponseProcessingException;
40 import javax.ws.rs.client.WebTarget;
41 import javax.ws.rs.core.GenericType;
42 import javax.ws.rs.core.MediaType;
43 import javax.ws.rs.core.MultivaluedHashMap;
44 import java.io.IOException;
45 import java.io.InputStream;
46 import java.net.URI;
47 import java.nio.file.Files;
48 import java.nio.file.Path;
49 import java.nio.file.StandardCopyOption;
50 import java.text.DateFormat;
51 import java.text.SimpleDateFormat;
52 import java.util.Collection;
53 import java.util.Collections;
54 import java.util.Map;
55 import java.util.Map.Entry;
56 import java.util.UUID;
57
58 import static org.onap.vid.utils.Logging.getHttpServletRequest;
59 import static org.onap.vid.utils.Logging.requestIdHeaderKey;
60 /**
61  * The Class RestfulAsdcClient.
62  */
63 @SuppressWarnings("Duplicates")
64 public class RestfulAsdcClient implements AsdcClient {
65
66
67     /**
68      * The Class Builder.
69      */
70     public static class Builder {
71
72         /**
73          * The client.
74          */
75         private final Client client;
76
77         /**
78          * The uri.
79          */
80         private final URI uri;
81
82         /**
83          * The auth.
84          */
85         private String auth = null;
86
87         /**
88          * Instantiates a new builder.
89          *
90          * @param client the client
91          * @param uri    the uri
92          */
93         public Builder(Client client, URI uri) {
94             this.client = client;
95             this.client.register(JacksonJsonProvider.class);
96             this.uri = uri;
97         }
98
99         /**
100          * Auth.
101          *
102          * @param auth the auth
103          * @return the builder
104          */
105         public Builder auth(String auth) {
106             this.auth = auth;
107             return this;
108         }
109
110         /**
111          * Builds the.
112          *
113          * @return the restful asdc client
114          */
115         public RestfulAsdcClient build() {
116             return new RestfulAsdcClient(this);
117         }
118     }
119
120     /**
121      * The Constant LOG.
122      */
123     static final EELFLoggerDelegate LOG = EELFLoggerDelegate.getLogger(RestfulAsdcClient.class);
124
125     /**
126      * The Constant dateFormat.
127      */
128     final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
129
130     /**
131      * The client.
132      */
133     private final Client client;
134
135     /**
136      * The uri.
137      */
138     private final URI uri;
139
140     /**
141      * The common headers.
142      */
143     private final MultivaluedHashMap<String, Object> commonHeaders;
144
145     /**
146      * The auth.
147      */
148     private final String auth;
149
150     ToscaParserImpl p = new ToscaParserImpl();
151
152     /**
153      * Instantiates a new restful asdc client.
154      *
155      * @param builder the builder
156      */
157     RestfulAsdcClient(Builder builder) {
158         client = builder.client;
159         uri = builder.uri;
160         auth = builder.auth;
161
162         commonHeaders = new MultivaluedHashMap<String, Object>();
163         commonHeaders.put("Authorization", Collections.singletonList((Object) (auth)));
164         commonHeaders.put("X-ECOMP-InstanceID", Collections.singletonList((Object) (SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME))));
165     }
166
167     private Path createTmpFile(InputStream csarInputStream) throws AsdcCatalogException {
168         final Path csarFile;
169         try {
170             csarFile = Files.createTempFile("csar", ".zip");
171             Files.copy(csarInputStream, csarFile, StandardCopyOption.REPLACE_EXISTING);
172         } catch (IOException e) {
173             throw new AsdcCatalogException("Caught IOException while creating CSAR", e);
174         }
175         return csarFile;
176     }
177
178     /**
179      * Gets the client.
180      *
181      * @return the client
182      */
183     private Client getClient() {
184         return client;
185     }
186
187     /* (non-Javadoc)
188      * @see org.onap.vid.asdc.AsdcClient#getResource(java.util.UUID)
189      */
190     public Resource getResource(UUID uuid) throws AsdcCatalogException {
191
192         String path = VidProperties.getPropertyWithDefault(ModelConstants.ASDC_RESOURCE_API_PATH, ModelConstants.DEFAULT_ASDC_RESOURCE_API_PATH);
193         try {
194             return getClient()
195                     .target(uri)
196                     .path(path + "/" + uuid.toString() + "/metadata")
197                     .request(MediaType.APPLICATION_JSON_TYPE)
198                     .headers(commonHeaders)
199                     .header("Content-Type", MediaType.APPLICATION_JSON)
200                     .header(requestIdHeaderKey, getHttpServletRequest().getHeader(requestIdHeaderKey))
201                     .get(Resource.class);
202         } catch (ResponseProcessingException e) {
203             //Couldn't convert response to Java type
204             throw new AsdcCatalogException("SDC response could not be processed", e);
205         } catch (ProcessingException e) {
206             //IO problems during request
207             throw new AsdcCatalogException("Failed to get a response from SDC service", e);
208         } catch (WebApplicationException e) {
209             //Web service returned data, but the response status wasn't a good one (i.e. non 2xx)
210             throw new AsdcCatalogException(e);
211         }
212     }
213
214     /* (non-Javadoc)
215      * @see org.onap.vid.asdc.AsdcClient#getResourceArtifact(java.util.UUID, java.util.UUID)
216      */
217     public Artifact getResourceArtifact(UUID resourceUuid, UUID artifactUuid) throws AsdcCatalogException {
218         String path = VidProperties.getPropertyWithDefault(ModelConstants.ASDC_RESOURCE_API_PATH, ModelConstants.DEFAULT_ASDC_RESOURCE_API_PATH);
219         try {
220             return getClient()
221                     .target(uri)
222                     .path(path + "/" + resourceUuid + "/artifacts/" + artifactUuid)
223                     .request(MediaType.APPLICATION_JSON_TYPE)
224                     .headers(commonHeaders)
225                     .header("Content-Type", MediaType.APPLICATION_JSON)
226                     .header(requestIdHeaderKey, getHttpServletRequest().getHeader(requestIdHeaderKey))
227                     .get(Artifact.class);
228         } catch (ResponseProcessingException e) {
229             //Couldn't convert response to Java type
230             throw new AsdcCatalogException("SDC response could not be processed", e);
231         } catch (ProcessingException e) {
232             //IO problems during request
233             throw new AsdcCatalogException("Failed to get a response from SDC service", e);
234         } catch (WebApplicationException e) {
235             //Web service returned data, but the response status wasn't a good one (i.e. non 2xx)
236             throw new AsdcCatalogException(e);
237         }
238     }
239
240     /* (non-Javadoc)
241      * @see org.onap.vid.asdc.AsdcClient#getResources()
242      */
243     public Collection<Resource> getResources() throws AsdcCatalogException {
244         String path = VidProperties.getPropertyWithDefault(ModelConstants.ASDC_RESOURCE_API_PATH, ModelConstants.DEFAULT_ASDC_RESOURCE_API_PATH);
245         try {
246             return getClient()
247                     .target(uri)
248                     .path(path)
249                     .request(MediaType.APPLICATION_JSON_TYPE)
250                     .headers(commonHeaders)
251                     .header("Content-Type", MediaType.APPLICATION_JSON)
252                     .header(requestIdHeaderKey, getHttpServletRequest().getHeader(requestIdHeaderKey))
253                     .get(new GenericType<Collection<Resource>>() {
254                     });
255         } catch (ResponseProcessingException e) {
256             //Couldn't convert response to Java type
257             throw new AsdcCatalogException("SDC response could not be processed", e);
258         } catch (ProcessingException e) {
259             //IO problems during request
260             throw new AsdcCatalogException("Failed to get a response from SDC service", e);
261         } catch (WebApplicationException e) {
262             //Web service returned data, but the response status wasn't a good one (i.e. non 2xx)
263             throw new AsdcCatalogException(e);
264         }
265     }
266
267     /* (non-Javadoc)
268      * @see org.onap.vid.asdc.AsdcClient#getResources(java.util.Map)
269      */
270     public Collection<Resource> getResources(Map<String, String[]> filter) throws AsdcCatalogException {
271         String path = VidProperties.getPropertyWithDefault(ModelConstants.ASDC_RESOURCE_API_PATH, ModelConstants.DEFAULT_ASDC_RESOURCE_API_PATH);
272         WebTarget target = getClient()
273                 .target(uri)
274                 .path(path);
275
276         for (Entry<String, String[]> filterEntry : filter.entrySet()) {
277             target = target.queryParam(filterEntry.getKey(), (Object[]) filterEntry.getValue());
278         }
279
280         try {
281             return target.request()
282                     .accept(MediaType.APPLICATION_JSON_TYPE)
283                     .headers(commonHeaders)
284                     .header("Content-Type", MediaType.APPLICATION_JSON)
285                     .header(requestIdHeaderKey, getHttpServletRequest().getHeader(requestIdHeaderKey))
286                     .get(new GenericType<Collection<Resource>>() {
287                     });
288         } catch (ResponseProcessingException e) {
289             //Couldn't convert response to Java type
290             throw new AsdcCatalogException("SDC response could not be processed", e);
291         } catch (ProcessingException e) {
292             //IO problems during request
293             throw new AsdcCatalogException("Failed to get a response from SDC service", e);
294         } catch (NotFoundException e) {
295             throw e;
296         } catch (WebApplicationException e) {
297             //Web service returned data, but the response status wasn't a good one (i.e. non 2xx)
298             throw new AsdcCatalogException(e);
299         }
300     }
301
302     /* (non-Javadoc)
303      * @see org.onap.vid.asdc.AsdcClient#getResourceToscaModel(java.util.UUID)
304      */
305     public Path getResourceToscaModel(UUID resourceUuid) throws AsdcCatalogException {
306         String path = VidProperties.getPropertyWithDefault(ModelConstants.ASDC_RESOURCE_API_PATH, ModelConstants.DEFAULT_ASDC_RESOURCE_API_PATH);
307         try (final InputStream csarInputStream = (InputStream) getClient()
308                 .target(uri)
309                 .path(path + "/" + resourceUuid + "/toscaModel")
310                 .request(MediaType.APPLICATION_OCTET_STREAM_TYPE)
311                 .headers(commonHeaders)
312                 .header("Content-Type", MediaType.APPLICATION_OCTET_STREAM)
313                 .header(requestIdHeaderKey, getHttpServletRequest().getHeader(requestIdHeaderKey))
314                 .get(InputStream.class)) {
315
316             return getToscaCsar(csarInputStream);
317         } catch (IOException e) {
318             throw new AsdcCatalogException("Failed to retrieve resource TOSCA model from SDC", e);
319         }
320     }
321
322     /* (non-Javadoc)
323      * @see org.onap.vid.asdc.AsdcClient#getService(java.util.UUID)
324      */
325     public Service getService(UUID uuid) throws AsdcCatalogException {
326
327         String path = VidProperties.getPropertyWithDefault(ModelConstants.ASDC_SVC_API_PATH, ModelConstants.DEFAULT_ASDC_SVC_API_PATH);
328         try {
329             return getClient()
330                     .target(uri)
331                     .path(path + "/" + uuid.toString() + "/metadata")
332                     .request(MediaType.APPLICATION_JSON)
333                     .headers(commonHeaders)
334                     .header(requestIdHeaderKey, getHttpServletRequest().getHeader(requestIdHeaderKey))
335                     .get(Service.class);
336         } catch (ResponseProcessingException e) {
337             //Couldn't convert response to Java type
338             throw new AsdcCatalogException("SDC response could not be processed", e);
339         } catch (ProcessingException e) {
340             //IO problems during request
341             throw new AsdcCatalogException("Failed to get a response from SDC service", e);
342         } catch (WebApplicationException e) {
343             //Web service returned data, but the response status wasn't a good one (i.e. non 2xx)
344             throw new AsdcCatalogException(e);
345         }
346     }
347
348     /* (non-Javadoc)
349      * @see org.onap.vid.asdc.AsdcClient#getServiceArtifact(java.util.UUID, java.util.UUID)
350      */
351     public Artifact getServiceArtifact(UUID serviceUuid, UUID artifactUuid) throws AsdcCatalogException {
352         String path = VidProperties.getPropertyWithDefault(ModelConstants.ASDC_SVC_API_PATH, ModelConstants.DEFAULT_ASDC_SVC_API_PATH);
353
354         try {
355             return getClient()
356                     .target(uri)
357                     .path(path + "/" + serviceUuid + "/artifacts/" + artifactUuid)
358                     .request(MediaType.APPLICATION_JSON_TYPE)
359                     .headers(commonHeaders)
360                     .header("Content-Type", MediaType.APPLICATION_JSON)
361                     .header(requestIdHeaderKey, getHttpServletRequest().getHeader(requestIdHeaderKey))
362                     .get(Artifact.class);
363         } catch (ResponseProcessingException e) {
364             //Couldn't convert response to Java type
365             throw new AsdcCatalogException("SDC response could not be processed", e);
366         } catch (ProcessingException e) {
367             //IO problems during request
368             throw new AsdcCatalogException("Failed to get a response from SDC service", e);
369         } catch (WebApplicationException e) {
370             //Web service returned data, but the response status wasn't a good one (i.e. non 2xx)
371             throw new AsdcCatalogException(e);
372         }
373     }
374
375     /* (non-Javadoc)
376      * @see org.onap.vid.asdc.AsdcClient#getServices()
377      */
378     public Collection<Service> getServices() throws AsdcCatalogException {
379         String path = VidProperties.getPropertyWithDefault(ModelConstants.ASDC_SVC_API_PATH, ModelConstants.DEFAULT_ASDC_SVC_API_PATH);
380         try {
381             return getClient()
382                     .target(uri)
383                     .path(path)
384                     .request()
385                     .accept(MediaType.APPLICATION_JSON_TYPE)
386                     .headers(commonHeaders)
387                     .header("Content-Type", MediaType.APPLICATION_JSON)
388                     .header(requestIdHeaderKey, getHttpServletRequest().getHeader(requestIdHeaderKey))
389                     .get(new GenericType<Collection<Service>>() {
390                     });
391         } catch (ResponseProcessingException e) {
392             //Couldn't convert response to Java type
393             throw new AsdcCatalogException("SDC response could not be processed", e);
394         } catch (ProcessingException e) {
395             //IO problems during request
396             throw new AsdcCatalogException("Failed to get a response from SDC service", e);
397         } catch (WebApplicationException e) {
398             //Web service returned data, but the response status wasn't a good one (i.e. non 2xx)
399             throw new AsdcCatalogException(e);
400         }
401     }
402
403     /* (non-Javadoc)
404      * @see org.onap.vid.asdc.AsdcClient#getServices(java.util.Map)
405      */
406     public Collection<Service> getServices(Map<String, String[]> filter) throws AsdcCatalogException {
407
408         String path = VidProperties.getPropertyWithDefault(ModelConstants.ASDC_SVC_API_PATH, ModelConstants.DEFAULT_ASDC_SVC_API_PATH);
409         WebTarget target = getClient()
410                 .target(uri)
411                 .path(path);
412
413
414         for (Entry<String, String[]> filterEntry : filter.entrySet()) {
415             target = target.queryParam(filterEntry.getKey(), (Object[]) filterEntry.getValue());
416         }
417
418         try {
419             return target.request()
420                     .accept(MediaType.APPLICATION_JSON_TYPE)
421                     .headers(commonHeaders)
422                     .header("Content-Type", MediaType.APPLICATION_JSON)
423                     .header(requestIdHeaderKey, getHttpServletRequest().getHeader(requestIdHeaderKey))
424                     .get(new GenericType<Collection<Service>>() {
425                     });
426         } catch (ResponseProcessingException e) {
427             //Couldn't convert response to Java type
428             throw new AsdcCatalogException("SDC response could not be processed", e);
429         } catch (ProcessingException e) {
430             //IO problems during request
431             throw new AsdcCatalogException("Failed to get a response from SDC service", e);
432         } catch (NotFoundException e) {
433             throw e;
434         } catch (WebApplicationException e) {
435             //Web service returned data, but the response status wasn't a good one (i.e. non 2xx)
436             throw new AsdcCatalogException(e);
437         }
438     }
439
440
441     /* (non-Javadoc)
442      * @see org.onap.vid.asdc.AsdcClient#getServiceToscaModel(java.util.UUID)
443      */
444     public Path getServiceToscaModel(UUID serviceUuid) throws AsdcCatalogException {
445         String path = VidProperties.getPropertyWithDefault(ModelConstants.ASDC_SVC_API_PATH, ModelConstants.DEFAULT_ASDC_SVC_API_PATH);
446         try {
447             final InputStream csarInputStream = (InputStream) getClient()
448                     .target(uri)
449                     .path(path + "/" + serviceUuid + "/toscaModel")
450                     .request(MediaType.APPLICATION_OCTET_STREAM_TYPE)
451                     .headers(commonHeaders)
452                     .header("Content-Type", MediaType.APPLICATION_OCTET_STREAM)
453                     .header(requestIdHeaderKey, getHttpServletRequest().getHeader(requestIdHeaderKey))
454                     .get(InputStream.class);
455
456
457             return getToscaCsar(csarInputStream);
458         } catch (ResponseProcessingException e) {
459             //Couldn't convert response to Java type
460             throw new AsdcCatalogException("SDC response could not be processed", e);
461         } catch (ProcessingException e) {
462             //IO problems during request
463             throw new AsdcCatalogException("Failed to get a response from SDC service", e);
464         } catch (WebApplicationException e) {
465             //Web service returned data, but the response status wasn't a good one (i.e. non 2xx)
466             throw new AsdcCatalogException(e);
467         }
468     }
469
470
471     /**
472      * Gets the tosca model.
473      *
474      * @param csarInputStream the csar input stream
475      * @return the tosca model
476      * @throws AsdcCatalogException the asdc catalog exception
477      */
478     private Path getToscaCsar(InputStream csarInputStream) throws AsdcCatalogException {
479         return createTmpFile(csarInputStream);
480     }
481 }
482