2  * ============LICENSE_START=======================================================
 
   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  * Licensed under the Apache License, Version 2.0 (the "License");
 
   9  * you may not use this file except in compliance with the License.
 
  10  * You may obtain a copy of the License at
 
  12  *      http://www.apache.org/licenses/LICENSE-2.0
 
  14  * Unless required by applicable law or agreed to in writing, software
 
  15  * distributed under the License is distributed on an "AS IS" BASIS,
 
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  17  * See the License for the specific language governing permissions and
 
  18  * limitations under the License.
 
  19  * ============LICENSE_END=========================================================
 
  21 package org.openecomp.mso.adapters.sdnc.sdncrest;
 
  23 import org.openecomp.mso.adapters.sdncrest.SDNCErrorCommon;
 
  24 import org.openecomp.mso.adapters.sdncrest.SDNCResponseCommon;
 
  25 import org.openecomp.mso.adapters.sdncrest.SDNCServiceError;
 
  26 import org.openecomp.mso.adapters.sdncrest.SDNCServiceResponse;
 
  27 import org.w3c.dom.Document;
 
  28 import org.w3c.dom.Element;
 
  29 import org.xml.sax.InputSource;
 
  31 import javax.xml.XMLConstants;
 
  32 import javax.xml.parsers.DocumentBuilderFactory;
 
  33 import java.io.StringReader;
 
  34 import java.net.HttpURLConnection;
 
  35 import java.text.ParseException;
 
  36 import java.util.ArrayList;
 
  37 import java.util.List;
 
  38 import org.openecomp.mso.logger.MsoLogger;
 
  41  * SDNCConnector for "agnostic" API services.
 
  43 public class SDNCServiceRequestConnector extends SDNCConnector {
 
  45     private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
 
  46     private static final String YES = "Y";
 
  48         protected SDNCResponseCommon createResponseFromContent(int statusCode, String statusMessage,
 
  49                         String responseContent, TypedRequestTunables rt) {
 
  51                         return parseResponseContent(responseContent);
 
  52                 } catch (ParseException e) {
 
  53                         logError(e.getMessage());
 
  54                         return createErrorResponse(HttpURLConnection.HTTP_INTERNAL_ERROR, e.getMessage(), rt);
 
  59         protected SDNCErrorCommon createErrorResponse(int statusCode, String errMsg,
 
  60                         TypedRequestTunables rt) {
 
  61                 return new SDNCServiceError(rt.getReqId(), String.valueOf(statusCode), errMsg, YES);
 
  65          * Parses SDNC synchronous service response content or service notification content.
 
  66          * If the content can be parsed and contains all required elements, then an object
 
  67          * is returned.  The type of the returned object depends on the response code
 
  68          * contained in the content.  For 2XX response codes, an SDNCServiceResponse is
 
  69          * returned.  Otherwise, an SDNCServiceError is returned.  If the content cannot
 
  70          * be parsed, or if the content does not contain all required elements, a parse
 
  71          * exception is thrown.  This method performs no logging or alarming.
 
  72          * @throws ParseException on error
 
  74         public static SDNCResponseCommon parseResponseContent(String responseContent)
 
  75                         throws ParseException {
 
  77                         // Note: this document builder is not namespace-aware, so namespaces are ignored.
 
  78                         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
 
  79                         documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
 
  80                         InputSource source = new InputSource(new StringReader(responseContent));
 
  81                         Document doc = documentBuilderFactory.newDocumentBuilder().parse(source);
 
  83                         // Find the configuration-response-common child under the root element.
 
  84                         // The root element is expected to be an "output" element, but we don't really care.
 
  86                         Element root = doc.getDocumentElement();
 
  87                         Element configurationResponseCommon = null;
 
  89                         for (Element child : SDNCAdapterUtils.childElements(root)) {
 
  90                                 if ("configuration-response-common".equals(child.getNodeName())) {
 
  91                                         configurationResponseCommon = child;
 
  96                         if (configurationResponseCommon == null) {
 
  97                                 throw new ParseException("No configuration-response-common element in SDNC response", 0);
 
 100                         // Process the children of configuration-response-common.
 
 102                         String responseCode = null;
 
 103                         String responseMessage = null;
 
 104                         String svcRequestId = null;
 
 105                         String ackFinalIndicator = null;
 
 106                         List<Element> responseParameters = new ArrayList<>();
 
 108                         for (Element child : SDNCAdapterUtils.childElements(configurationResponseCommon)) {
 
 109                                 if ("response-code".equals(child.getNodeName())) {
 
 110                                         responseCode = child.getTextContent();
 
 111                                 } else if ("response-message".equals(child.getNodeName())) {
 
 112                                         responseMessage = child.getTextContent();
 
 113                                 } else if ("svc-request-id".equals(child.getNodeName())) {
 
 114                                         svcRequestId = child.getTextContent();
 
 115                                 } else if ("ack-final-indicator".equals(child.getNodeName())) {
 
 116                                         ackFinalIndicator = child.getTextContent();
 
 117                                 } else if ("response-parameters".equals(child.getNodeName())) {
 
 118                     responseParameters.add((Element) child);
 
 122                         // svc-request-id is mandatory.
 
 124                         if (svcRequestId == null || svcRequestId.isEmpty()) {
 
 125                                 throw new ParseException("No svc-request-id in SDNC response", 0);
 
 128                         // response-code is mandatory.
 
 130                         if (responseCode == null || responseCode.isEmpty()) {
 
 131                                 throw new ParseException("No response-code in SDNC response", 0);
 
 134                         // ack-final-indicator is optional: default to "Y".
 
 136                         if (ackFinalIndicator == null || ackFinalIndicator.trim().isEmpty()) {
 
 137                                 ackFinalIndicator = YES;
 
 140                         if (!YES.equals(ackFinalIndicator) && !"N".equals(ackFinalIndicator)) {
 
 141                                 throw new ParseException("Invalid ack-final-indicator in SDNC response: '" + ackFinalIndicator + "'", 0);
 
 144                         // response-message is optional.  If the value is empty, omit it from the response object.
 
 146                         if (responseMessage != null && responseMessage.isEmpty()) {
 
 147                                 responseMessage = null;
 
 150                         // If the response code in the message from SDNC was not 2XX, return SDNCServiceError.
 
 152                         if (!responseCode.matches("2[0-9][0-9]")) {
 
 153                                 // Not a 2XX response.  Return SDNCServiceError.
 
 154                                 return new SDNCServiceError(svcRequestId, responseCode, responseMessage, ackFinalIndicator);
 
 157                         // Create a success response object.
 
 159                         SDNCServiceResponse response = new SDNCServiceResponse(svcRequestId,
 
 160                                 responseCode, responseMessage, ackFinalIndicator);
 
 162             // Process any response-parameters that might be present.
 
 164             for (Element element : responseParameters) {
 
 165                 String tagName = null;
 
 166                 String tagValue = null;
 
 168                 for (Element child : SDNCAdapterUtils.childElements(element)) {
 
 169                     if ("tag-name".equals(child.getNodeName())) {
 
 170                         tagName = child.getTextContent();
 
 171                     } else if ("tag-value".equals(child.getNodeName())) {
 
 172                         tagValue = child.getTextContent();
 
 176                 // tag-name is mandatory
 
 178                 if (tagName == null) {
 
 179                     throw new ParseException("Missing tag-name in SDNC response parameter", 0);
 
 182                 // tag-value is optional.  If absent, make it an empty string so we don't
 
 183                 // end up with null values in the parameter map.
 
 185                 if (tagValue == null) {
 
 189                 response.addParam(tagName, tagValue);
 
 193                 } catch (ParseException e) {
 
 195                 } catch (Exception e) {
 
 196                     LOGGER.debug("Exception:", e);
 
 197                         throw new ParseException("Failed to parse SDNC response", 0);