summaryrefslogtreecommitdiffstats
path: root/adapters/mso-sdnc-adapter/src/main/java/org/openecomp
diff options
context:
space:
mode:
Diffstat (limited to 'adapters/mso-sdnc-adapter/src/main/java/org/openecomp')
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterPortType.java6
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterRequest.java2
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterService.java6
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCAdapterCallbackRequest.java2
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCCallbackAdapterPortType.java6
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCCallbackAdapterService.java6
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/package-info.java2
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/impl/Constants.java9
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/impl/SDNCAdapterPortTypeImpl.java2
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/package-info.java2
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/BPRestCallback.java173
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCAdapterProperties.java85
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCAdapterRest.java239
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCAdapterUtils.java70
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCConnector.java309
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCEventParser.java156
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCServiceRequestConnector.java194
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCServiceRequestTask.java205
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SNIROResponse.java78
-rw-r--r--adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/TypedRequestTunables.java224
20 files changed, 1755 insertions, 21 deletions
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterPortType.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterPortType.java
index 254fea0ba3..f4c8234407 100644
--- a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterPortType.java
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterPortType.java
@@ -36,15 +36,15 @@ import javax.xml.bind.annotation.XmlSeeAlso;
*
*/
//BPEL SDNCAdapter SOAP WebService - impl class in impl pkg
-@WebService(targetNamespace = "http://domain2.att.com/workflow/sdnc/adapter/wsdl/v1", name = "SDNCAdapterPortType")
+@WebService(targetNamespace = "http://org.openecomp/workflow/sdnc/adapter/wsdl/v1", name = "SDNCAdapterPortType")
@XmlSeeAlso({ObjectFactory.class})
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface SDNCAdapterPortType {
- @WebResult(name = "SDNCAdapterResponse", targetNamespace = "http://domain2.att.com/workflow/sdnc/adapter/schema/v1", partName = "SDNCAdapterResponse")
+ @WebResult(name = "SDNCAdapterResponse", targetNamespace = "http://org.openecomp/workflow/sdnc/adapter/schema/v1", partName = "SDNCAdapterResponse")
@WebMethod(operationName = "SDNCAdapter")
public SDNCAdapterResponse sdncAdapter(
- @WebParam(partName = "SDNCAdapterRequest", name = "SDNCAdapterRequest", targetNamespace = "http://domain2.att.com/workflow/sdnc/adapter/schema/v1")
+ @WebParam(partName = "SDNCAdapterRequest", name = "SDNCAdapterRequest", targetNamespace = "http://org.openecomp/workflow/sdnc/adapter/schema/v1")
SDNCAdapterRequest sdncAdapterRequest
);
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterRequest.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterRequest.java
index 6b75949453..5da1e51d43 100644
--- a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterRequest.java
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterRequest.java
@@ -41,7 +41,7 @@ import org.openecomp.mso.adapters.sdnc.impl.Utils;
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
- * <element ref="{http://domain2.att.com/workflow/sdnc/adapter/schema/v1}RequestHeader"/>
+ * <element ref="{http://org.openecomp/workflow/sdnc/adapter/schema/v1}RequestHeader"/>
* <element name="RequestData" type="{http://www.w3.org/2001/XMLSchema}anyType"/>
* </sequence>
* </restriction>
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterService.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterService.java
index 0b63ad6dea..1e33789ba8 100644
--- a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterService.java
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/SDNCAdapterService.java
@@ -42,15 +42,15 @@ import org.openecomp.mso.logger.MessageEnum;
//BPEL SDNCAdapter SOAP WebService
@WebServiceClient(name = "SDNCAdapterService",
wsdlLocation = "main/resources/SDNCAdapter.wsdl",
- targetNamespace = "http://domain2.att.com/workflow/sdnc/adapter/wsdl/v1")
+ targetNamespace = "http://org.openecomp/workflow/sdnc/adapter/wsdl/v1")
public class SDNCAdapterService extends Service {
private static MsoLogger logger = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
public final static URL WSDL_LOCATION;
- public final static QName SERVICE = new QName("http://domain2.att.com/workflow/sdnc/adapter/wsdl/v1", "SDNCAdapterService");
- public final static QName SDNCAdapterSoapHttpPort = new QName("http://domain2.att.com/workflow/sdnc/adapter/wsdl/v1", "SDNCAdapterSoapHttpPort");
+ public final static QName SERVICE = new QName("http://org.openecomp/workflow/sdnc/adapter/wsdl/v1", "SDNCAdapterService");
+ public final static QName SDNCAdapterSoapHttpPort = new QName("http://org.openecomp/workflow/sdnc/adapter/wsdl/v1", "SDNCAdapterSoapHttpPort");
static {
URL wsdlUrl = null;
try {
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCAdapterCallbackRequest.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCAdapterCallbackRequest.java
index fd16e4754c..f62c984ef9 100644
--- a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCAdapterCallbackRequest.java
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCAdapterCallbackRequest.java
@@ -42,7 +42,7 @@ import org.openecomp.mso.logger.MessageEnum;
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
- * <element ref="{http://domain2.att.com/workflow/sdnc/adapter/schema/v1}CallbackHeader"/>
+ * <element ref="{http://org.openecomp/workflow/sdnc/adapter/schema/v1}CallbackHeader"/>
* <element name="RequestData" type="{http://www.w3.org/2001/XMLSchema}anyType"/>
* </sequence>
* </restriction>
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCCallbackAdapterPortType.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCCallbackAdapterPortType.java
index 6818e67e75..d792b9ca18 100644
--- a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCCallbackAdapterPortType.java
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCCallbackAdapterPortType.java
@@ -37,15 +37,15 @@ import org.openecomp.mso.adapters.sdnc.SDNCAdapterResponse;
*
*/
//SDNCAdapter to BPEL Async response WEB Service
-@WebService(targetNamespace = "http://domain2.att.com/workflow/sdnc/adapter/callback/wsdl/v1", name = "SDNCCallbackAdapterPortType")
+@WebService(targetNamespace = "http://org.openecomp/workflow/sdnc/adapter/callback/wsdl/v1", name = "SDNCCallbackAdapterPortType")
@XmlSeeAlso({ObjectFactory.class})
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface SDNCCallbackAdapterPortType {
- @WebResult(name = "SDNCAdapterResponse", targetNamespace = "http://domain2.att.com/workflow/sdnc/adapter/schema/v1", partName = "SDNCAdapterCallbackResponse")
+ @WebResult(name = "SDNCAdapterResponse", targetNamespace = "http://org.openecomp/workflow/sdnc/adapter/schema/v1", partName = "SDNCAdapterCallbackResponse")
@WebMethod(operationName = "SDNCAdapterCallback")
public SDNCAdapterResponse sdncAdapterCallback(
- @WebParam(partName = "SDNCAdapterCallbackRequest", name = "SDNCAdapterCallbackRequest", targetNamespace = "http://domain2.att.com/workflow/sdnc/adapter/schema/v1")
+ @WebParam(partName = "SDNCAdapterCallbackRequest", name = "SDNCAdapterCallbackRequest", targetNamespace = "http://org.openecomp/workflow/sdnc/adapter/schema/v1")
SDNCAdapterCallbackRequest sdncAdapterCallbackRequest
);
}
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCCallbackAdapterService.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCCallbackAdapterService.java
index 6fa8e035a5..bbac6a30cb 100644
--- a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCCallbackAdapterService.java
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/SDNCCallbackAdapterService.java
@@ -40,14 +40,14 @@ import org.openecomp.mso.logger.MsoLogger;
//SDNCAdapter to BPEL Async response WEB Service
@WebServiceClient(name = "SDNCCallbackAdapterService",
wsdlLocation = "main/resources/SDNCCallbackAdapter.wsdl",
- targetNamespace = "http://domain2.att.com/workflow/sdnc/adapter/callback/wsdl/v1")
+ targetNamespace = "http://org.openecomp/workflow/sdnc/adapter/callback/wsdl/v1")
public class SDNCCallbackAdapterService extends Service {
private static MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
public final static URL WSDL_LOCATION;
- public final static QName SERVICE = new QName("http://domain2.att.com/workflow/sdnc/adapter/callback/wsdl/v1", "SDNCCallbackAdapterService");
- public final static QName SDNCCallbackAdapterSoapHttpPort = new QName("http://domain2.att.com/workflow/sdnc/adapter/callback/wsdl/v1", "SDNCCallbackAdapterSoapHttpPort");
+ public final static QName SERVICE = new QName("http://org.openecomp/workflow/sdnc/adapter/callback/wsdl/v1", "SDNCCallbackAdapterService");
+ public final static QName SDNCCallbackAdapterSoapHttpPort = new QName("http://org.openecomp/workflow/sdnc/adapter/callback/wsdl/v1", "SDNCCallbackAdapterSoapHttpPort");
static {
URL wsdlUrl = null;
try {
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/package-info.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/package-info.java
index 0d6f900f47..35334dfa74 100644
--- a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/package-info.java
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/client/package-info.java
@@ -18,6 +18,6 @@
* ============LICENSE_END=========================================================
*/
-@javax.xml.bind.annotation.XmlSchema(namespace = "http://domain2.att.com/workflow/sdnc/adapter/schema/v1", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+@javax.xml.bind.annotation.XmlSchema(namespace = "http://org.openecomp/workflow/sdnc/adapter/schema/v1", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package org.openecomp.mso.adapters.sdnc.client;
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/impl/Constants.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/impl/Constants.java
index 6cc0ecbd92..78983291c6 100644
--- a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/impl/Constants.java
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/impl/Constants.java
@@ -7,9 +7,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,11 +23,12 @@ package org.openecomp.mso.adapters.sdnc.impl;
public interface Constants {
+ public static final String BPEL_REST_URL_PROP = "org.openecomp.mso.adapters.sdnc.rest.bpelurl";
public static final String BPEL_URL_PROP = "org.openecomp.mso.adapters.sdnc.bpelurl";
- public static final String DEFAULT_BPEL_URL = "http://msobpel.mtcnj.aic.cip.att.com:8080//active-bpel/services/SDNCAdapterCallbackV1";
+ public static final String DEFAULT_BPEL_URL = "http://localhost:8080//active-bpel/services/SDNCAdapterCallbackV1";
public static final String MY_URL_PROP = "org.openecomp.mso.adapters.sdnc.myurl";
- public static final String DEFAULT_MY_URL = "https://msojra.mtcnj.aic.cip.att.com:8443/adapters/rest/SDNCNotify";
+ public static final String DEFAULT_MY_URL = "https://localhost:8443/adapters/rest/SDNCNotify";
public static final String SDNC_AUTH_PROP = "org.openecomp.mso.adapters.sdnc.sdncauth";
public static final String DEFAULT_SDNC_AUTH = "406B2AE613211B6FB52466DE6E1769AC";
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/impl/SDNCAdapterPortTypeImpl.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/impl/SDNCAdapterPortTypeImpl.java
index 887c0a9990..0eeacaf5fc 100644
--- a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/impl/SDNCAdapterPortTypeImpl.java
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/impl/SDNCAdapterPortTypeImpl.java
@@ -35,7 +35,7 @@ import org.openecomp.mso.properties.MsoPropertiesException;
import org.openecomp.mso.properties.MsoPropertiesFactory;
//BPEL SDNCAdapter SOAP Web Service implementation
-@WebService(serviceName = "SDNCAdapterService", endpointInterface = "org.openecomp.mso.adapters.sdnc.SDNCAdapterPortType", targetNamespace = "http://domain2.att.com/workflow/sdnc/adapter/wsdl/v1")
+@WebService(serviceName = "SDNCAdapterService", endpointInterface = "org.openecomp.mso.adapters.sdnc.SDNCAdapterPortType", targetNamespace = "http://org.openecomp/workflow/sdnc/adapter/wsdl/v1")
public class SDNCAdapterPortTypeImpl implements SDNCAdapterPortType {
private MsoPropertiesFactory msoPropertiesFactory=new MsoPropertiesFactory();
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/package-info.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/package-info.java
index 58359c69b0..55819c6e4d 100644
--- a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/package-info.java
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/package-info.java
@@ -18,6 +18,6 @@
* ============LICENSE_END=========================================================
*/
-@javax.xml.bind.annotation.XmlSchema(namespace = "http://domain2.att.com/workflow/sdnc/adapter/schema/v1", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+@javax.xml.bind.annotation.XmlSchema(namespace = "http://org.openecomp/workflow/sdnc/adapter/schema/v1", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package org.openecomp.mso.adapters.sdnc;
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/BPRestCallback.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/BPRestCallback.java
new file mode 100644
index 0000000000..52b1f19b5f
--- /dev/null
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/BPRestCallback.java
@@ -0,0 +1,173 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.mso.adapters.sdnc.sdncrest;
+
+import org.openecomp.mso.adapters.sdnc.impl.Constants;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoAlarmLogger;
+import org.openecomp.mso.logger.MsoLogger;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+
+import javax.xml.bind.DatatypeConverter;
+
+/**
+ * Sends asynchronous messages to the BPMN workflow message service.
+ */
+public class BPRestCallback {
+ private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
+ private static final MsoAlarmLogger ALARMLOGGER = new MsoAlarmLogger();
+
+ /**
+ * Sends a message to the BPMN workflow message service. The URL path is
+ * constructed using the specified message type and correlator.
+ * @param workflowMessageUrl the base BPMN WorkflowMessage URL
+ * @param messageType the message type
+ * @param correlator the message correlator
+ * @param message the JSON content
+ * @return true if the message was consumed successfully by the endpoint
+ */
+ public boolean send(String workflowMessageUrl, String messageType, String correlator, String message) {
+ LOGGER.debug(getClass().getSimpleName() + ".send("
+ + "workflowMessageUrl=" + workflowMessageUrl
+ + " messageType=" + messageType
+ + " correlator=" + correlator
+ + " message=" + message
+ + ")");
+
+ while (workflowMessageUrl.endsWith("/")) {
+ workflowMessageUrl = workflowMessageUrl.substring(0, workflowMessageUrl.length()-1);
+ }
+
+ String endpoint = workflowMessageUrl + "/" + SDNCAdapterUtils.encodeURLPathSegment(messageType)
+ + "/" + SDNCAdapterUtils.encodeURLPathSegment(correlator);
+
+ return send(endpoint, message);
+ }
+
+ /**
+ * Sends a message to the BPMN workflow message service. The specified URL
+ * must have the message type and correlator already embedded in it.
+ * @param url the endpoint URL
+ * @param message the JSON content
+ * @return true if the message was consumed successfully by the endpoint
+ */
+ public boolean send(String url, String message) {
+ LOGGER.debug(getClass().getSimpleName() + ".send("
+ + "url=" + url
+ + " message=" + message
+ + ")");
+
+ LOGGER.info(MessageEnum.RA_CALLBACK_BPEL, message == null ? "[no content]" : message, "Camunda", "");
+
+ HttpPost method = null;
+ HttpResponse httpResponse = null;
+
+ try {
+ // TODO: configurable timeout?
+ int timeout = 60 * 1000;
+
+ RequestConfig requestConfig = RequestConfig.custom()
+ .setSocketTimeout(timeout)
+ .setConnectTimeout(timeout)
+ .setConnectionRequestTimeout(timeout)
+ .build();
+
+ HttpClient client = HttpClientBuilder.create().build();
+ method = new HttpPost(url);
+ method.setConfig(requestConfig);
+
+ if (message != null) {
+ method.setEntity(new StringEntity(message, ContentType.APPLICATION_JSON));
+ }
+
+ boolean error = false;
+
+ try {
+ // AAF Integration, disabled for now due to the constrains from other party
+ // String userCredentials = CredentialConstants.getDecryptedCredential(Constants.DEFAULT_BPEL_AUTH);
+ // Once AAF enabled, the credential shall be get by triggering the CredentialConstants.getDecryptedCredential -- remove line
+ String userCredentials = SDNCAdapterProperties.getEncryptedProperty(Constants.BPEL_AUTH_PROP,
+ Constants.DEFAULT_BPEL_AUTH, Constants.ENCRYPTION_KEY);
+ String authorization = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
+ method.setHeader("Authorization", authorization);
+ } catch (Exception e) {
+ LOGGER.error(MessageEnum.RA_SET_CALLBACK_AUTH_EXC, "Camunda", "", MsoLogger.ErrorCode.BusinessProcesssError,
+ "Unable to set authorization in callback request", e);
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL,
+ "Unable to set authorization in callback request: " + e.getMessage());
+ error = true;
+ }
+
+ if (!error) {
+ httpResponse = client.execute(method);
+
+ @SuppressWarnings("unused")
+ String responseContent = null;
+
+ if (httpResponse.getEntity() != null) {
+ responseContent = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
+ }
+
+ if (httpResponse.getStatusLine().getStatusCode() >= 300) {
+ String msg = "Received error response to callback request: " + httpResponse.getStatusLine();
+ LOGGER.error(MessageEnum.RA_CALLBACK_BPEL_EXC, "Camunda", "", MsoLogger.ErrorCode.BusinessProcesssError, msg);
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, msg);
+ }
+
+ httpResponse = null;
+ }
+
+ method.reset();
+ method = null;
+ return true;
+ } catch (Exception e) {
+ LOGGER.error(MessageEnum.RA_CALLBACK_BPEL_EXC, "Camunda", "", MsoLogger.ErrorCode.BusinessProcesssError,
+ "Error sending callback request", e);
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL,
+ "Error sending callback request: " + e.getMessage());
+ return false;
+ } finally {
+ if (httpResponse != null) {
+ try {
+ EntityUtils.consume(httpResponse.getEntity());
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+
+ if (method != null) {
+ try {
+ method.reset();
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+
+ LOGGER.info(MessageEnum.RA_CALLBACK_BPEL_COMPLETE, "Camunda", "");
+ }
+ }
+} \ No newline at end of file
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCAdapterProperties.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCAdapterProperties.java
new file mode 100644
index 0000000000..ba8fdfb936
--- /dev/null
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCAdapterProperties.java
@@ -0,0 +1,85 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.mso.adapters.sdnc.sdncrest;
+
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoLogger;
+import org.openecomp.mso.properties.MsoJavaProperties;
+import org.openecomp.mso.properties.MsoPropertiesException;
+import org.openecomp.mso.properties.MsoPropertiesFactory;
+
+/**
+ * Static methods to access SDNC adapter properties.
+ */
+public final class SDNCAdapterProperties {
+ private static final String MSO_PROPERTIES_ID = "MSO_PROP_SDNC_ADAPTER";
+ private static final MsoPropertiesFactory MSO_PROPERTIES_FACTORY = new MsoPropertiesFactory();
+ private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
+
+ /**
+ * Gets the value of an SDNC adapter property.
+ * @param key the property key
+ * @param defaultValue the default value to use if the property does not
+ * exist or if an error occurs
+ */
+ public static String getProperty(String key, String defaultValue) {
+ MsoJavaProperties properties;
+
+ try {
+ properties = MSO_PROPERTIES_FACTORY.getMsoJavaProperties(MSO_PROPERTIES_ID);
+ } catch (MsoPropertiesException e) {
+ LOGGER.error (MessageEnum.NO_PROPERTIES, "Unknown. Mso Properties ID not found in cache: " + MSO_PROPERTIES_ID,
+ "SDNC", "", MsoLogger.ErrorCode.DataError, "Exception - Mso Properties ID not found in cache", e);
+ return defaultValue;
+ }
+
+ String value = properties.getProperty(key, defaultValue);
+ LOGGER.debug("Config read for " + MSO_PROPERTIES_ID + " - key:" + key + " value:" + value);
+ return value;
+ }
+
+ /**
+ * Gets the value of an SDNC adapter property.
+ * @param key the property key
+ * @param defaultValue the default value to use if the property does not
+ * exist or if an error occurs
+ */
+ public static String getEncryptedProperty(String key, String defaultValue, String encryptionKey) {
+ MsoJavaProperties properties;
+
+ try {
+ properties = MSO_PROPERTIES_FACTORY.getMsoJavaProperties(MSO_PROPERTIES_ID);
+ } catch (MsoPropertiesException e) {
+ LOGGER.error (MessageEnum.NO_PROPERTIES, "Unknown. Mso Properties ID not found in cache: " + MSO_PROPERTIES_ID,
+ "SDNC", "", MsoLogger.ErrorCode.DataError, "Exception - Mso Properties ID not found in cache", e);
+ return defaultValue;
+ }
+
+ String value = properties.getEncryptedProperty(key, defaultValue, encryptionKey);
+ LOGGER.debug("Config read for " + MSO_PROPERTIES_ID + " - key:" + key);
+ return value;
+ }
+
+ /**
+ * Instantiation is not allowed.
+ */
+ private SDNCAdapterProperties() {
+ }
+} \ No newline at end of file
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCAdapterRest.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCAdapterRest.java
new file mode 100644
index 0000000000..c4ed50a1b1
--- /dev/null
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCAdapterRest.java
@@ -0,0 +1,239 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.mso.adapters.sdnc.sdncrest;
+
+import org.openecomp.mso.HealthCheckUtils;
+import org.openecomp.mso.adapters.sdnc.impl.Constants;
+import org.openecomp.mso.adapters.sdncrest.SDNCEvent;
+import org.openecomp.mso.adapters.sdncrest.SDNCResponseCommon;
+import org.openecomp.mso.adapters.sdncrest.SDNCServiceError;
+import org.openecomp.mso.adapters.sdncrest.SDNCServiceRequest;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoAlarmLogger;
+import org.openecomp.mso.logger.MsoLogger;
+import org.openecomp.mso.utils.UUIDChecker;
+import org.apache.http.HttpStatus;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.*;
+import javax.ws.rs.core.GenericEntity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.text.ParseException;
+
+/**
+ * SDNC REST adapter interface added in 1702 to support the SDNC "agnostic" API.
+ */
+@Path("/")
+public class SDNCAdapterRest {
+ private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
+ private static final MsoAlarmLogger ALARMLOGGER = new MsoAlarmLogger();
+
+ private static final String MSO_PROPERTIES_ID = "MSO_PROP_SDNC_ADAPTER";
+
+ @HEAD
+ @GET
+ @Path("/v1/sdnc/healthcheck")
+ @Produces(MediaType.TEXT_HTML)
+ public Response healthcheck(@QueryParam("requestId") String requestId) {
+ long startTime = System.currentTimeMillis();
+ MsoLogger.setServiceName("Healthcheck");
+ UUIDChecker.verifyOldUUID(requestId, LOGGER);
+ HealthCheckUtils healthCheck = new HealthCheckUtils();
+
+ if (!healthCheck.siteStatusCheck(LOGGER, startTime)) {
+ return HealthCheckUtils.HEALTH_CHECK_NOK_RESPONSE;
+ }
+
+ if (!healthCheck.configFileCheck(LOGGER, startTime, MSO_PROPERTIES_ID)) {
+ return HealthCheckUtils.NOT_STARTED_RESPONSE;
+ }
+
+ LOGGER.debug("healthcheck - Successful");
+ return HealthCheckUtils.HEALTH_CHECK_RESPONSE;
+ }
+
+ /**
+ * Processes an SDNCServiceRequest (a request for "agnostic" API services) from BP.
+ * @param request the request
+ * @param msoRequestId the request ID for the top-level MSO flow (used for logging only)
+ * @param msoServiceInstanceId the top-level service-instance-id (used for logging only)
+ */
+ @POST
+ @Path("/v1/sdnc/services")
+ @Consumes({MediaType.APPLICATION_JSON})
+ @Produces({MediaType.APPLICATION_JSON})
+ public Response service(
+ SDNCServiceRequest request,
+ @HeaderParam(value="att-mso-request-id") String msoRequestId,
+ @HeaderParam(value="att-mso-service-instance-id") String msoServiceInstanceId) {
+
+ MsoLogger.setLogContext(msoRequestId, msoServiceInstanceId);
+
+ try {
+ LOGGER.debug(getClass().getSimpleName() + ".service(request)"
+ + " entered with request: " + request.toJson());
+
+ SDNCServiceRequestTask task = new SDNCServiceRequestTask(request, msoRequestId,
+ msoServiceInstanceId, "/services");
+
+ try {
+ Thread thread = new Thread(task);
+ thread.start();
+ } catch (Exception e) {
+ String msg = "Failed to start thread to run SDNCServiceTask";
+ LOGGER.error(MessageEnum.RA_SEND_REQUEST_SDNC_ERR, "SDNC", "", MsoLogger.ErrorCode.BusinessProcesssError, msg, e);
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, msg);
+ SDNCServiceError error = new SDNCServiceError(request.getSDNCRequestId(),
+ String.valueOf(HttpStatus.SC_INTERNAL_SERVER_ERROR), e.toString(), "Y");
+ LOGGER.debug(getClass().getSimpleName() + ".service(request)"
+ + " exited with error: " + msg);
+ return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
+ .entity(new GenericEntity<SDNCServiceError>(error){})
+ .build();
+ }
+
+ // Send sync response to caller
+ LOGGER.debug(getClass().getSimpleName() + ".service(request)"
+ + " exited successfully");
+ return Response.status(HttpStatus.SC_ACCEPTED).build();
+ } catch (Exception e) {
+ String msg = "Caught " + e.getClass().getSimpleName() + " in 'service' method";
+ LOGGER.error(MessageEnum.RA_SEND_REQUEST_SDNC_ERR, "SDNC", "", MsoLogger.ErrorCode.BusinessProcesssError, msg, e);
+ LOGGER.debug(getClass().getSimpleName() + ".service(request)"
+ + " exited with error: " + msg);
+ SDNCServiceError error = new SDNCServiceError(request.getSDNCRequestId(),
+ String.valueOf(HttpStatus.SC_INTERNAL_SERVER_ERROR), e.toString(), "Y");
+ return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
+ .entity(new GenericEntity<SDNCServiceError>(error){})
+ .build();
+ }
+ }
+
+ /**
+ * Processes a notification from SDNC for "agnostic" API services.
+ * Note that the "myurl" configuration property specifies the path
+ * up to and including /SDNCNotify. The /services part of the path
+ * is added by this class.
+ * @param content the notification content
+ */
+ @POST
+ @Path("/SDNCNotify/services")
+ @Consumes({MediaType.APPLICATION_XML})
+ @Produces({MediaType.APPLICATION_XML})
+ public Response serviceNotification(String content) {
+ LOGGER.info(MessageEnum.RA_RECEIVE_SDNC_NOTIF, content, "SDNC", "SDNCNotify/services");
+
+ long startTime = System.currentTimeMillis();
+
+ try {
+ // Because the format of a notification is exactly the same as that of
+ // a synchronous response, we can use the same code to parse it.
+ SDNCResponseCommon response = SDNCServiceRequestConnector.parseResponseContent(content);
+
+ String bpUrl = SDNCAdapterProperties.getProperty(Constants.BPEL_REST_URL_PROP, null);
+
+ if (bpUrl == null) {
+ String error = "Missing configuration for: " + Constants.BPEL_REST_URL_PROP;
+ LOGGER.error(MessageEnum.RA_SDNC_MISS_CONFIG_PARAM, Constants.BPEL_REST_URL_PROP, "SDNC", "",
+ MsoLogger.ErrorCode.DataError, "Missing config param");
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+ return Response.status(HttpServletResponse.SC_BAD_REQUEST).entity(error).build();
+ }
+
+ long bpStartTime = System.currentTimeMillis();
+ BPRestCallback callback = new BPRestCallback();
+ boolean callbackSuccess = callback.send(bpUrl, "SDNCAResponse", response.getSDNCRequestId(), response.toJson());
+
+ if (callbackSuccess) {
+ LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
+ "Sent notification", "BPMN", bpUrl, null);
+ LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successful");
+ } else {
+ LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
+ "Failed to send notification", "BPMN", bpUrl, null);
+ LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
+ "Failed to send notification");
+ }
+
+ return Response.ok().build();
+ } catch (ParseException e) {
+ LOGGER.error(MessageEnum.RA_PARSING_REQUEST_ERROR, "SDNC", "SDNCNotify/services",
+ MsoLogger.ErrorCode.SchemaError, e.getMessage());
+ LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
+ MsoLogger.ResponseCode.SchemaError, e.getMessage());
+ return Response.status(HttpServletResponse.SC_BAD_REQUEST).entity(e.getMessage()).build();
+ }
+ }
+
+ /**
+ * Processes an event notification from SDNC.
+ * Note that the "myurl" configuration property specifies the path
+ * up to and including /SDNCNotify. The /activate part of the path
+ * is added by this class.
+ * @param content the notification content
+ */
+ @POST
+ @Path("/SDNCNotify/event")
+ @Consumes({MediaType.APPLICATION_XML})
+ @Produces({MediaType.APPLICATION_XML})
+ public Response eventNotification(String content) {
+ LOGGER.info(MessageEnum.RA_RECEIVE_SDNC_NOTIF, content, "SDNC", "SDNCNotify/event");
+
+ long startTime = System.currentTimeMillis();
+
+ try {
+ SDNCEvent event = SDNCEventParser.parse(content);
+
+ String bpUrl = SDNCAdapterProperties.getProperty(Constants.BPEL_REST_URL_PROP, null);
+
+ if (bpUrl == null) {
+ String error = "Missing configuration for: " + Constants.BPEL_REST_URL_PROP;
+ LOGGER.error(MessageEnum.RA_SDNC_MISS_CONFIG_PARAM, Constants.BPEL_REST_URL_PROP, "SDNC", "",
+ MsoLogger.ErrorCode.DataError, "Missing config param");
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+ return Response.status(HttpServletResponse.SC_BAD_REQUEST).entity(error).build();
+ }
+
+ long bpStartTime = System.currentTimeMillis();
+ BPRestCallback callback = new BPRestCallback();
+ boolean callbackSuccess = callback.send(bpUrl, "SDNCAEvent", event.getEventCorrelator(), event.toJson());
+
+ if (callbackSuccess) {
+ LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
+ "Sent notification", "BPMN", bpUrl, null);
+ LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successful");
+ } else {
+ LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
+ "Failed to send notification", "BPMN", bpUrl, null);
+ LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
+ "Failed to send notification");
+ }
+
+ return Response.ok().build();
+ } catch (ParseException e) {
+ LOGGER.error(MessageEnum.RA_PARSING_REQUEST_ERROR, "SDNC", "SDNCNotify/event",
+ MsoLogger.ErrorCode.SchemaError, e.getMessage());
+ LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
+ MsoLogger.ResponseCode.SchemaError, e.getMessage());
+ return Response.status(HttpServletResponse.SC_BAD_REQUEST).entity(e.getMessage()).build();
+ }
+ }
+} \ No newline at end of file
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCAdapterUtils.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCAdapterUtils.java
new file mode 100644
index 0000000000..d97f340a7c
--- /dev/null
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCAdapterUtils.java
@@ -0,0 +1,70 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.mso.adapters.sdnc.sdncrest;
+
+import org.springframework.web.util.UriUtils;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility methods used by SDNCAdapterRest.
+ */
+public final class SDNCAdapterUtils {
+ /**
+ * Returns a node's child elements in a list.
+ */
+ public static List<Element> childElements(Node node) {
+ List<Element> elements = new ArrayList<Element>();
+
+ NodeList nodeList = node.getChildNodes();
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ Node child = nodeList.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ elements.add((Element) child);
+ }
+ }
+
+ return elements;
+ }
+
+ /**
+ * Encodes a URL path segment according to RFC 3986 Section 2.
+ * @param pathSegment the path segment to encode
+ * @return the encoded path segment
+ */
+ public static String encodeURLPathSegment(String pathSegment) {
+ try {
+ return UriUtils.encodePathSegment(pathSegment, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 encoding is not supported");
+ }
+ }
+
+ /**
+ * Instantiation is not allowed.
+ */
+ private SDNCAdapterUtils() {
+ }
+} \ No newline at end of file
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCConnector.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCConnector.java
new file mode 100644
index 0000000000..26c186599c
--- /dev/null
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCConnector.java
@@ -0,0 +1,309 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.mso.adapters.sdnc.sdncrest;
+
+import org.openecomp.mso.adapters.sdnc.impl.Constants;
+import org.openecomp.mso.adapters.sdncrest.SDNCErrorCommon;
+import org.openecomp.mso.adapters.sdncrest.SDNCResponseCommon;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoAlarmLogger;
+import org.openecomp.mso.logger.MsoLogger;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.*;
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.DatatypeConverter;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import java.io.StringReader;
+import java.net.HttpURLConnection;
+import java.net.SocketTimeoutException;
+
+/**
+ * Sends requests to SDNC and processes the responses.
+ */
+public abstract class SDNCConnector {
+ private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
+ private static final MsoAlarmLogger ALARMLOGGER = new MsoAlarmLogger();
+
+ public SDNCResponseCommon send(String content, TypedRequestTunables rt) {
+ LOGGER.info(MessageEnum.RA_SEND_REQUEST_SDNC, rt.toString(), "SDNC", "");
+ LOGGER.debug("SDNC Request Body:\n" + content);
+
+ HttpRequestBase method = null;
+ HttpResponse httpResponse = null;
+
+ try {
+ int timeout = Integer.parseInt(rt.getTimeout());
+
+ RequestConfig requestConfig = RequestConfig.custom()
+ .setSocketTimeout(timeout)
+ .setConnectTimeout(timeout)
+ .setConnectionRequestTimeout(timeout)
+ .build();
+
+ HttpClient client = HttpClientBuilder.create().build();
+
+ if ("POST".equals(rt.getReqMethod())) {
+ HttpPost httpPost = new HttpPost(rt.getSdncUrl());
+ httpPost.setConfig(requestConfig);
+ httpPost.setEntity(new StringEntity(content, ContentType.APPLICATION_XML));
+ method = httpPost;
+ } else if ("PUT".equals(rt.getReqMethod())) {
+ HttpPut httpPut = new HttpPut(rt.getSdncUrl());
+ httpPut.setConfig(requestConfig);
+ httpPut.setEntity(new StringEntity(content, ContentType.APPLICATION_XML));
+ method = httpPut;
+ } else if ("GET".equals(rt.getReqMethod())) {
+ HttpGet httpGet = new HttpGet(rt.getSdncUrl());
+ httpGet.setConfig(requestConfig);
+ method = httpGet;
+ } else if ("DELETE".equals(rt.getReqMethod())) {
+ HttpDelete httpDelete = new HttpDelete(rt.getSdncUrl());
+ httpDelete.setConfig(requestConfig);
+ method = httpDelete;
+ }
+
+ // AAF Integration, disabled for now due to the constrains from other party
+ // String userCredentials = CredentialConstants.getSecurityProperties().getEncryptedProperty(CredentialConstants.DEFAULT_AUTH, "", CredentialConstants.getEncryptionKey());
+ // if (userCredentials == null) {
+ // userCredentials = "";
+ //}
+ String userCredentials = SDNCAdapterProperties.getEncryptedProperty(Constants.SDNC_AUTH_PROP,
+ Constants.DEFAULT_SDNC_AUTH, Constants.ENCRYPTION_KEY);
+ String authorization = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
+ method.setHeader("Authorization", authorization);
+
+ method.setHeader("Accept", "application/yang.data+xml");
+
+ httpResponse = client.execute(method);
+
+ String responseContent = null;
+ if (httpResponse.getEntity() != null) {
+ responseContent = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
+ }
+
+ int statusCode = httpResponse.getStatusLine().getStatusCode();
+ String statusMessage = httpResponse.getStatusLine().getReasonPhrase();
+
+ LOGGER.debug("SDNC Response: " + statusCode + " " + statusMessage
+ + (responseContent == null ? "" : System.lineSeparator() + responseContent));
+
+ if (httpResponse.getStatusLine().getStatusCode() >= 300) {
+ String errMsg = "SDNC returned " + statusCode + " " + statusMessage;
+
+ String errors = analyzeErrors(responseContent);
+ if (errors != null) {
+ errMsg += " " + errors;
+ }
+
+ logError(errMsg);
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, errMsg);
+ return createErrorResponse(statusCode, errMsg, rt);
+ }
+
+ httpResponse = null;
+
+ method.reset();
+ method = null;
+
+ LOGGER.info(MessageEnum.RA_RESPONSE_FROM_SDNC, responseContent, "SDNC", "");
+ return createResponseFromContent(statusCode, statusMessage, responseContent, rt);
+
+ } catch (SocketTimeoutException e) {
+ String errMsg = "Request to SDNC timed out";
+ logError(errMsg, e);
+ return createErrorResponse(HttpURLConnection.HTTP_CLIENT_TIMEOUT, errMsg, rt);
+
+ } catch (ConnectTimeoutException e) {
+ String errMsg = "Request to SDNC timed out";
+ logError(errMsg, e);
+ return createErrorResponse(HttpURLConnection.HTTP_CLIENT_TIMEOUT, errMsg, rt);
+
+ } catch (Exception e) {
+ String errMsg = "Error processing request to SDNC";
+ logError(errMsg, e);
+ return createErrorResponse(HttpURLConnection.HTTP_INTERNAL_ERROR, errMsg, rt);
+
+ } finally {
+ if (httpResponse != null) {
+ try {
+ EntityUtils.consume(httpResponse.getEntity());
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+
+ if (method != null) {
+ try {
+ method.reset();
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ }
+ }
+
+ protected void logError(String errMsg) {
+ LOGGER.error(MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC, "SDNC", "",
+ MsoLogger.ErrorCode.AvailabilityError, errMsg);
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, errMsg);
+ }
+
+ protected void logError(String errMsg, Throwable t) {
+ LOGGER.error(MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC, "SDNC", "",
+ MsoLogger.ErrorCode.AvailabilityError, errMsg, t);
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, errMsg);
+ }
+
+ /**
+ * Generates a response object from content received from SDNC. The response
+ * object may be a success response object or an error response object. This
+ * method must be overridden by the subclass to return the correct object type.
+ * @param statusCode the response status code from SDNC (e.g. 200)
+ * @param statusMessage the response status message from SDNC (e.g. "OK")
+ * @param responseContent the body of the response from SDNC (possibly null)
+ * @param rt request tunables
+ * @return a response object
+ */
+ protected abstract SDNCResponseCommon createResponseFromContent(int statusCode,
+ String statusMessage, String responseContent, TypedRequestTunables rt);
+
+ /**
+ * Generates an error response object. This method must be overridden by the
+ * subclass to return the correct object type.
+ * @param statusCode the response status code (from SDNC, or internally generated)
+ * @param errMsg the error message (normally a verbose explanation of the error)
+ * @param rt request tunables
+ * @return an error response object
+ */
+ protected abstract SDNCErrorCommon createErrorResponse(int statusCode,
+ String errMsg, TypedRequestTunables rt);
+
+ /**
+ * Called by the send() method to analyze errors that may be encoded in the
+ * content of non-2XX responses. By default, this method tries to parse the
+ * content as a restconf error.
+ * <pre>
+ * xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf"
+ * </pre>
+ * If an error (or errors) can be obtained from the content, then the result
+ * is a string in this format:
+ * <pre>
+ * [error-type:TYPE, error-tag:TAG, error-message:MESSAGE] ...
+ * </pre>
+ * If no error could be obtained from the content, then the result is null.
+ * <p>
+ * The subclass can override this method to provide another implementation.
+ */
+ protected String analyzeErrors(String content) {
+ if (content == null || content.isEmpty()) {
+ return null;
+ }
+
+ // Confirmed with Andrew Shen on 11/1/16 that SDNC will send content like
+ // this in error responses (non-2XX response codes) to "agnostic" service
+ // requests.
+ //
+ // <errors xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
+ // <error>
+ // <error-type>protocol</error-type>
+ // <error-tag>malformed-message</error-tag>
+ // <error-message>Error parsing input: The element type "input" must be terminated by the matching end-tag "&lt;/input&gt;".</error-message>
+ // </error>
+ // </errors>
+
+ String output = null;
+
+ try {
+ XPathFactory xpathFactory = XPathFactory.newInstance();
+ XPath xpath = xpathFactory.newXPath();
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ InputSource source = new InputSource(new StringReader(content));
+ Document doc = documentBuilderFactory.newDocumentBuilder().parse(source);
+ 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 info = "";
+
+ try {
+ String errorType = xpath.evaluate("error-type", error);
+ info += "error-type:" + errorType;
+ } catch (XPathExpressionException e) {
+ LOGGER.error(MessageEnum.RA_EVALUATE_XPATH_ERROR, "error-type", error.toString(), "SDNC", "",
+ MsoLogger.ErrorCode.DataError, "XPath Exception", e);
+ }
+
+ try {
+ String errorTag = xpath.evaluate( "error-tag", error);
+ if (!info.isEmpty()) {
+ info += ", ";
+ }
+ info += "error-tag:" + errorTag;
+ } catch (XPathExpressionException e) {
+ LOGGER.error(MessageEnum.RA_EVALUATE_XPATH_ERROR, "error-tag", error.toString(), "SDNC", "",
+ MsoLogger.ErrorCode.DataError, "XPath Exception", e);
+ }
+
+ try {
+ String errorMessage = xpath.evaluate("error-message", error);
+ if (!info.isEmpty()) {
+ info += ", ";
+ }
+ info += "error-message:" + errorMessage;
+ } catch (Exception e) {
+ LOGGER.error(MessageEnum.RA_EVALUATE_XPATH_ERROR, "error-message", error.toString(), "SDNC", "",
+ MsoLogger.ErrorCode.DataError, "XPath Exception", e);
+ }
+
+ if (!info.isEmpty()) {
+ if (output == null) {
+ output = "[" + info + "]";
+ } else {
+ output += " [" + info + "]";
+ }
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.error (MessageEnum.RA_ANALYZE_ERROR_EXC, "SDNC", "",
+ MsoLogger.ErrorCode.DataError, "Exception while analyzing errors", e);
+ }
+
+ return output;
+ }
+}
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCEventParser.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCEventParser.java
new file mode 100644
index 0000000000..9808f48e7e
--- /dev/null
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCEventParser.java
@@ -0,0 +1,156 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.mso.adapters.sdnc.sdncrest;
+
+import org.openecomp.mso.adapters.sdncrest.SDNCEvent;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.StringReader;
+import java.text.ParseException;
+
+/**
+ * SDNCConnector for "agnostic" API services.
+ */
+public class SDNCEventParser {
+ /**
+ * Parses SDNC event XML. If the content can be parsed and contains all required
+ * elements, then an object is returned. Otherwise, a ParseException is thrown.
+ * This method performs no logging or alarming.
+ * @throws ParseException on error
+ */
+ public static SDNCEvent parse(String content) throws ParseException {
+ try {
+ // Note: this document builder is not namespace-aware, so namespaces are ignored.
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ InputSource source = new InputSource(new StringReader(content));
+ Document doc = documentBuilderFactory.newDocumentBuilder().parse(source);
+
+ // Find the configuration-event child under the root element.
+ // The root element is expected to be an "output" element, but we don't really care.
+
+ Element root = doc.getDocumentElement();
+ Element configurationEvent = null;
+
+ for (Element child : SDNCAdapterUtils.childElements(root)) {
+ if ("configuration-event".equals(child.getNodeName())) {
+ configurationEvent = child;
+ break;
+ }
+ }
+
+ if (configurationEvent == null) {
+ throw new ParseException("No configuration-event element in SDNC event", 0);
+ }
+
+ // Process the children of configuration-event
+
+ String eventType = null;
+ String eventCorrelatorType = null;
+ String eventCorrelator = null;
+ Element eventParameters = null;
+
+ for (Element child : SDNCAdapterUtils.childElements(configurationEvent)) {
+ if ("event-type".equals(child.getNodeName())) {
+ eventType = child.getTextContent();
+ } else if ("event-correlator-type".equals(child.getNodeName())) {
+ eventCorrelatorType = child.getTextContent();
+ } else if ("event-correlator".equals(child.getNodeName())) {
+ eventCorrelator = child.getTextContent();
+ } else if ("event-parameters".equals(child.getNodeName())) {
+ eventParameters = (Element) child;
+ }
+ }
+
+ // event-type is mandatory.
+
+ if (eventType == null || eventType.isEmpty()) {
+ throw new ParseException("No event-type in SDNC event", 0);
+ }
+
+ // event-correlator-type is mandatory.
+
+ if (eventCorrelatorType == null || eventCorrelatorType.isEmpty()) {
+ throw new ParseException("No event-correlator-type in SDNC event", 0);
+ }
+
+ // event-correlator is mandatory.
+
+ if (eventCorrelator == null || eventCorrelator.isEmpty()) {
+ throw new ParseException("No event-correlator in SDNC event", 0);
+ }
+
+ // Create an event object.
+
+ SDNCEvent event = new SDNCEvent(eventType, eventCorrelatorType, eventCorrelator);
+
+ // event-parameters is an optional container element. If present,
+ // process its children, adding values to the event object.
+
+ if (eventParameters != null) {
+ for (Element element : SDNCAdapterUtils.childElements(eventParameters)) {
+ if (!"event-parameter".equals(element.getNodeName())) {
+ continue;
+ }
+
+ String tagName = null;
+ String tagValue = null;
+
+ for (Element child : SDNCAdapterUtils.childElements(element)) {
+ if ("tag-name".equals(child.getNodeName())) {
+ tagName = child.getTextContent();
+ } else if ("tag-value".equals(child.getNodeName())) {
+ tagValue = child.getTextContent();
+ }
+ }
+
+ // tag-name is mandatory
+
+ if (tagName == null) {
+ throw new ParseException("Missing tag-name in SDNC event parameter", 0);
+ }
+
+ // tag-value is optional. If absent, make it an empty string so we don't
+ // end up with null values in the parameter map.
+
+ if (tagValue == null) {
+ tagValue = "";
+ }
+
+ event.addParam(tagName, tagValue);
+ }
+ }
+
+ return event;
+ } catch (ParseException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ParseException("Failed to parse SDNC event", 0);
+ }
+ }
+
+ // Instantiation is not allowed.
+ private SDNCEventParser() {
+ }
+} \ No newline at end of file
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCServiceRequestConnector.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCServiceRequestConnector.java
new file mode 100644
index 0000000000..bd864d085a
--- /dev/null
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCServiceRequestConnector.java
@@ -0,0 +1,194 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.mso.adapters.sdnc.sdncrest;
+
+import org.openecomp.mso.adapters.sdncrest.SDNCErrorCommon;
+import org.openecomp.mso.adapters.sdncrest.SDNCResponseCommon;
+import org.openecomp.mso.adapters.sdncrest.SDNCServiceError;
+import org.openecomp.mso.adapters.sdncrest.SDNCServiceResponse;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.StringReader;
+import java.net.HttpURLConnection;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * SDNCConnector for "agnostic" API services.
+ */
+public class SDNCServiceRequestConnector extends SDNCConnector {
+
+ @Override
+ protected SDNCResponseCommon createResponseFromContent(int statusCode, String statusMessage,
+ String responseContent, TypedRequestTunables rt) {
+ try {
+ return parseResponseContent(responseContent);
+ } catch (ParseException e) {
+ logError(e.getMessage());
+ return createErrorResponse(HttpURLConnection.HTTP_INTERNAL_ERROR, e.getMessage(), rt);
+ }
+ }
+
+ @Override
+ protected SDNCErrorCommon createErrorResponse(int statusCode, String errMsg,
+ TypedRequestTunables rt) {
+ return new SDNCServiceError(rt.getReqId(), String.valueOf(statusCode), errMsg, "Y");
+ }
+
+ /**
+ * Parses SDNC synchronous service response content or service notification content.
+ * If the content can be parsed and contains all required elements, then an object
+ * is returned. The type of the returned object depends on the response code
+ * contained in the content. For 2XX response codes, an SDNCServiceResponse is
+ * returned. Otherwise, an SDNCServiceError is returned. If the content cannot
+ * be parsed, or if the content does not contain all required elements, a parse
+ * exception is thrown. This method performs no logging or alarming.
+ * @throws ParseException on error
+ */
+ public static SDNCResponseCommon parseResponseContent(String responseContent)
+ throws ParseException {
+ try {
+ // Note: this document builder is not namespace-aware, so namespaces are ignored.
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ InputSource source = new InputSource(new StringReader(responseContent));
+ Document doc = documentBuilderFactory.newDocumentBuilder().parse(source);
+
+ // Find the configuration-response-common child under the root element.
+ // The root element is expected to be an "output" element, but we don't really care.
+
+ Element root = doc.getDocumentElement();
+ Element configurationResponseCommon = null;
+
+ for (Element child : SDNCAdapterUtils.childElements(root)) {
+ if ("configuration-response-common".equals(child.getNodeName())) {
+ configurationResponseCommon = child;
+ break;
+ }
+ }
+
+ if (configurationResponseCommon == null) {
+ throw new ParseException("No configuration-response-common element in SDNC response", 0);
+ }
+
+ // Process the children of configuration-response-common.
+
+ String responseCode = null;
+ String responseMessage = null;
+ String svcRequestId = null;
+ String ackFinalIndicator = null;
+ List<Element> responseParameters = new ArrayList<Element>();
+
+ for (Element child : SDNCAdapterUtils.childElements(configurationResponseCommon)) {
+ if ("response-code".equals(child.getNodeName())) {
+ responseCode = child.getTextContent();
+ } else if ("response-message".equals(child.getNodeName())) {
+ responseMessage = child.getTextContent();
+ } else if ("svc-request-id".equals(child.getNodeName())) {
+ svcRequestId = child.getTextContent();
+ } else if ("ack-final-indicator".equals(child.getNodeName())) {
+ ackFinalIndicator = child.getTextContent();
+ } else if ("response-parameters".equals(child.getNodeName())) {
+ responseParameters.add((Element) child);
+ }
+ }
+
+ // svc-request-id is mandatory.
+
+ if (svcRequestId == null || svcRequestId.isEmpty()) {
+ throw new ParseException("No svc-request-id in SDNC response", 0);
+ }
+
+ // response-code is mandatory.
+
+ if (responseCode == null || responseCode.isEmpty()) {
+ throw new ParseException("No response-code in SDNC response", 0);
+ }
+
+ // ack-final-indicator is optional: default to "Y".
+
+ if (ackFinalIndicator == null) {
+ ackFinalIndicator = "Y";
+ }
+
+ if (!ackFinalIndicator.equals("Y") && !ackFinalIndicator.equals("N")) {
+ throw new ParseException("Invalid ack-final-indicator in SDNC response: '" + ackFinalIndicator + "'", 0);
+ }
+
+ // response-message is optional. If the value is empty, omit it from the response object.
+
+ if (responseMessage != null && responseMessage.isEmpty()) {
+ responseMessage = null;
+ }
+
+ // If the response code in the message from SDNC was not 2XX, return SDNCServiceError.
+
+ if (!responseCode.matches("2[0-9][0-9]")) {
+ // Not a 2XX response. Return SDNCServiceError.
+ return new SDNCServiceError(svcRequestId, responseCode, responseMessage, ackFinalIndicator);
+ }
+
+ // Create a success response object.
+
+ SDNCServiceResponse response = new SDNCServiceResponse(svcRequestId,
+ responseCode, responseMessage, ackFinalIndicator);
+
+ // Process any response-parameters that might be present.
+
+ for (Element element : responseParameters) {
+ String tagName = null;
+ String tagValue = null;
+
+ for (Element child : SDNCAdapterUtils.childElements(element)) {
+ if ("tag-name".equals(child.getNodeName())) {
+ tagName = child.getTextContent();
+ } else if ("tag-value".equals(child.getNodeName())) {
+ tagValue = child.getTextContent();
+ }
+ }
+
+ // tag-name is mandatory
+
+ if (tagName == null) {
+ throw new ParseException("Missing tag-name in SDNC response parameter", 0);
+ }
+
+ // tag-value is optional. If absent, make it an empty string so we don't
+ // end up with null values in the parameter map.
+
+ if (tagValue == null) {
+ tagValue = "";
+ }
+
+ response.addParam(tagName, tagValue);
+ }
+ return response;
+ } catch (ParseException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ParseException("Failed to parse SDNC response", 0);
+ }
+ }
+}
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCServiceRequestTask.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCServiceRequestTask.java
new file mode 100644
index 0000000000..e52a426b4d
--- /dev/null
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SDNCServiceRequestTask.java
@@ -0,0 +1,205 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.mso.adapters.sdnc.sdncrest;
+
+import org.openecomp.mso.adapters.sdncrest.SDNCErrorCommon;
+import org.openecomp.mso.adapters.sdncrest.SDNCResponseCommon;
+import org.openecomp.mso.adapters.sdncrest.SDNCServiceError;
+import org.openecomp.mso.adapters.sdncrest.SDNCServiceRequest;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoLogger;
+import org.apache.http.HttpStatus;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.StringWriter;
+
+public class SDNCServiceRequestTask implements Runnable {
+ private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
+
+ private final SDNCServiceRequest request;
+ private final String msoRequestId;
+ private final String msoServiceInstanceId;
+ private final String myUrlSuffix;
+
+ public SDNCServiceRequestTask(SDNCServiceRequest request,
+ String msoRequestId, String msoServiceInstanceId,
+ String myUrlSuffix) {
+ this.request = request;
+ this.msoRequestId = msoRequestId;
+ this.msoServiceInstanceId = msoServiceInstanceId;
+ this.myUrlSuffix = myUrlSuffix;
+ }
+
+ @Override
+ public void run()
+ {
+ MsoLogger.setLogContext(msoRequestId, msoServiceInstanceId);
+ MsoLogger.setServiceName(getClass().getSimpleName());
+
+ LOGGER.debug(getClass().getSimpleName() + ".run()"
+ + " entered with request: " + request.toJson());
+
+ String sdncRequestId = request.getSDNCRequestId();
+ String sdncService = request.getSDNCService();
+ String sdncOperation = request.getSDNCOperation();
+
+ TypedRequestTunables rt = new TypedRequestTunables(sdncRequestId, myUrlSuffix);
+ rt.setServiceKey(sdncService, sdncOperation);
+
+ if (!rt.setTunables()) {
+ // Note that the error was logged and alarmed by setTunables()
+ SDNCServiceError error = new SDNCServiceError(request.getSDNCRequestId(),
+ String.valueOf(HttpStatus.SC_INTERNAL_SERVER_ERROR), rt.getError(), "Y");
+ BPRestCallback callback = new BPRestCallback();
+ callback.send(request.getBPNotificationUrl(), error.toJson());
+ return;
+ }
+
+ String xml = genSdncReq(request, rt);
+
+ long sdncStartTime = System.currentTimeMillis();
+ SDNCConnector connector = new SDNCServiceRequestConnector();
+ SDNCResponseCommon response = connector.send(xml, rt);
+
+ if (response instanceof SDNCErrorCommon) {
+ LOGGER.recordMetricEvent(sdncStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
+ "Received success response from SDNC", "SDNC", sdncService + "." + sdncOperation, null);
+ } else {
+ LOGGER.recordMetricEvent(sdncStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
+ "Received error response from SDNC", "SDNC", sdncService + "." + sdncOperation, null);
+ }
+
+ long bpStartTime = System.currentTimeMillis();
+ BPRestCallback callback = new BPRestCallback();
+ boolean callbackSuccess = callback.send(request.getBPNotificationUrl(), response.toJson());
+
+ if (callbackSuccess) {
+ LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
+ "Sent notification", "BPMN", request.getBPNotificationUrl(), null);
+ } else {
+ LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
+ "Failed to send notification", "BPMN", request.getBPNotificationUrl(), null);
+ }
+ }
+
+ private Element addChild(Element parent, String tag) {
+ Element child = parent.getOwnerDocument().createElement(tag);
+ parent.appendChild(child);
+ return child;
+ }
+
+ private void addTextChild(Element parent, String tag, String text) {
+ if (text != null) {
+ Element child = parent.getOwnerDocument().createElement(tag);
+ child.setTextContent(text);
+ parent.appendChild(child);
+ }
+ }
+
+ private String genSdncReq(SDNCServiceRequest request, TypedRequestTunables rt) {
+ Document doc;
+
+ try {
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+
+ doc = documentBuilder.newDocument();
+ Element root = doc.createElementNS(rt.getNamespace(), "input");
+ doc.appendChild(root);
+
+ Element hdr = addChild(root, rt.getHeaderName());
+ addTextChild(hdr, "svc-request-id", rt.getReqId());
+ addTextChild(hdr, "svc-notification-url", rt.getMyUrl());
+
+ Element requestInformation = addChild(root, "request-information");
+ addTextChild(requestInformation, "request-id", request.getRequestInformation().getRequestId());
+ addTextChild(requestInformation, "source", request.getRequestInformation().getSource());
+ addTextChild(requestInformation, "notification-url", request.getRequestInformation().getNotificationUrl());
+
+ Element serviceInformation = addChild(root, "service-information");
+ addTextChild(serviceInformation, "service-type", request.getServiceInformation().getServiceType());
+ addTextChild(serviceInformation, "service-instance-id", request.getServiceInformation().getServiceInstanceId());
+ addTextChild(serviceInformation, "subscriber-name", request.getServiceInformation().getSubscriberName());
+ addTextChild(serviceInformation, "subscriber-global-id", request.getServiceInformation().getSubscriberGlobalId());
+
+ Element agnosticServiceInformation = addChild(root, "agnostic-service-information");
+ addTextChild(agnosticServiceInformation, "operation", request.getSDNCOperation());
+ addTextChild(agnosticServiceInformation, "service", request.getSDNCService());
+
+ // anydata is mandatory in the SDNC schema, so if the data we got is null,
+ // set use an empty string instead to ensure we generate an empty element.
+
+ String anydata = request.getSDNCServiceData();
+ if (anydata == null) {
+ anydata = "";
+ }
+
+ // content-type is also mandatory.
+
+ String contentType = request.getSDNCServiceDataType();
+
+ if (contentType == null || contentType.isEmpty()) {
+ if (anydata.isEmpty()) {
+ contentType = "XML";
+ } else {
+ if (anydata.startsWith("<")) {
+ contentType = "XML";
+ } else {
+ contentType = "JSON";
+ }
+ }
+ }
+
+ addTextChild(agnosticServiceInformation, "content-type", contentType);
+ addTextChild(agnosticServiceInformation, "anydata", anydata);
+ } catch (Exception e) {
+ LOGGER.error(MessageEnum.RA_ERROR_CREATE_SDNC_REQUEST, "SDNC", "",
+ MsoLogger.ErrorCode.BusinessProcesssError, "Exception in genSdncReq", e);
+ return null;
+ }
+
+ String xml;
+
+ try {
+ StringWriter writer = new StringWriter();
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+ transformer.transform(new DOMSource(doc), new StreamResult(writer));
+ xml = writer.toString();
+ } catch (Exception e) {
+ LOGGER.error(MessageEnum.RA_ERROR_CONVERT_XML2STR, "", "",
+ MsoLogger.ErrorCode.DataError, "Exception - domToStr", e);
+ return(null);
+ }
+
+ LOGGER.debug("Formatted SDNC service request XML:\n" + xml);
+ return xml;
+ }
+}
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SNIROResponse.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SNIROResponse.java
new file mode 100644
index 0000000000..2045b8c353
--- /dev/null
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/SNIROResponse.java
@@ -0,0 +1,78 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.mso.adapters.sdnc.sdncrest;
+
+import org.openecomp.mso.adapters.sdnc.impl.Constants;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoAlarmLogger;
+import org.openecomp.mso.logger.MsoLogger;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+/**
+ * A temporary interface to support notifications from SNIRO to BPMN.
+ * We added this to the SDNC adapter because we didn't have time to
+ * develop a SNIRO adapter in 1702.
+ */
+@Path("/")
+public class SNIROResponse {
+ private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
+ private static final MsoAlarmLogger ALARMLOGGER = new MsoAlarmLogger();
+
+ @POST
+ @Path("/SDNCNotify/SNIROResponse/{correlator}")
+ @Consumes("*/*")
+ @Produces({MediaType.TEXT_PLAIN})
+ public Response serviceNotification(@PathParam("correlator") String correlator, String content) {
+ LOGGER.info(MessageEnum.RA_RECEIVE_SDNC_NOTIF, content, "SDNC", "SDNCNotify/SNIROResponse");
+
+ long startTime = System.currentTimeMillis();
+
+ String bpUrl = SDNCAdapterProperties.getProperty(Constants.BPEL_REST_URL_PROP, null);
+
+ if (bpUrl == null) {
+ String error = "Missing configuration for: " + Constants.BPEL_REST_URL_PROP;
+ LOGGER.error(MessageEnum.RA_SDNC_MISS_CONFIG_PARAM, Constants.BPEL_REST_URL_PROP, "SDNC", "",
+ MsoLogger.ErrorCode.DataError, "Missing config param");
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+ return Response.status(HttpServletResponse.SC_BAD_REQUEST).entity(error).build();
+ }
+
+ long bpStartTime = System.currentTimeMillis();
+ BPRestCallback callback = new BPRestCallback();
+ boolean callbackSuccess = callback.send(bpUrl, "SNIROResponse", correlator, content);
+
+ if (callbackSuccess) {
+ LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
+ "Sent notification", "BPMN", bpUrl, null);
+ LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successful");
+ } else {
+ LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
+ "Failed to send notification", "BPMN", bpUrl, null);
+ LOGGER.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
+ "Failed to send notification");
+ }
+
+ return Response.status(204).build();
+ }
+} \ No newline at end of file
diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/TypedRequestTunables.java b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/TypedRequestTunables.java
new file mode 100644
index 0000000000..4c270cee60
--- /dev/null
+++ b/adapters/mso-sdnc-adapter/src/main/java/org/openecomp/mso/adapters/sdnc/sdncrest/TypedRequestTunables.java
@@ -0,0 +1,224 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.mso.adapters.sdnc.sdncrest;
+
+import org.openecomp.mso.adapters.sdnc.impl.Constants;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoAlarmLogger;
+import org.openecomp.mso.logger.MsoLogger;
+import org.openecomp.mso.properties.MsoJavaProperties;
+import org.openecomp.mso.properties.MsoPropertiesException;
+import org.openecomp.mso.properties.MsoPropertiesFactory;
+
+/**
+ * Typed Request Tunables. Each entry is identified by a TYPE in the property name.
+ * Different types can have different keys.
+ * <p>
+ * General format:
+ * <pre>
+ * org.openecomp.mso.adapters.sdnc.TYPE.KEY1[.KEY2...]=METHOD|TIMEOUT|URL|HEADER|NAMESPACE
+ * </pre>
+ * Currently supported type(s): service
+ * <pre>
+ * org.openecomp.mso.adapters.sdnc.service.SERVICE.OPERATION=METHOD|TIMEOUT|URL|HEADER|NAMESPACE
+ * </pre>
+ */
+public class TypedRequestTunables {
+
+ private static final String MSO_PROPERTIES_ID = "MSO_PROP_SDNC_ADAPTER";
+
+ private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
+ private static final MsoAlarmLogger ALARMLOGGER = new MsoAlarmLogger();
+
+ private final MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();
+
+ private final String reqId;
+ private final String myUrlSuffix;
+ private String key = null;
+ private String error = null;
+
+ // tunables (all are required)
+ private String reqMethod = null;
+ private String timeout = null;
+ private String sdncUrl = null;
+ private String headerName = null;
+ private String namespace = null;
+ private String myUrl = null;
+
+ public TypedRequestTunables(String reqId, String myUrlSuffix) {
+ this.reqId = reqId;
+ this.myUrlSuffix = myUrlSuffix;
+ }
+
+ /**
+ * Sets the key for a service request:
+ * <pre>
+ * org.openecomp.mso.adapters.sdnc.service.SERVICE.OPERATION
+ * </pre>
+ * @param service the sdncService
+ * @param operation the sdncOperation
+ */
+ public void setServiceKey(String service, String operation) {
+ key = Constants.REQUEST_TUNABLES + ".service." + service + "." + operation;
+ LOGGER.debug("Generated " + getClass().getSimpleName() + " key: " + key);
+ }
+
+ /**
+ * Gets the SDNC request ID.
+ */
+ public String getReqId() {
+ return reqId;
+ }
+
+ /**
+ * Gets the generated key.
+ */
+ public String getKey() {
+ return key;
+ }
+
+ /**
+ * Gets the most recent error, or null if there was no error.
+ */
+ public String getError() {
+ return error;
+ }
+
+ public String getReqMethod() {
+ return reqMethod;
+ }
+
+ public String getTimeout() {
+ return timeout;
+ }
+
+ public String getSdncUrl() {
+ return sdncUrl;
+ }
+
+ public String getHeaderName() {
+ return headerName;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ /**
+ * Gets the SDNC adapter notification URL, trimmed of trailing '/' characters.
+ */
+ public String getMyUrl() {
+ return myUrl;
+ }
+
+ /**
+ * Returns true if successful. If there is an error, it is logged and alarmed.
+ * The error description may be retrieved by calling getError().
+ */
+ public boolean setTunables() {
+ error = null;
+ MsoJavaProperties properties;
+
+ try {
+ properties = msoPropertiesFactory.getMsoJavaProperties(MSO_PROPERTIES_ID);
+ } catch (MsoPropertiesException e) {
+ error = "Mso Properties ID not found in cache: " + MSO_PROPERTIES_ID;
+ LOGGER.error(MessageEnum.LOAD_PROPERTIES_FAIL, "Unknown. " + error, "SDNC", "",
+ MsoLogger.ErrorCode.DataError, "Exception - Mso Properties ID not found in cache", e);
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+ return false;
+ }
+
+ String value = properties.getProperty(key, "");
+
+ if (value.equals("")) {
+ error = "Missing configuration for: " + key;
+ LOGGER.error(MessageEnum.RA_SDNC_MISS_CONFIG_PARAM, key, "SDNC", "", MsoLogger.ErrorCode.DataError, "Missing config param");
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+ return false;
+ }
+
+ String[] parts = value.split("\\|");
+
+ if (parts.length != 5) {
+ error = "Invalid configuration for: " + key;
+ LOGGER.error(MessageEnum.RA_SDNC_INVALID_CONFIG, key, value, "SDNC", "", MsoLogger.ErrorCode.DataError, "Invalid config");
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+ return false;
+ }
+
+ reqMethod = parts[0];
+ LOGGER.debug("Request Method is set to: " + reqMethod);
+
+ timeout = parts[1];
+ LOGGER.debug("Timeout is set to: " + timeout);
+
+ String urlPropKey = Constants.REQUEST_TUNABLES + "." + parts[2];
+ sdncUrl = properties.getProperty(urlPropKey, "");
+
+ if (sdncUrl.equals("")) {
+ error = "Missing configuration for: " + urlPropKey;
+ LOGGER.error(MessageEnum.RA_SDNC_MISS_CONFIG_PARAM, urlPropKey, "SDNC", "", MsoLogger.ErrorCode.DataError, "Missing config param");
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+ return false;
+ }
+
+ LOGGER.debug("SDNC Url is set to: " + sdncUrl);
+
+ headerName = parts[3];
+ LOGGER.debug("Header Name is set to: " + headerName);
+
+ namespace = parts[4];
+ LOGGER.debug("Namespace is set to: " + namespace);
+
+ myUrl = properties.getProperty(Constants.MY_URL_PROP, "");
+
+ if (myUrl.equals("")) {
+ error = "Missing configuration for: " + Constants.MY_URL_PROP;
+ LOGGER.error(MessageEnum.RA_SDNC_MISS_CONFIG_PARAM, Constants.MY_URL_PROP, "SDNC", "",
+ MsoLogger.ErrorCode.DataError, "Missing config param");
+ ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+ return false;
+ }
+
+ while (myUrl.endsWith("/")) {
+ myUrl = myUrl.substring(0, myUrl.length()-1);
+ }
+
+ myUrl += myUrlSuffix;
+
+ LOGGER.debug(toString());
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "["
+ + "reqId=" + reqId
+ + (key == null ? "" : ", key=" + key)
+ + (reqMethod == null ? "" : ", reqMethod=" + reqMethod)
+ + (sdncUrl == null ? "" : ", sdncUrl=" + sdncUrl)
+ + (timeout == null ? "" : ", timeout=" + timeout)
+ + (headerName == null ? "" : ", headerName=" + headerName)
+ + (namespace == null ? "" : ", namespace=" + namespace)
+ + (myUrl == null ? "" : ", myUrl=" + myUrl)
+ + "]";
+ }
+} \ No newline at end of file