Implement so-oof-adapter to handle OOF Callback
	- Add NSI/NST selection callback for Networkslicing

Issue-ID: SO-3205
Signed-off-by: Priyadharshini <priyadharshini.b96@wipro.com>
Change-Id: Ica88d503495949ecce8b897c3a990fbdaa5d4f0e
diff --git a/adapters/mso-oof-adapter/.gitignore b/adapters/mso-oof-adapter/.gitignore
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ b/adapters/mso-oof-adapter/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/adapters/mso-oof-adapter/pom.xml b/adapters/mso-oof-adapter/pom.xml
new file mode 100644
index 0000000..98150d3
--- /dev/null
+++ b/adapters/mso-oof-adapter/pom.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.onap.so</groupId>
+    <artifactId>adapters</artifactId>
+    <version>1.7.1-SNAPSHOT</version>
+  </parent>
+  <groupId>org.onap.so.adapters</groupId>
+  <artifactId>mso-oof-adapter</artifactId>
+  <name>mso-oof-adapter</name>
+  <description>mso oof adapter</description>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-dependencies</artifactId>
+        <version>${springboot.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-webflux</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-spring-boot-starter-jaxrs</artifactId>
+      <version>${cxf.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-rs-service-description-swagger</artifactId>
+      <version>${cxf.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-test</artifactId>
+      <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>org.junit.vintage</groupId>
+          <artifactId>junit-vintage-engine</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-engine</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.vintage</groupId>
+      <artifactId>junit-vintage-engine</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <finalName>${project.artifactId}-${project.version}</finalName>
+    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
+    <plugins>
+      <plugin>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-maven-plugin</artifactId>
+        <configuration>
+          <mainClass>org.onap.so.adapters.oof.MsoOofAdapterApplication</mainClass>
+        </configuration>
+        <executions>
+          <execution>
+            <goals>
+              <goal>repackage</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.jacoco</groupId>
+        <artifactId>jacoco-maven-plugin</artifactId>
+      </plugin>
+    </plugins>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+        <excludes>
+          <exclude>**/*.p12</exclude>
+          <exclude>**/*.jks</exclude>
+        </excludes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>false</filtering>
+        <includes>
+          <include>**/*.p12</include>
+          <include>**/*.jks</include>
+        </includes>
+      </resource>
+    </resources>
+  </build>
+</project>
diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/MsoOofAdapterApplication.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/MsoOofAdapterApplication.java
new file mode 100644
index 0000000..78fbe6e
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/MsoOofAdapterApplication.java
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Wipro Limited. 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.onap.so.adapters.oof;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MsoOofAdapterApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(MsoOofAdapterApplication.class, args);
+    }
+}
diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/OofAdapterClientConfig.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/OofAdapterClientConfig.java
new file mode 100644
index 0000000..5e13c59
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/OofAdapterClientConfig.java
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Wipro Limited. 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.onap.so.adapters.oof;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import org.apache.http.client.HttpClient;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.HttpClients;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class OofAdapterClientConfig {
+
+    @Bean
+    public RestTemplate getRestTemplate() {
+        HttpComponentsClientHttpRequestFactory requestFactory =
+                new HttpComponentsClientHttpRequestFactory(getHttpsClient());
+        requestFactory.setConnectTimeout(60000);
+        requestFactory.setReadTimeout(60000);
+        return new RestTemplate(requestFactory);
+    }
+
+    private HttpClient getHttpsClient() {
+        TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
+            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+                return null;
+            }
+
+            public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
+
+            public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
+        }};
+
+        // Install the all-trusting trust manager
+        try {
+            SSLContext sc = SSLContext.getInstance("SSL");
+            sc.init(null, trustAllCerts, new java.security.SecureRandom());
+            HostnameVerifier hostnameVerifier = new HostnameVerifier() {
+                @Override
+                public boolean verify(String hostname, SSLSession session) {
+                    return true;
+                }
+            };
+            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sc,
+                    new String[] {"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"}, null, hostnameVerifier);
+            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
+        } catch (Exception e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+}
diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/WebSecurityConfig.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/WebSecurityConfig.java
new file mode 100644
index 0000000..9a07b01
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/WebSecurityConfig.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Wipro Limited. 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.onap.so.adapters.oof;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@EnableWebSecurity
+@Configuration
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.csrf().disable();
+    }
+
+}
diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/constants/Constants.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/constants/Constants.java
new file mode 100644
index 0000000..5d91bf3
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/constants/Constants.java
@@ -0,0 +1,31 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Wipro Limited. 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.onap.so.adapters.oof.constants;
+
+public class Constants {
+
+    public static final String OOF_ENDPOINT = "mso.oof.endpoint";
+    public static final String OOF_AUTH = "mso.oof.auth";
+    public static final String MSO_KEY = "mso.msoKey";
+    public static final String CAMUNDA_URL = "mso.camundaURL";
+    public static final String CAMUNDA_AUTH = "mso.camundaAuth";
+    public static final String WORKFLOW_MESSAGE_ENPOINT = "mso.workflow.message.endpoint";
+
+}
diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/exceptions/OofAdapterException.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/exceptions/OofAdapterException.java
new file mode 100644
index 0000000..ff16d74
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/exceptions/OofAdapterException.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Wipro Limited. 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.onap.so.adapters.oof.exceptions;
+
+public class OofAdapterException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    public OofAdapterException(String message) {
+        super(message);
+    }
+
+    public OofAdapterException(Throwable e) {
+        super(e);
+    }
+
+    public OofAdapterException(String message, Throwable e) {
+        super(message, e);
+    }
+
+}
diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/model/OofRequest.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/model/OofRequest.java
new file mode 100644
index 0000000..1eb694f
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/model/OofRequest.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Wipro Limited. 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.onap.so.adapters.oof.model;
+
+/**
+ * POJO representing generic request payload from BPMN processes
+ */
+public class OofRequest {
+
+    private String apiPath;
+
+    private Object requestDetails;
+
+    public String getApiPath() {
+        return apiPath;
+    }
+
+    public void setApiPath(String apiPath) {
+        this.apiPath = apiPath;
+    }
+
+    public Object getRequestDetails() {
+        return requestDetails;
+    }
+
+    public void setRequestDetails(Object requestDetails) {
+        this.requestDetails = requestDetails;
+    }
+
+    @Override
+    public String toString() {
+        return "{\"apiPath:\"\"" + apiPath + "\"\", requestDetails:\"\"" + requestDetails + "}";
+    }
+
+}
diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/rest/OofCallbackHandler.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/rest/OofCallbackHandler.java
new file mode 100644
index 0000000..f8da6c6
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/rest/OofCallbackHandler.java
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Wipro Limited. 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.onap.so.adapters.oof.rest;
+
+import org.onap.so.adapters.oof.exceptions.OofAdapterException;
+import org.onap.so.adapters.oof.utils.OofUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * A generic call back handler to receive async response from OOF
+ */
+@RestController
+@RequestMapping("/so/adapters/oof/callback/")
+public class OofCallbackHandler {
+
+    @Autowired
+    OofUtils utils;
+
+    @Autowired
+    RestTemplate restTemplate;
+
+    private static final Logger logger = LoggerFactory.getLogger(OofCallbackHandler.class);
+
+    @PostMapping("/{version:[vV][1]}/{messageEventName}/{correlator}")
+    public ResponseEntity<String> processCallback(@PathVariable("messageEventName") String messageEventName,
+            @PathVariable("correlator") String correlator, @RequestBody String oofCallbackRequest)
+            throws OofAdapterException {
+        logger.debug("Oof Async response received for event : {} , callback request body : {} ", messageEventName,
+                oofCallbackRequest);
+        String camundaMsgUrl = utils.getCamundaMsgUrl(messageEventName, correlator);
+        HttpEntity<String> request = new HttpEntity<String>(oofCallbackRequest, utils.getCamundaHeaders());
+        try {
+            ResponseEntity<String> response = restTemplate.postForEntity(camundaMsgUrl, request, String.class);
+            logger.debug("Response from BPMN : {} ", response);
+            return response;
+        } catch (Exception e) {
+            logger.warn("Error injecting message event into BPMN {} {} ", e.getCause(), e.getMessage());
+            throw new OofAdapterException(e);
+        }
+
+    }
+
+}
diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/rest/OofClient.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/rest/OofClient.java
new file mode 100644
index 0000000..3a91ec4
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/rest/OofClient.java
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Wipro Limited. 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.onap.so.adapters.oof.rest;
+
+import org.onap.so.adapters.oof.exceptions.OofAdapterException;
+import org.onap.so.adapters.oof.model.OofRequest;
+import org.onap.so.adapters.oof.utils.OofUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * A generic client class to call OOF with request from BPMN
+ */
+@RestController
+@RequestMapping("/so/adapters/oof/")
+public class OofClient {
+
+    @Autowired
+    RestTemplate restTemplate;
+
+    @Autowired
+    OofUtils utils;
+
+    private static final Logger logger = LoggerFactory.getLogger(OofClient.class);
+
+    @PostMapping("/{version:[vV][1]}")
+    public ResponseEntity<String> callOof(@RequestBody OofRequest oofRequest) throws OofAdapterException {
+        try {
+            logger.debug("Received Request from BPEL {} ", oofRequest);
+            String oofUrl = utils.getOofurl(oofRequest.getApiPath());
+            HttpEntity<?> request = new HttpEntity<>(oofRequest.getRequestDetails(), utils.getOofHttpHeaders());
+            ResponseEntity<String> response = restTemplate.postForEntity(oofUrl, request, String.class);
+            logger.debug("Response from OOF : {} ", response);
+            return response;
+        } catch (Exception e) {
+            logger.warn("Error while calling OOF {} {} ", e.getCause(), e.getMessage());
+            throw new OofAdapterException(e);
+        }
+    }
+
+}
diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/utils/OofUtils.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/utils/OofUtils.java
new file mode 100644
index 0000000..f45baa3
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/utils/OofUtils.java
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Wipro Limited. 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.onap.so.adapters.oof.utils;
+
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.DatatypeConverter;
+import org.onap.so.adapters.oof.constants.Constants;
+import org.onap.so.utils.CryptoUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Component;
+
+@Component
+public class OofUtils {
+    private static Logger logger = LoggerFactory.getLogger(OofUtils.class);
+
+    @Autowired
+    private Environment env;
+
+    /**
+     * @param messageEventName
+     * @param correlator
+     * @return
+     */
+    public String getCamundaMsgUrl(String messageEventName, String correlator) {
+        System.out.println(env);
+        String camundaMsgUrl = new StringBuilder(env.getRequiredProperty(Constants.WORKFLOW_MESSAGE_ENPOINT))
+                .append("/").append(messageEventName).append("/").append(correlator).toString();
+        return camundaMsgUrl;
+    }
+
+    /**
+     * @return
+     */
+    public HttpHeaders getCamundaHeaders() {
+        HttpHeaders headers = new HttpHeaders();
+        List<MediaType> acceptableMediaTypes = new ArrayList<>();
+        acceptableMediaTypes.add(MediaType.ALL);
+        headers.setAccept(acceptableMediaTypes);
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        headers.add(HttpHeaders.AUTHORIZATION, addAuthorizationHeader(env.getRequiredProperty(Constants.CAMUNDA_AUTH),
+                env.getRequiredProperty(Constants.MSO_KEY)));
+        return headers;
+    }
+
+    /**
+     * @param auth
+     * @param msoKey
+     * @return
+     */
+    protected String addAuthorizationHeader(String auth, String msoKey) {
+        String basicAuth = null;
+        try {
+            String userCredentials = CryptoUtils.decrypt(auth, msoKey);
+            if (userCredentials != null) {
+                basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
+            }
+        } catch (GeneralSecurityException e) {
+            logger.error("Security exception", e);
+        }
+        return basicAuth;
+    }
+
+    /**
+     * @return
+     * @throws Exception
+     */
+    public HttpHeaders getOofHttpHeaders() throws Exception {
+        HttpHeaders headers = new HttpHeaders();
+        List<MediaType> acceptableMediaTypes = new ArrayList<>();
+        acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
+        headers.setAccept(acceptableMediaTypes);
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        return headers;
+    }
+
+    /**
+     * @param apiPath
+     * @return
+     */
+    public String getOofurl(String apiPath) {
+        return new StringBuilder(env.getRequiredProperty(Constants.OOF_ENDPOINT)).append(apiPath).toString();
+    }
+
+
+}
diff --git a/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/rest/OofCallbackHandlerTest.java b/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/rest/OofCallbackHandlerTest.java
new file mode 100644
index 0000000..3a2f7f5
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/rest/OofCallbackHandlerTest.java
@@ -0,0 +1,85 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Wipro Limited. 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.onap.so.adapters.oof.rest;
+
+import static org.mockito.Mockito.when;
+import java.io.File;
+import java.io.IOException;
+import org.junit.Before;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import org.onap.so.adapters.oof.utils.OofUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+class OofCallbackHandlerTest {
+
+    @Autowired
+    TestRestTemplate restTemplate;
+
+    @MockBean
+    OofUtils oofutils;
+
+    @MockBean
+    RestTemplate mockrestTemplate;
+
+    @Before
+    void prepareMocks() throws Exception {
+        ResponseEntity<Object> responseEntity = new ResponseEntity<>(HttpStatus.OK);
+        when(oofutils.getCamundaHeaders()).thenReturn(new HttpHeaders());
+        when(oofutils.getCamundaMsgUrl(Mockito.anyString(), Mockito.anyString())).thenReturn("oofurl");
+        when(mockrestTemplate.postForEntity(Mockito.anyString(), Mockito.any(), Mockito.any()))
+                .thenReturn(responseEntity);
+    }
+
+    @Test
+    void processCallbackTest() throws Exception {
+        Object request = prepareOofResponse();
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<Object> entity = new HttpEntity<Object>(request, headers);
+        ResponseEntity<String> response = restTemplate.postForEntity(
+                "/so/adapters/oof/callback/v1/NSISelectionResponse/d88da85c-d9e8-4f73-b837-3a72a431622a", entity,
+                String.class);
+        Assertions.assertEquals(HttpStatus.OK, response.getStatusCode());
+    }
+
+    private Object prepareOofResponse() throws IOException {
+        File file = new ClassPathResource("testInputs/NsiSelectionResponse.json").getFile();
+        ObjectMapper objectMapper = new ObjectMapper();
+        return objectMapper.readValue(file, Object.class);
+    }
+
+}
diff --git a/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/rest/OofClientTest.java b/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/rest/OofClientTest.java
new file mode 100644
index 0000000..ff38a9a
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/rest/OofClientTest.java
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Wipro Limited. 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.onap.so.adapters.oof.rest;
+
+import static org.mockito.Mockito.when;
+import java.io.File;
+import java.io.IOException;
+import org.junit.Before;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.onap.so.adapters.oof.model.OofRequest;
+import org.onap.so.adapters.oof.utils.OofUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+class OofClientTest {
+
+    @Autowired
+    TestRestTemplate restTemplate;
+
+    @MockBean
+    OofUtils oofutils;
+
+    @MockBean
+    RestTemplate mockrestTemplate;
+
+    @Before
+    void prepareMocks() throws Exception {
+        ResponseEntity<Object> responseEntity = new ResponseEntity<>(HttpStatus.OK);
+        when(oofutils.getOofHttpHeaders()).thenReturn(new HttpHeaders());
+        when(oofutils.getOofurl(Mockito.anyString())).thenReturn("oofurl");
+        when(mockrestTemplate.postForEntity(Mockito.anyString(), Mockito.any(), Mockito.any()))
+                .thenReturn(responseEntity);
+    }
+
+    @Test
+    void callOofTest() throws Exception {
+        OofRequest request = prepareOofRequest();
+        System.out.println(request);
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<OofRequest> entity = new HttpEntity<OofRequest>(request, headers);
+        ResponseEntity<String> response = restTemplate.postForEntity("/so/adapters/oof/v1", entity, String.class);
+        Assertions.assertEquals(HttpStatus.OK, response.getStatusCode());
+    }
+
+    private OofRequest prepareOofRequest() throws IOException {
+        File file = new ClassPathResource("testInputs/NsiSelectionOofRequest.json").getFile();
+        ObjectMapper objectMapper = new ObjectMapper();
+        return objectMapper.readValue(file, OofRequest.class);
+    }
+
+
+}
diff --git a/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/utils/OofUtilsTest.java b/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/utils/OofUtilsTest.java
new file mode 100644
index 0000000..e68fa10
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/utils/OofUtilsTest.java
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Wipro Limited. 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.onap.so.adapters.oof.utils;
+
+import static org.mockito.Mockito.when;
+import java.security.GeneralSecurityException;
+import javax.xml.bind.DatatypeConverter;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.onap.so.utils.CryptoUtils;
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpHeaders;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+class OofUtilsTest {
+
+    @InjectMocks
+    OofUtils oofUtils;
+
+    @Mock
+    Environment env;
+
+    @Test
+    void testGetCamundaMsgUrl() {
+        when(env.getRequiredProperty(Mockito.anyString())).thenReturn("dummyString");
+        String camundamsgUrl = oofUtils.getCamundaMsgUrl("samplemessage", "sampleCorrelator");
+        Assertions.assertNotNull(camundamsgUrl);
+    }
+
+
+    void testGetCamundaHeaders() throws GeneralSecurityException {
+        when(env.getRequiredProperty(Mockito.anyString())).thenReturn("dummyString");
+        when(CryptoUtils.decrypt(Mockito.anyString(), Mockito.anyString())).thenReturn("decryptedString");
+        HttpHeaders headers = oofUtils.getCamundaHeaders();
+        Assertions.assertNotNull(headers);
+    }
+
+
+    @Test
+    void testGetOofHttpHeaders() throws Exception {
+        when(env.getRequiredProperty(Mockito.anyString())).thenReturn("dummyString");
+        HttpHeaders headers = oofUtils.getOofHttpHeaders();
+        Assertions.assertNotNull(headers);
+    }
+
+    @Test
+    void testGetOofurl() {
+        when(env.getRequiredProperty(Mockito.anyString())).thenReturn("dummyString");
+        String oofurl = oofUtils.getOofurl("/api/v1/");
+        Assertions.assertNotNull(oofurl);
+    }
+
+}
diff --git a/adapters/mso-oof-adapter/src/test/resources/testInputs/NsiSelectionOofRequest.json b/adapters/mso-oof-adapter/src/test/resources/testInputs/NsiSelectionOofRequest.json
new file mode 100644
index 0000000..569aae9
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/test/resources/testInputs/NsiSelectionOofRequest.json
@@ -0,0 +1,84 @@
+{
+	"apiPath":"/api/oof/selection/nsi/v1",
+	"requestDetails":{
+   "serviceProfile":{
+      "blob":"content"
+   },
+   "requestInfo":{
+      "transactionId":"d290f1ee-6c54-4b01-90e6-d701748f0851",
+      "requestId":"d290f1ee-6c54-4b01-90e6-d701748f0851",
+      "callbackUrl":"myDomain.com/myCallback",
+      "callbackHeader":{
+         "blob":"content"
+      },
+      "sourceId":"d290f1ee-6c54-4b01-90e6-d701748f0851",
+      "timeout":5,
+      "numSolutions":1
+   },
+   "NSTInfo":{
+      "UUID":"3fa85f64-5717-4562-b3fc-2c963f66afa1",
+      "invariantUUID":"7ua85f64-5717-4562-b3fc-2c963f66afa6",
+      "name":"embb-nst"
+   },
+   "NSSTInfo":[
+      {
+         "UUID":"3fa85f64-5717-4562-b3fc-2c963f66afa2",
+         "invariantUUID":"2fa85f64-5717-4562-b3fc-2c963f66afa6",
+         "name":"embb-an-nf"
+      },
+      {
+         "UUID":"3fa85f64-5717-4562-b3fc-2c963f66afa3",
+         "invariantUUID":"4fa85f64-5717-4562-b3fc-2c963f66afa6",
+         "name":"embb-cn"
+      },
+      {
+         "UUID":"3fa85f64-5717-4562-b3fc-2c963f66afa4",
+         "invariantUUID":"5ta85f64-5717-4562-b3fc-2c963f66afa6",
+         "name":"embb-tn-fh"
+      },
+      {
+         "UUID":"3fa85f64-5717-4562-b3fc-2c963f66afa5",
+         "invariantUUID":"6ya85f64-5717-4562-b3fc-2c963f66afa6",
+         "name":"embb-tn-mh"
+      },
+      {
+         "UUID":"3fa85f64-5717-4562-b3fc-2c963f66afa7",
+         "invariantUUID":"7ua85f64-5717-4562-b3fc-2c963f66afa6",
+         "name":"embb-tn-bh"
+      }
+   ],
+   "preferReuse":false,
+   "subnetCapabilities":[
+      {
+         "domainType":"AN-NF",
+         "capabilityDetails":{
+            "blob":"content"
+         }
+      },
+      {
+         "domainType":"CN",
+         "capabilityDetails":{
+            "blob":"content"
+         }
+      },
+      {
+         "domainType":"TN-FH",
+         "capabilityDetails":{
+            "blob":"content"
+         }
+      },
+      {
+         "domainType":"TN-MH",
+         "capabilityDetails":{
+            "blob":"content"
+         }
+      },
+      {
+         "domainType":"TN-BH",
+         "capabilityDetails":{
+            "blob":"content"
+         }
+      }
+   ]
+}
+}
\ No newline at end of file
diff --git a/adapters/mso-oof-adapter/src/test/resources/testInputs/NsiSelectionResponse.json b/adapters/mso-oof-adapter/src/test/resources/testInputs/NsiSelectionResponse.json
new file mode 100644
index 0000000..4ddca3e
--- /dev/null
+++ b/adapters/mso-oof-adapter/src/test/resources/testInputs/NsiSelectionResponse.json
@@ -0,0 +1,20 @@
+{
+  "transactionId": "s4r0f1ee-6c54-4b01-90e6-d701748f0851",
+  "requestId": "r500f1ee-6c54-4b01-90e6-d701748f0851",
+  "requestStatus": "completed",
+  "solutions": [
+    {
+      "existingNSI": false,
+      "newNSISolution": {
+        "sliceProfiles": [
+            {
+                "domainType":"CN"
+            }
+        ],
+        "matchLevel": {
+            "blob": "content"
+          }
+      }
+    }
+  ]
+}