create custom spring aop annotation for logging
[so.git] / adapters / mso-sdnc-adapter / src / main / java / org / onap / so / adapters / sdnc / sdncrest / BPRestCallback.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
7  * ================================================================================
8  * Modifications Copyright (C) 2018 IBM.
9  * Modifications Copyright (c) 2019 Samsung
10  * ================================================================================
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  * 
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  * 
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.onap.so.adapters.sdnc.sdncrest;
26
27 import java.net.URI;
28 import javax.xml.bind.DatatypeConverter;
29 import org.onap.logging.filter.spring.SpringClientPayloadFilter;
30 import org.onap.so.adapters.sdnc.impl.Constants;
31 import org.onap.logging.filter.base.ErrorCode;
32 import org.onap.so.logger.LoggingAnchor;
33 import org.onap.so.logger.MessageEnum;
34 import org.onap.so.logging.jaxrs.filter.SOSpringClientFilter;
35 import org.onap.so.utils.CryptoUtils;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38 import org.springframework.beans.factory.annotation.Autowired;
39 import org.springframework.core.env.Environment;
40 import org.springframework.http.HttpEntity;
41 import org.springframework.http.HttpHeaders;
42 import org.springframework.http.HttpStatus;
43 import org.springframework.http.MediaType;
44 import org.springframework.http.ResponseEntity;
45 import org.springframework.http.client.BufferingClientHttpRequestFactory;
46 import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
47 import org.springframework.stereotype.Component;
48 import org.springframework.web.client.HttpStatusCodeException;
49 import org.springframework.web.client.RestTemplate;
50 import org.springframework.web.util.UriComponentsBuilder;
51
52 /**
53  * Sends asynchronous messages to the BPMN WorkflowMessage service.
54  */
55 @Component
56 public class BPRestCallback {
57     private static final Logger logger = LoggerFactory.getLogger(BPRestCallback.class);
58
59     private static final String CAMUNDA = "Camunda";
60     private static final String MSO_INTERNAL_ERROR = "MsoInternalError";
61     @Autowired
62     private Environment env;
63
64     /**
65      * Sends a message to the BPMN workflow message service. The URL path is constructed using the specified message
66      * type and correlator.
67      * 
68      * @param workflowMessageUrl the base BPMN WorkflowMessage URL
69      * @param messageType the message type
70      * @param correlator the message correlator
71      * @param message the JSON content
72      * @return true if the message was consumed successfully by the endpoint
73      */
74     public boolean send(String workflowMessageUrl, String messageType, String correlator, String message) {
75         logger.debug(getClass().getSimpleName() + ".send(" + "workflowMessageUrl=" + workflowMessageUrl
76                 + " messageType=" + messageType + " correlator=" + correlator + " message=" + message + ")");
77
78         while (workflowMessageUrl.endsWith("/")) {
79             workflowMessageUrl = workflowMessageUrl.substring(0, workflowMessageUrl.length() - 1);
80         }
81
82         String endpoint = workflowMessageUrl + "/" + SDNCAdapterUtils.encodeURLPathSegment(messageType) + "/"
83                 + SDNCAdapterUtils.encodeURLPathSegment(correlator);
84
85         return send(endpoint, message);
86     }
87
88     /**
89      * Sends a message to the BPMN workflow message service. The specified URL must have the message type and correlator
90      * already embedded in it.
91      * 
92      * @param url the endpoint URL
93      * @param message the JSON content
94      * @return true if the message was consumed successfully by the endpoint
95      */
96     public boolean send(String url, String message) {
97         logger.debug(getClass().getSimpleName() + ".send(" + "url=" + url + " message=" + message + ")");
98
99         logger.info(LoggingAnchor.THREE, MessageEnum.RA_CALLBACK_BPEL.toString(),
100                 message == null ? "[no content]" : message, CAMUNDA);
101         try {
102             int timeout = 60 * 1000;
103             RestTemplate restTemplate = setRestTemplate(timeout);
104
105             HttpHeaders headers = new HttpHeaders();
106             headers.setContentType(MediaType.APPLICATION_JSON);
107
108             boolean error = setAuthorizationHeader(headers);
109
110             HttpEntity<String> requestEntity = new HttpEntity<>(message, headers);
111             if (!error) {
112                 postRequest(restTemplate, url, requestEntity);
113             }
114             logger.info(LoggingAnchor.TWO, MessageEnum.RA_CALLBACK_BPEL_COMPLETE.toString(), CAMUNDA);
115             return true;
116         } catch (Exception e) {
117             logger.error(LoggingAnchor.FOUR, MessageEnum.RA_CALLBACK_BPEL_EXC.toString(), CAMUNDA,
118                     ErrorCode.BusinessProcessError.getValue(), "Error sending callback request", e);
119             return false;
120         }
121     }
122
123     protected boolean setAuthorizationHeader(HttpHeaders headers) {
124         boolean error = false;
125         try {
126             String userCredentials = CryptoUtils.decrypt(env.getProperty(Constants.BPEL_AUTH_PROP),
127                     env.getProperty(Constants.ENCRYPTION_KEY_PROP));
128             String authorization = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
129             headers.set("Authorization", authorization);
130         } catch (Exception e) {
131             logger.error(LoggingAnchor.FOUR, MessageEnum.RA_SET_CALLBACK_AUTH_EXC.toString(), CAMUNDA,
132                     ErrorCode.BusinessProcessError.getValue(), "Unable to set authorization in callback request", e);
133             error = true;
134         }
135         return error;
136     }
137
138     private void postRequest(RestTemplate restTemplate, String url, HttpEntity<String> requestEntity) {
139         ResponseEntity<String> response = null;
140         try {
141             UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url);
142             URI uri = builder.build(true).toUri();
143             response = restTemplate.postForEntity(uri, requestEntity, String.class);
144         } catch (HttpStatusCodeException e) {
145             logResponseError(e.getStatusCode());
146         }
147         if (response != null && response.getStatusCode().is3xxRedirection()) {
148             logResponseError(response.getStatusCode());
149         }
150     }
151
152     private void logResponseError(HttpStatus statusCode) {
153         String msg = "Received error response to callback request: " + statusCode;
154         logger.error(LoggingAnchor.FOUR, MessageEnum.RA_CALLBACK_BPEL_EXC.toString(), CAMUNDA,
155                 ErrorCode.BusinessProcessError.getValue(), msg);
156     }
157
158     protected RestTemplate setRestTemplate(int timeout) {
159         RestTemplate restTemplate = new RestTemplate();
160         HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
161         factory.setConnectionRequestTimeout(timeout);
162         factory.setReadTimeout(timeout);
163         factory.setConnectTimeout(timeout);
164         restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory));
165         restTemplate.getInterceptors().add(new SOSpringClientFilter());
166         restTemplate.getInterceptors().add((new SpringClientPayloadFilter()));
167         return restTemplate;
168     }
169 }