class SDNCRestClient {

    public SDNCResponse getSdncResp(String sdncReqBody, RequestTunables rt) {

        URL url;
        HttpURLConnection con = null;
        DataOutputStream out = null;
        BufferedReader in = null;
        SDNCResponse sdncResp = new SDNCResponse(rt.getReqId());
        StringBuilder response = new StringBuilder();

        logger.info("{} :\n {} {}", MessageEnum.RA_SEND_REQUEST_SDNC.name(), rt.toString(), "SDNC");
        logger.trace("SDNC Request Body:{} \n", sdncReqBody);

        try {

            url = new URL(rt.getSdncUrl());

            con = (HttpURLConnection) url.openConnection();
            con.setConnectTimeout(Integer.parseInt(env.getProperty(Constants.SDNC_CONNECTTIME_PROP)));
            con.setReadTimeout(Integer.parseInt(rt.getTimeout()));
            con.setRequestProperty("Accept", "application/yang.data+xml"); // for response in xml
            String userCredentials = CryptoUtils.decrypt(env.getProperty(Constants.SDNC_AUTH_PROP),
                    env.getProperty(Constants.ENCRYPTION_KEY_PROP));

            String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
            con.setRequestProperty("Authorization", basicAuth);
            con.setRequestMethod(rt.getReqMethod());
            String msoAction = rt.getMsoAction();

            // Add request headers
            if ("POST".equals(rt.getReqMethod()) || "PUT".equals(rt.getReqMethod())) {
                if (Constants.MSO_ACTION_MDONS.equals(msoAction)) {
                    con.setRequestProperty("Content-type", "application/json");
                } else {
                    con.setRequestProperty("Content-type", "application/xml");
                }
                con.setRequestProperty("Content-length", String.valueOf(sdncReqBody.length()));
                con.setDoOutput(true);
                out = new DataOutputStream(con.getOutputStream());
                out.writeBytes(sdncReqBody);
                out.flush();
                out.close();
            }

            // Get response
            sdncResp.setRespCode(con.getResponseCode());
            sdncResp.setRespMsg(con.getResponseMessage());

            if (con.getResponseCode() >= 200 && con.getResponseCode() <= 299) {
                in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                String inputLine;
                // Not parsing the response -it contains a responseHdr section and data section
                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();
            }

            sdncResp.setSdncRespXml(response.toString());
            logger.info("{} :\n {} {}", MessageEnum.RA_RESPONSE_FROM_SDNC.name(), sdncResp.toString(), "SDNC");
            return (sdncResp);
        } catch (Exception e) {
            logger.error(LoggingAnchor.FOUR, MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC.toString(), "SDNC",
                    ErrorCode.BusinessProcessError.getValue(), "Exception processing request to SDNC", e);
            // default
            sdncResp.setRespCode(HttpURLConnection.HTTP_INTERNAL_ERROR);
            String respMsg = "Error processing request to SDNC. ";
            StringBuilder sdncErrMsg = new StringBuilder();

            if (e instanceof java.net.SocketTimeoutException) {
                sdncResp.setRespCode(HttpURLConnection.HTTP_CLIENT_TIMEOUT);
                respMsg = "Request to SDNC timed out. ";
            }
            if (con != null) {
                try { // e1
                    if (con.getResponseCode() != HttpURLConnection.HTTP_OK) // seen in SocketException connection reset
                        sdncResp.setRespCode(con.getResponseCode());
                    respMsg = respMsg + con.getResponseMessage() + ". ";
                    InputStream is = con.getErrorStream();
                    if (is != null) {
                        XPathFactory xpathFactory = XPathFactory.newInstance();
                        XPath xpath = xpathFactory.newXPath();
                        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                        dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
                        dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
                        dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
                        DocumentBuilder db;
                        Document doc = null;
                        try { // e2
                            db = dbf.newDocumentBuilder();
                            doc = db.parse(is);
                            NodeList errors = (NodeList) xpath.evaluate("errors/error", doc, XPathConstants.NODESET);
                            for (int i = 0; i < errors.getLength(); i++) {
                                Element error = (Element) errors.item(i);
                                String eType = null;
                                try {
                                    eType = xpath.evaluate("error-type", error);
                                    sdncErrMsg = new StringBuilder(". SDNC Returned-[error-type:" + eType);
                                } catch (Exception e3) {
                                    logger.error(LoggingAnchor.SIX, MessageEnum.RA_EVALUATE_XPATH_ERROR.toString(),
                                            "error-type", error.toString(), "SDNC", ErrorCode.DataError.getValue(),
                                            EXCEPTION_MSG, e3);
                                }

                                String eTag = null;
                                try {
                                    eTag = xpath.evaluate("error-tag", error);
                                    sdncErrMsg.append(", error-tag:").append(eTag);
                                } catch (Exception e3) {
                                    logger.error(LoggingAnchor.SIX, MessageEnum.RA_EVALUATE_XPATH_ERROR.toString(),
                                            "error-tag", error.toString(), "SDNC", ErrorCode.DataError.getValue(),
                                            EXCEPTION_MSG, e3);
                                }

                                String eMsg = null;
                                try {
                                    eMsg = xpath.evaluate("error-message", error);
                                    sdncErrMsg.append(", error-message:").append(eMsg).append("]");
                                } catch (Exception e3) {
                                    logger.error(LoggingAnchor.SIX, MessageEnum.RA_EVALUATE_XPATH_ERROR.toString(),
                                            "error-message", error.toString(), "SDNC", ErrorCode.DataError.getValue(),
                                            EXCEPTION_MSG, e3);
                                }
                            }
                        } catch (Exception e2) {
                            logger.error(LoggingAnchor.FOUR, MessageEnum.RA_ANALYZE_ERROR_EXC.toString(), "SDNC",
                                    ErrorCode.DataError.getValue(), "Exception while analyse error", e2);
                        }
                    } // is != null
                } catch (Exception e1) {
                    logger.error(LoggingAnchor.FOUR, MessageEnum.RA_ERROR_GET_RESPONSE_SDNC.toString(), "SDNC",
                            ErrorCode.BusinessProcessError.getValue(), "Exception while get SDNC response", e1);
                }
            } // con != null

            if (e.getMessage() != null) {
                respMsg = respMsg + e.getMessage();
            }
            respMsg = respMsg + sdncErrMsg;

            sdncResp.setRespMsg(respMsg);

            logger.error(LoggingAnchor.FOUR, MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC.toString(), "SDNC",
                    ErrorCode.AvailabilityError.getValue(), "Exception while communicate with SDNC", e);

            return sdncResp;
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
    }

}