Change the header to SO
[so.git] / adapters / mso-sdnc-adapter / src / main / java / org / openecomp / mso / adapters / sdnc / sdncrest / SDNCAdapterRest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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 package org.openecomp.mso.adapters.sdnc.sdncrest;
21
22 import org.openecomp.mso.HealthCheckUtils;
23 import org.openecomp.mso.adapters.sdnc.impl.Constants;
24 import org.openecomp.mso.adapters.sdncrest.SDNCEvent;
25 import org.openecomp.mso.adapters.sdncrest.SDNCResponseCommon;
26 import org.openecomp.mso.adapters.sdncrest.SDNCServiceError;
27 import org.openecomp.mso.adapters.sdncrest.SDNCServiceRequest;
28 import org.openecomp.mso.logger.MessageEnum;
29 import org.openecomp.mso.logger.MsoAlarmLogger;
30 import org.openecomp.mso.logger.MsoLogger;
31 import org.openecomp.mso.utils.UUIDChecker;
32 import org.apache.http.HttpStatus;
33
34 import javax.servlet.http.HttpServletResponse;
35 import javax.ws.rs.*;
36 import javax.ws.rs.core.GenericEntity;
37 import javax.ws.rs.core.MediaType;
38 import javax.ws.rs.core.Response;
39 import java.text.ParseException;
40
41 /**
42  * SDNC REST adapter interface added in 1702 to support the SDNC "agnostic" API.
43  */
44 @Path("/")
45 public class SDNCAdapterRest {
46         private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
47         private static final MsoAlarmLogger ALARMLOGGER = new MsoAlarmLogger();
48
49         private static final String MSO_PROPERTIES_ID = "MSO_PROP_SDNC_ADAPTER";
50
51         @HEAD
52         @GET
53         @Path("/v1/sdnc/healthcheck")
54         @Produces(MediaType.TEXT_HTML)
55         public Response healthcheck(@QueryParam("requestId") String requestId) {
56                 long startTime = System.currentTimeMillis();
57                 MsoLogger.setServiceName("Healthcheck");
58                 UUIDChecker.verifyOldUUID(requestId, LOGGER);
59                 HealthCheckUtils healthCheck = new HealthCheckUtils();
60
61                 if (!healthCheck.siteStatusCheck(LOGGER, startTime)) {
62                         return HealthCheckUtils.HEALTH_CHECK_NOK_RESPONSE;
63                 }
64
65                 if (!healthCheck.configFileCheck(LOGGER, startTime, MSO_PROPERTIES_ID)) {
66                         return HealthCheckUtils.NOT_STARTED_RESPONSE;
67                 }
68
69                 LOGGER.debug("healthcheck - Successful");
70                 return HealthCheckUtils.HEALTH_CHECK_RESPONSE;
71         }
72
73         /**
74          * Processes an SDNCServiceRequest (a request for "agnostic" API services) from BP.
75          * @param request the request
76          * @param msoRequestId the request ID for the top-level MSO flow (used for logging only)
77          * @param msoServiceInstanceId the top-level service-instance-id (used for logging only)
78          */
79         @POST
80         @Path("/v1/sdnc/services")
81         @Consumes({MediaType.APPLICATION_JSON})
82         @Produces({MediaType.APPLICATION_JSON})
83         public Response service(
84                         SDNCServiceRequest request,
85                         @HeaderParam(value="mso-request-id") String msoRequestId,
86                         @HeaderParam(value="mso-service-instance-id") String msoServiceInstanceId) {
87
88                 MsoLogger.setLogContext(msoRequestId, msoServiceInstanceId);
89
90                 try {
91                         LOGGER.debug(getClass().getSimpleName() + ".service(request)"
92                                 + " entered with request: " + request.toJson());
93
94                         SDNCServiceRequestTask task = new SDNCServiceRequestTask(request, msoRequestId,
95                                         msoServiceInstanceId, "/services");
96
97                 try {
98                         Thread thread = new Thread(task);
99                         thread.start();
100                 } catch (Exception e) {
101                         String msg = "Failed to start thread to run SDNCServiceTask";
102                         LOGGER.error(MessageEnum.RA_SEND_REQUEST_SDNC_ERR, "SDNC", "", MsoLogger.ErrorCode.BusinessProcesssError, msg, e);
103                         ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, msg);
104                         SDNCServiceError error = new SDNCServiceError(request.getSDNCRequestId(),
105                                 String.valueOf(HttpStatus.SC_INTERNAL_SERVER_ERROR), e.toString(), "Y");
106                         LOGGER.debug(getClass().getSimpleName() + ".service(request)"
107                                 + " exited with error: " + msg);
108                         return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
109                                 .entity(new GenericEntity<SDNCServiceError>(error){})
110                                 .build();
111                 }
112
113                 // Send sync response to caller
114                 LOGGER.debug(getClass().getSimpleName() + ".service(request)"
115                         + " exited successfully");
116                 return Response.status(HttpStatus.SC_ACCEPTED).build();
117                 } catch (Exception e) {
118                         String msg = "Caught " + e.getClass().getSimpleName() + " in 'service' method";
119                         LOGGER.error(MessageEnum.RA_SEND_REQUEST_SDNC_ERR, "SDNC", "", MsoLogger.ErrorCode.BusinessProcesssError, msg, e);
120                 LOGGER.debug(getClass().getSimpleName() + ".service(request)"
121                         + " exited with error: " + msg);
122                         SDNCServiceError error = new SDNCServiceError(request.getSDNCRequestId(),
123                                 String.valueOf(HttpStatus.SC_INTERNAL_SERVER_ERROR), e.toString(), "Y");
124                         return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
125                                 .entity(new GenericEntity<SDNCServiceError>(error){})
126                                 .build();
127                 }
128         }
129
130         /**
131          * Processes a notification from SDNC for "agnostic" API services.
132          * Note that the "myurl" configuration property specifies the path
133          * up to and including /SDNCNotify. The /services part of the path
134          * is added by this class.
135          * @param content the notification content
136          */
137         @POST
138         @Path("/SDNCNotify/services")
139         @Consumes({MediaType.APPLICATION_XML})
140         @Produces({MediaType.APPLICATION_XML})
141         public Response serviceNotification(String content) {
142                 LOGGER.info(MessageEnum.RA_RECEIVE_SDNC_NOTIF, content, "SDNC", "SDNCNotify/services");
143
144                 long startTime = System.currentTimeMillis();
145
146                 try {
147                         // Because the format of a notification is exactly the same as that of
148                         // a synchronous response, we can use the same code to parse it.
149                         SDNCResponseCommon response = SDNCServiceRequestConnector.parseResponseContent(content);
150
151                         String bpUrl = SDNCAdapterProperties.getProperty(Constants.BPEL_REST_URL_PROP, null);
152
153                         if (bpUrl == null) {
154                                 String error = "Missing configuration for: " + Constants.BPEL_REST_URL_PROP;
155                                 LOGGER.error(MessageEnum.RA_SDNC_MISS_CONFIG_PARAM, Constants.BPEL_REST_URL_PROP, "SDNC", "",
156                                         MsoLogger.ErrorCode.DataError, "Missing config param");
157                                 ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
158                                 return Response.status(HttpServletResponse.SC_BAD_REQUEST).entity(error).build();
159                         }
160
161                         long bpStartTime = System.currentTimeMillis();
162                         BPRestCallback callback = new BPRestCallback();
163                         boolean callbackSuccess = callback.send(bpUrl, "SDNCAResponse", response.getSDNCRequestId(), response.toJson());
164
165                         if (callbackSuccess) {
166                                 LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
167                                         "Sent notification", "BPMN", bpUrl, null);
168                                 LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successful");
169                         } else {
170                                 LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
171                                         "Failed to send notification", "BPMN", bpUrl, null);
172                                 LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
173                                         "Failed to send notification");
174                         }
175
176                         return Response.ok().build();
177                 } catch (ParseException e) {
178                         LOGGER.error(MessageEnum.RA_PARSING_REQUEST_ERROR, "SDNC", "SDNCNotify/services",
179                                 MsoLogger.ErrorCode.SchemaError, e.getMessage());
180                         LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
181                                 MsoLogger.ResponseCode.SchemaError, e.getMessage());
182                         return Response.status(HttpServletResponse.SC_BAD_REQUEST).entity(e.getMessage()).build();
183                 }
184         }
185
186         /**
187          * Processes an event notification from SDNC.
188          * Note that the "myurl" configuration property specifies the path
189          * up to and including /SDNCNotify. The /activate part of the path
190          * is added by this class.
191          * @param content the notification content
192          */
193         @POST
194         @Path("/SDNCNotify/event")
195         @Consumes({MediaType.APPLICATION_XML})
196         @Produces({MediaType.APPLICATION_XML})
197         public Response eventNotification(String content) {
198                 LOGGER.info(MessageEnum.RA_RECEIVE_SDNC_NOTIF, content, "SDNC", "SDNCNotify/event");
199
200                 long startTime = System.currentTimeMillis();
201
202                 try {
203                         SDNCEvent event = SDNCEventParser.parse(content);
204
205                         String bpUrl = SDNCAdapterProperties.getProperty(Constants.BPEL_REST_URL_PROP, null);
206
207                         if (bpUrl == null) {
208                                 String error = "Missing configuration for: " + Constants.BPEL_REST_URL_PROP;
209                                 LOGGER.error(MessageEnum.RA_SDNC_MISS_CONFIG_PARAM, Constants.BPEL_REST_URL_PROP, "SDNC", "",
210                                         MsoLogger.ErrorCode.DataError, "Missing config param");
211                                 ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
212                                 return Response.status(HttpServletResponse.SC_BAD_REQUEST).entity(error).build();
213                         }
214
215                         long bpStartTime = System.currentTimeMillis();
216                         BPRestCallback callback = new BPRestCallback();
217                         boolean callbackSuccess = callback.send(bpUrl, "SDNCAEvent", event.getEventCorrelator(), event.toJson());
218
219                         if (callbackSuccess) {
220                                 LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
221                                         "Sent notification", "BPMN", bpUrl, null);
222                                 LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successful");
223                         } else {
224                                 LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
225                                         "Failed to send notification", "BPMN", bpUrl, null);
226                                 LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
227                                         "Failed to send notification");
228                         }
229
230                         return Response.ok().build();
231                 } catch (ParseException e) {
232                         LOGGER.error(MessageEnum.RA_PARSING_REQUEST_ERROR, "SDNC", "SDNCNotify/event",
233                                 MsoLogger.ErrorCode.SchemaError, e.getMessage());
234                         LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
235                                 MsoLogger.ResponseCode.SchemaError, e.getMessage());
236                         return Response.status(HttpServletResponse.SC_BAD_REQUEST).entity(e.getMessage()).build();
237                 }
238         }
239 }