be6fc34d44b0d60d542c95233e45b9ef96d25435
[so.git] / adapters / mso-sdnc-adapter / src / main / java / org / openecomp / mso / adapters / sdnc / sdncrest / SDNCServiceRequestConnector.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * OPENECOMP - MSO
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.adapters.sdncrest.SDNCErrorCommon;
23 import org.openecomp.mso.adapters.sdncrest.SDNCResponseCommon;
24 import org.openecomp.mso.adapters.sdncrest.SDNCServiceError;
25 import org.openecomp.mso.adapters.sdncrest.SDNCServiceResponse;
26 import org.w3c.dom.Document;
27 import org.w3c.dom.Element;
28 import org.xml.sax.InputSource;
29
30 import javax.xml.XMLConstants;
31 import javax.xml.parsers.DocumentBuilderFactory;
32 import java.io.StringReader;
33 import java.net.HttpURLConnection;
34 import java.text.ParseException;
35 import java.util.ArrayList;
36 import java.util.List;
37
38 /**
39  * SDNCConnector for "agnostic" API services.
40  */
41 public class SDNCServiceRequestConnector extends SDNCConnector {
42
43         @Override
44         protected SDNCResponseCommon createResponseFromContent(int statusCode, String statusMessage,
45                         String responseContent, TypedRequestTunables rt) {
46                 try {
47                         return parseResponseContent(responseContent);
48                 } catch (ParseException e) {
49                         logError(e.getMessage());
50                         return createErrorResponse(HttpURLConnection.HTTP_INTERNAL_ERROR, e.getMessage(), rt);
51                 }
52         }
53
54         @Override
55         protected SDNCErrorCommon createErrorResponse(int statusCode, String errMsg,
56                         TypedRequestTunables rt) {
57                 return new SDNCServiceError(rt.getReqId(), String.valueOf(statusCode), errMsg, "Y");
58         }
59
60         /**
61          * Parses SDNC synchronous service response content or service notification content.
62          * If the content can be parsed and contains all required elements, then an object
63          * is returned.  The type of the returned object depends on the response code
64          * contained in the content.  For 2XX response codes, an SDNCServiceResponse is
65          * returned.  Otherwise, an SDNCServiceError is returned.  If the content cannot
66          * be parsed, or if the content does not contain all required elements, a parse
67          * exception is thrown.  This method performs no logging or alarming.
68          * @throws ParseException on error
69          */
70         public static SDNCResponseCommon parseResponseContent(String responseContent)
71                         throws ParseException {
72                 try {
73                         // Note: this document builder is not namespace-aware, so namespaces are ignored.
74                         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
75                         documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
76                         InputSource source = new InputSource(new StringReader(responseContent));
77                         Document doc = documentBuilderFactory.newDocumentBuilder().parse(source);
78
79                         // Find the configuration-response-common child under the root element.
80                         // The root element is expected to be an "output" element, but we don't really care.
81
82                         Element root = doc.getDocumentElement();
83                         Element configurationResponseCommon = null;
84
85                         for (Element child : SDNCAdapterUtils.childElements(root)) {
86                                 if ("configuration-response-common".equals(child.getNodeName())) {
87                                         configurationResponseCommon = child;
88                                         break;
89                                 }
90                         }
91
92                         if (configurationResponseCommon == null) {
93                                 throw new ParseException("No configuration-response-common element in SDNC response", 0);
94                         }
95
96                         // Process the children of configuration-response-common.
97
98                         String responseCode = null;
99                         String responseMessage = null;
100                         String svcRequestId = null;
101                         String ackFinalIndicator = null;
102                         List<Element> responseParameters = new ArrayList<Element>();
103
104                         for (Element child : SDNCAdapterUtils.childElements(configurationResponseCommon)) {
105                                 if ("response-code".equals(child.getNodeName())) {
106                                         responseCode = child.getTextContent();
107                                 } else if ("response-message".equals(child.getNodeName())) {
108                                         responseMessage = child.getTextContent();
109                                 } else if ("svc-request-id".equals(child.getNodeName())) {
110                                         svcRequestId = child.getTextContent();
111                                 } else if ("ack-final-indicator".equals(child.getNodeName())) {
112                                         ackFinalIndicator = child.getTextContent();
113                                 } else if ("response-parameters".equals(child.getNodeName())) {
114                     responseParameters.add((Element) child);
115                                 }
116                         }
117
118                         // svc-request-id is mandatory.
119
120                         if (svcRequestId == null || svcRequestId.isEmpty()) {
121                                 throw new ParseException("No svc-request-id in SDNC response", 0);
122                         }
123
124                         // response-code is mandatory.
125
126                         if (responseCode == null || responseCode.isEmpty()) {
127                                 throw new ParseException("No response-code in SDNC response", 0);
128                         }
129
130                         // ack-final-indicator is optional: default to "Y".
131
132                         if (ackFinalIndicator == null || ackFinalIndicator.trim().isEmpty()) {
133                                 ackFinalIndicator = "Y";
134                         }
135
136                         if (!ackFinalIndicator.equals("Y") && !ackFinalIndicator.equals("N")) {
137                                 throw new ParseException("Invalid ack-final-indicator in SDNC response: '" + ackFinalIndicator + "'", 0);
138                         }
139
140                         // response-message is optional.  If the value is empty, omit it from the response object.
141
142                         if (responseMessage != null && responseMessage.isEmpty()) {
143                                 responseMessage = null;
144                         }
145
146                         // If the response code in the message from SDNC was not 2XX, return SDNCServiceError.
147
148                         if (!responseCode.matches("2[0-9][0-9]")) {
149                                 // Not a 2XX response.  Return SDNCServiceError.
150                                 return new SDNCServiceError(svcRequestId, responseCode, responseMessage, ackFinalIndicator);
151                         }
152
153                         // Create a success response object.
154
155                         SDNCServiceResponse response = new SDNCServiceResponse(svcRequestId,
156                                 responseCode, responseMessage, ackFinalIndicator);
157
158             // Process any response-parameters that might be present.
159
160             for (Element element : responseParameters) {
161                 String tagName = null;
162                 String tagValue = null;
163
164                 for (Element child : SDNCAdapterUtils.childElements(element)) {
165                     if ("tag-name".equals(child.getNodeName())) {
166                         tagName = child.getTextContent();
167                     } else if ("tag-value".equals(child.getNodeName())) {
168                         tagValue = child.getTextContent();
169                     }
170                 }
171
172                 // tag-name is mandatory
173
174                 if (tagName == null) {
175                     throw new ParseException("Missing tag-name in SDNC response parameter", 0);
176                 }
177
178                 // tag-value is optional.  If absent, make it an empty string so we don't
179                 // end up with null values in the parameter map.
180
181                 if (tagValue == null) {
182                     tagValue = "";
183                 }
184
185                 response.addParam(tagName, tagValue);
186             }
187
188                         return response;
189                 } catch (ParseException e) {
190                         throw e;
191                 } catch (Exception e) {
192                         throw new ParseException("Failed to parse SDNC response", 0);
193                 }
194         }
195 }