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