Implementation for TMF 633 API - POST /serviceSpecification
[externalapi/nbi.git] / src / main / java / org / onap / nbi / apis / servicecatalog / SdcClient.java
1 /**
2  * Copyright (c) 2018 Orange
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14
15 package org.onap.nbi.apis.servicecatalog;
16
17 import java.io.File;
18 import java.io.FileOutputStream;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.net.URI;
22 import java.nio.file.Files;
23 import java.nio.file.Path;
24 import java.nio.file.StandardCopyOption;
25 import java.util.*;
26 import java.util.Map.Entry;
27 import javax.annotation.PostConstruct;
28 import org.apache.commons.io.IOUtils;
29 import org.onap.nbi.OnapComponentsUrlPaths;
30 import org.onap.nbi.exceptions.BackendFunctionalException;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33 import org.springframework.beans.factory.annotation.Autowired;
34 import org.springframework.beans.factory.annotation.Value;
35 import org.springframework.http.HttpEntity;
36 import org.springframework.http.HttpHeaders;
37 import org.springframework.http.HttpMethod;
38 import org.springframework.http.HttpStatus;
39 import org.springframework.http.MediaType;
40 import org.springframework.http.ResponseEntity;
41 import org.springframework.stereotype.Service;
42 import org.springframework.util.MultiValueMap;
43 import org.springframework.web.client.ResourceAccessException;
44 import org.springframework.web.client.RestTemplate;
45 import org.springframework.web.util.UriComponentsBuilder;
46
47 /**
48  * @author user
49  *
50  */
51 @Service
52 public class SdcClient {
53
54     @Autowired
55     private RestTemplate restTemplate;
56
57     @Value("${sdc.host}")
58     private String sdcHost;
59
60     @Value("${sdc.header.ecompInstanceId}")
61     private String ecompInstanceId;
62
63     @Value("${sdc.header.authorization}")
64     private String sdcHeaderAuthorization;
65
66     private static final String HEADER_ECOMP_INSTANCE_ID = "x-ecomp-instanceid";
67     private static final String HEADER_AUTHORIZATION = "Authorization";
68     // changes for Post Implementation
69     private static final String USER_ID = "USER_ID";
70
71     private static final Logger LOGGER = LoggerFactory.getLogger(SdcClient.class);
72
73     private String sdcGetUrl;
74     private String sdcFindUrl;
75     private String sdcHealthCheck;
76
77     @PostConstruct
78     private void setUpAndLogSDCUrl() {
79         sdcGetUrl = new StringBuilder().append(sdcHost)
80                 .append(OnapComponentsUrlPaths.SDC_ROOT_URL + "/{id}" + OnapComponentsUrlPaths.SDC_GET_PATH).toString();
81         sdcFindUrl = new StringBuilder().append(sdcHost).append(OnapComponentsUrlPaths.SDC_ROOT_URL).toString();
82         sdcHealthCheck = new StringBuilder().append(sdcHost).append(OnapComponentsUrlPaths.SDC_HEALTH_CHECK).toString();
83
84         LOGGER.info("SDC GET url :  " + sdcGetUrl);
85         LOGGER.info("SDC FIND url :  " + sdcFindUrl);
86         LOGGER.info("SDC HealthCheck :  " + sdcHealthCheck);
87
88     }
89
90     public Map callGet(String id) {
91
92         String callUrl = sdcGetUrl.replace("{id}", id);
93         UriComponentsBuilder callURLFormated = UriComponentsBuilder.fromHttpUrl(callUrl);
94         ResponseEntity<Object> response = callSdc(callURLFormated.build().encode().toUri());
95         return (LinkedHashMap) response.getBody();
96
97     }
98
99     public List<LinkedHashMap> callFind(MultiValueMap<String, String> parametersMap) {
100
101         UriComponentsBuilder callURI = UriComponentsBuilder.fromHttpUrl(sdcFindUrl);
102         if (parametersMap != null) {
103             Map<String, String> stringStringMap = parametersMap.toSingleValueMap();
104             for (Entry<String, String> entry : stringStringMap.entrySet()) {
105                 if (!entry.getKey().equals("fields")) {
106                     callURI.queryParam(entry.getKey(), entry.getValue());
107                 }
108             }
109         }
110
111         ResponseEntity<Object> response = callSdc(callURI.build().encode().toUri());
112         return (List<LinkedHashMap>) response.getBody();
113
114     }
115
116     public LinkedHashMap callCheckConnectivity() {
117
118         UriComponentsBuilder callURI = UriComponentsBuilder.fromHttpUrl(sdcHealthCheck);
119         ResponseEntity<Object> response = callSdc(callURI.build().encode().toUri());
120         return (LinkedHashMap) response.getBody();
121
122     }
123
124     public File callGetWithAttachment(String toscaModelUrl) {
125         StringBuilder urlBuilder = new StringBuilder().append(sdcHost).append(toscaModelUrl);
126
127         UriComponentsBuilder callURI = UriComponentsBuilder.fromHttpUrl(urlBuilder.toString());
128
129         File directory = new File("temptoscafile");
130         if (!directory.exists()) {
131             directory.mkdir();
132         }
133
134         String fileName = "temptoscafile/" + System.currentTimeMillis() + "tosca.csar";
135         ResponseEntity<byte[]> response = callSdcWithAttachment(callURI.build().encode().toUri());
136         File toscaFile = new File(fileName);
137         try {
138             FileOutputStream toscaFileStream = new FileOutputStream(toscaFile);
139             if (response != null) {
140                 IOUtils.write(response.getBody(), toscaFileStream);
141             }
142             toscaFileStream.close();
143         } catch (IOException e) {
144             LOGGER.error("cannot get TOSCA File for url " + toscaModelUrl, e);
145         }
146         return toscaFile;
147
148     }
149
150     public Path getServiceToscaModel(String uuid) throws IOException {
151         StringBuilder urlBuilder = new StringBuilder().append(sdcHost).append(OnapComponentsUrlPaths.SDC_ROOT_URL)
152                 .append("/").append(uuid).append(OnapComponentsUrlPaths.SDC_TOSCA_PATH);
153
154         UriComponentsBuilder callURI = UriComponentsBuilder.fromHttpUrl(urlBuilder.toString());
155
156         InputStream inputStream = (InputStream) callSdc(callURI.build().encode().toUri()).getBody();
157
158         return createTmpFile(inputStream);
159     }
160     /**
161      *
162      * @param serviceCatalogObject
163      * @param userId
164      */
165     public Map callPost(HashMap<Object, Object> serviceCatalogObject, String userId) {
166         // post url is the same as find url
167         UriComponentsBuilder callURI = UriComponentsBuilder.fromHttpUrl(sdcFindUrl);
168         ResponseEntity<Object> response = callSdcForPost(callURI.build().encode().toUri(), serviceCatalogObject,
169                 userId);
170         // return (List<LinkedHashMap>) response.getBody();
171         return (LinkedHashMap) response.getBody();
172     }
173
174     private Path createTmpFile(InputStream csarInputStream) throws IOException {
175         Path csarFile = Files.createTempFile("csar", ".zip");
176         Files.copy(csarInputStream, csarFile, StandardCopyOption.REPLACE_EXISTING);
177
178         LOGGER.debug("Tosca file was saved at: {} ", csarFile.toAbsolutePath());
179
180         return csarFile;
181     }
182
183     private HttpEntity<String> buildRequestHeader() {
184         HttpHeaders httpHeaders = new HttpHeaders();
185         httpHeaders.setContentType(MediaType.APPLICATION_JSON);
186         httpHeaders.add(HEADER_ECOMP_INSTANCE_ID, ecompInstanceId);
187         httpHeaders.add(HEADER_AUTHORIZATION, sdcHeaderAuthorization);
188         return new HttpEntity<>("parameters", httpHeaders);
189     }
190
191     private ResponseEntity<Object> callSdc(URI callURI) {
192         ResponseEntity<Object> response =
193                 restTemplate.exchange(callURI, HttpMethod.GET, buildRequestHeader(), Object.class);
194
195         if (LOGGER.isDebugEnabled()) {
196             LOGGER.debug("response body : {} ", response.getBody().toString());
197         }
198         LOGGER.info("response status : {}", response.getStatusCodeValue());
199         loggDebugIfResponseKo(callURI.toString(), response);
200         return response;
201     }
202
203     private ResponseEntity<byte[]> callSdcWithAttachment(URI callURI) {
204         try {
205             ResponseEntity<byte[]> response =
206                     restTemplate.exchange(callURI, HttpMethod.GET, buildRequestHeader(), byte[].class);
207             LOGGER.info("response status : " + response.getStatusCodeValue());
208             if (LOGGER.isWarnEnabled() && !response.getStatusCode().equals(HttpStatus.OK)) {
209                 LOGGER.warn("HTTP call SDC on {} returns {} ", callURI.toString(), response.getStatusCodeValue());
210             }
211             return response;
212
213         } catch (BackendFunctionalException e) {
214             LOGGER.error("HTTP call SDC on {} error : {}", callURI.toString(), e);
215             return null;
216         }
217     }
218
219     private void loggDebugIfResponseKo(String callURI, ResponseEntity<Object> response) {
220         if (LOGGER.isWarnEnabled() && !response.getStatusCode().equals(HttpStatus.OK)) {
221             LOGGER.warn("HTTP call SDC on {} returns {} , {}", callURI, response.getStatusCodeValue(),
222                     response.getBody().toString());
223         }
224     }
225
226     //changes for Post implementation start
227     /**
228      *
229      * @param callURI
230      * @param obj
231      * @param userId
232      * @return
233      */
234     private ResponseEntity<Object> callSdcForPost(URI callURI, Object obj, String userId) {
235         ResponseEntity<Object> response = restTemplate.exchange(callURI, HttpMethod.POST,
236                 new HttpEntity<>(obj, buildRequestHeaderForPost(userId)), Object.class);
237
238         if (null == response) {
239             return null;
240         } else {
241
242             if (LOGGER.isDebugEnabled()) {
243                 LOGGER.debug("response body : {} ", response.getBody().toString());
244             }
245             LOGGER.info("response status : {}", response.getStatusCodeValue());
246             return response;
247         }
248
249     }
250     /**
251      *
252      * @param userId
253      * @return
254      */
255     private HttpHeaders buildRequestHeaderForPost(String userId) {
256         HttpHeaders httpHeaders = new HttpHeaders();
257
258         httpHeaders.setContentType(MediaType.APPLICATION_JSON);
259         httpHeaders.add(HEADER_ECOMP_INSTANCE_ID, ecompInstanceId);
260         httpHeaders.add(HEADER_AUTHORIZATION, sdcHeaderAuthorization);
261         httpHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
262         httpHeaders.add(USER_ID, userId);
263
264         return httpHeaders;
265     }
266
267 }