diff --git a/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/VfcAdapterRest.java b/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/VfcAdapterRest.java
index ef3c1b7..48da1ab 100644
--- a/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/VfcAdapterRest.java
+++ b/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/VfcAdapterRest.java
@@ -35,6 +35,7 @@
 import org.openecomp.mso.adapters.vfc.model.RestfulResponse;
 import org.openecomp.mso.adapters.vfc.util.JsonUtil;
 import org.openecomp.mso.adapters.vfc.util.ValidateUtil;
+import org.openecomp.mso.logger.MessageEnum;
 import org.openecomp.mso.logger.MsoLogger;
 
 /**
@@ -70,7 +71,7 @@
     public Response createNfvoNs(String data) {
         try {
             ValidateUtil.assertObjectNotNull(data);
-            LOGGER.debug("body from request is {}" + data);
+            LOGGER.info(MessageEnum.RA_NS_EXC, "Create NS Request Received.Body from request is :\n" + data, "org.openecomp.mso.adapters.vfc.VfcAdapterRest", "VFC Adapter");
             NSResourceInputParameter nsInput = JsonUtil.unMarshal(data, NSResourceInputParameter.class);
             RestfulResponse rsp = driverMgr.createNs(nsInput);
             return buildResponse(rsp);
@@ -95,7 +96,7 @@
         try {
 
             ValidateUtil.assertObjectNotNull(data);
-            LOGGER.debug("body from request is {}" + data);
+            LOGGER.info(MessageEnum.RA_NS_EXC, "Delete NS Request Received.Body from request is :\n" + data, "org.openecomp.mso.adapters.vfc.VfcAdapterRest", "VFC Adapter");
             NsOperationKey nsOperationKey = JsonUtil.unMarshal(data, NsOperationKey.class);
             RestfulResponse rsp = driverMgr.deleteNs(nsOperationKey, nsInstanceId);
             return buildResponse(rsp);
@@ -120,7 +121,7 @@
     public Response queryNfvoJobStatus(String data, @PathParam("jobId") String jobId) {
         try {
             ValidateUtil.assertObjectNotNull(data);
-            LOGGER.debug("body from request is {}" + data);
+            LOGGER.info(MessageEnum.RA_NS_EXC, "Query Job Request Received.Body from request is :\n" + data, "org.openecomp.mso.adapters.vfc.VfcAdapterRest", "VFC Adapter");
             NsOperationKey nsOperationKey = JsonUtil.unMarshal(data, NsOperationKey.class);
             RestfulResponse rsp = driverMgr.getNsProgress(nsOperationKey, jobId);
             return buildResponse(rsp);
@@ -145,7 +146,7 @@
     public Response instantiateNfvoNs(String data, @PathParam("nsInstanceId") String nsInstanceId) {
         try {
             ValidateUtil.assertObjectNotNull(data);
-            LOGGER.debug("body from request is {}" + data);
+            LOGGER.info(MessageEnum.RA_NS_EXC, "Instantiate Ns Request Received.Body from request is :\n" + data, "org.openecomp.mso.adapters.vfc.VfcAdapterRest", "VFC Adapter");
             NSResourceInputParameter nsInput = JsonUtil.unMarshal(data, NSResourceInputParameter.class);
             RestfulResponse rsp = driverMgr.instantiateNs(nsInstanceId, nsInput);
             return buildResponse(rsp);
@@ -170,7 +171,7 @@
     public Response terminateNfvoNs(String data, @PathParam("nsInstanceId") String nsInstanceId) {
         try {
             ValidateUtil.assertObjectNotNull(data);
-            LOGGER.debug("body from request is {}" + data);
+            LOGGER.info(MessageEnum.RA_NS_EXC, "Terminate Ns Request Received.Body from request is :\n" + data, "org.openecomp.mso.adapters.vfc.VfcAdapterRest", "VFC Adapter");
             NsOperationKey nsOperationKey = JsonUtil.unMarshal(data, NsOperationKey.class);
             RestfulResponse rsp = driverMgr.terminateNs(nsOperationKey, nsInstanceId);
             return buildResponse(rsp);
diff --git a/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/VfcManager.java b/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/VfcManager.java
index 35c8ead..8d820bc 100644
--- a/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/VfcManager.java
+++ b/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/VfcManager.java
@@ -40,11 +40,11 @@
 import org.openecomp.mso.adapters.vfc.util.JsonUtil;
 import org.openecomp.mso.adapters.vfc.util.RestfulUtil;
 import org.openecomp.mso.adapters.vfc.util.ValidateUtil;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoLogger;
 import org.openecomp.mso.requestsdb.RequestsDatabase;
 import org.openecomp.mso.requestsdb.RequestsDbConstant;
 import org.openecomp.mso.requestsdb.ResourceOperationStatus;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * VF-C Manager <br>
@@ -56,355 +56,355 @@
  */
 public class VfcManager {
 
-  private static final Logger LOGGER = LoggerFactory.getLogger(VfcManager.class);
+    private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
 
-  /**
-   * nfvo url map
-   */
-  private static Map<String, String> nfvoUrlMap;
+    /**
+     * nfvo url map
+     */
+    private static Map<String, String> nfvoUrlMap;
 
-  static {
-    nfvoUrlMap = new HashMap<>();
-    nfvoUrlMap.put(Step.CREATE, CommonConstant.NFVO_CREATE_URL);
-    nfvoUrlMap.put(Step.INSTANTIATE, CommonConstant.NFVO_INSTANTIATE_URL);
-    nfvoUrlMap.put(Step.TERMINATE, CommonConstant.NFVO_TERMINATE_URL);
-    nfvoUrlMap.put(Step.DELETE, CommonConstant.NFVO_DELETE_URL);
-    nfvoUrlMap.put(Step.QUERY, CommonConstant.NFVO_QUERY_URL);
-  }
-
-  public VfcManager() {
-
-  }
-
-  /**
-   * create network service <br>
-   * 
-   * @param segInput input parameters for current node from http request
-   * @return
-   * @since ONAP Amsterdam Release
-   */
-  public RestfulResponse createNs(NSResourceInputParameter segInput) throws ApplicationException {
-
-    // Step1: get service template by node type
-    String csarId = segInput.getNsOperationKey().getNodeTemplateUUID();
-    // nsdId for NFVO is "id" in the response, while for SDNO is "servcice template id"
-    LOGGER.info("serviceTemplateId is {}, id is {}", csarId);
-
-    LOGGER.info("create ns -> begin");
-    // Step2: Prepare url and method type
-    String url = getUrl(null, CommonConstant.Step.CREATE);
-    String methodType = CommonConstant.MethodType.POST;
-
-    // Step3: Prepare restful parameters and options
-    NsCreateReq oRequest = new NsCreateReq();
-    oRequest.setCsarId(csarId);
-    oRequest.setNsName(segInput.getNsServiceName());
-    oRequest.setDescription(segInput.getNsServiceDescription());
-    CustomerModel context = new CustomerModel();
-    context.setGlobalCustomerId(segInput.getNsOperationKey().getGlobalSubscriberId());
-    context.setServiceType(segInput.getNsOperationKey().getServiceType());
-    oRequest.setContext(context);
-    String createReq = JsonUtil.marshal(oRequest);
-
-    // Step4: Call NFVO or SDNO lcm to create ns
-    RestfulResponse createRsp = RestfulUtil.send(url, methodType, createReq);
-    ValidateUtil.assertObjectNotNull(createRsp);
-    LOGGER.info("create ns response status is : {}", createRsp.getStatus());
-    LOGGER.info("create ns response content is : {}", createRsp.getResponseContent());
-
-    // Step 5: save resource operation information
-    ResourceOperationStatus nsOperInfo = (RequestsDatabase.getInstance())
-        .getResourceOperationStatus(segInput.getNsOperationKey().getServiceId(),
-            segInput.getNsOperationKey().getOperationId(),
-            segInput.getNsOperationKey().getNodeTemplateUUID());
-    nsOperInfo.setStatus(RequestsDbConstant.Status.PROCESSING);
-    (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-
-    if (!HttpCode.isSucess(createRsp.getStatus())) {
-      LOGGER.error("update segment operation status : fail to create ns");
-      nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
-      nsOperInfo.setErrorCode(String.valueOf(createRsp.getStatus()));
-      (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-      throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
-          DriverExceptionID.FAIL_TO_CREATE_NS);
-    }
-    @SuppressWarnings("unchecked")
-    Map<String, String> rsp = JsonUtil.unMarshal(createRsp.getResponseContent(), Map.class);
-    String nsInstanceId = rsp.get(CommonConstant.NS_INSTANCE_ID);
-    if (ValidateUtil.isStrEmpty(nsInstanceId)) {
-      LOGGER.error("Invalid instanceId from create operation");
-      throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
-          DriverExceptionID.INVALID_RESPONSEE_FROM_CREATE_OPERATION);
-    }
-    LOGGER.info("create ns -> end");
-
-    return createRsp;
-  }
-
-  /**
-   * delete network service <br>
-   * 
-   * @param nsOperationKey The operation key of the NS resource
-   * @param nsInstanceId The NS instance id
-   * @return
-   * @since ONAP Amsterdam Release
-   */
-  public RestfulResponse deleteNs(NsOperationKey nsOperationKey, String nsInstanceId)
-      throws ApplicationException {
-    LOGGER.info("delete ns -> begin");
-    // Step1: prepare url and methodType
-    String url = getUrl(nsInstanceId, CommonConstant.Step.DELETE);
-    String methodType = CommonConstant.MethodType.DELETE;
-
-    // Step2: prepare restful parameters and options
-    RestfulResponse deleteRsp = RestfulUtil.send(url, methodType, "");
-    ValidateUtil.assertObjectNotNull(deleteRsp);
-    LOGGER.info("delete ns response status is : {}", deleteRsp.getStatus());
-    LOGGER.info("delete ns response content is : {}", deleteRsp.getResponseContent());
-    LOGGER.info("delete ns -> end");
-    ResourceOperationStatus nsOperInfo =
-        (RequestsDatabase.getInstance()).getResourceOperationStatus(nsOperationKey.getServiceId(),
-            nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateUUID());
-    if (!HttpCode.isSucess(deleteRsp.getStatus())) {
-      LOGGER.error("fail to delete ns");
-
-      nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
-      nsOperInfo.setErrorCode(String.valueOf(deleteRsp.getStatus()));
-      nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED);
-      (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-      throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
-          DriverExceptionID.FAIL_TO_DELETE_NS);
+    static {
+        nfvoUrlMap = new HashMap<>();
+        nfvoUrlMap.put(Step.CREATE, CommonConstant.NFVO_CREATE_URL);
+        nfvoUrlMap.put(Step.INSTANTIATE, CommonConstant.NFVO_INSTANTIATE_URL);
+        nfvoUrlMap.put(Step.TERMINATE, CommonConstant.NFVO_TERMINATE_URL);
+        nfvoUrlMap.put(Step.DELETE, CommonConstant.NFVO_DELETE_URL);
+        nfvoUrlMap.put(Step.QUERY, CommonConstant.NFVO_QUERY_URL);
     }
 
-    // Step4: update service segment operation status
-    nsOperInfo.setStatus(RequestsDbConstant.Status.FINISHED);
-    nsOperInfo.setErrorCode(String.valueOf(deleteRsp.getStatus()));
-    (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-    LOGGER.info("update segment operaton status for delete -> end");
+    public VfcManager() {
 
-    return deleteRsp;
+    }
 
-  }
+    /**
+     * create network service <br>
+     * 
+     * @param segInput input parameters for current node from http request
+     * @return
+     * @since ONAP Amsterdam Release
+     */
+    public RestfulResponse createNs(NSResourceInputParameter segInput) throws ApplicationException {
 
-  /**
-   * instantiate network service <br>
-   * 
-   * @param nsInstanceId The NS instance id
-   * @param segInput input parameters for current node from http request
-   * @return
-   * @since ONAP Amsterdam Release
-   */
-  public RestfulResponse instantiateNs(String nsInstanceId, NSResourceInputParameter segInput)
-      throws ApplicationException {
-    // Call the NFVO or SDNO service to instantiate service
-    LOGGER.info("instantiate ns -> begin");
+        // Step1: get service template by node type
+        String csarId = segInput.getNsOperationKey().getNodeTemplateUUID();
+        // nsdId for NFVO is "id" in the response, while for SDNO is "servcice template id"
+        logInfoMsg("serviceTemplateId is , id is " + csarId);
+        logInfoMsg("create ns -> begin");
+        // Step2: Prepare url and method type
+        String url = getUrl(null, CommonConstant.Step.CREATE);
+        String methodType = CommonConstant.MethodType.POST;
 
-    // Step1: Prepare restful parameters and options
-    NsInstantiateReq oRequest = new NsInstantiateReq();
-    oRequest.setNsInstanceId(nsInstanceId);
-    NsParameters nsParameters = segInput.getNsParameters();
-    oRequest.setLocationConstraints(nsParameters.getLocationConstraints());
-    oRequest.setAdditionalParamForNs(nsParameters.getAdditionalParamForNs());
-    String instReq = JsonUtil.marshal(oRequest);
-    // Step2: prepare url and
-    String url = getUrl(nsInstanceId, CommonConstant.Step.INSTANTIATE);
-    String methodType = CommonConstant.MethodType.POST;
+        // Step3: Prepare restful parameters and options
+        NsCreateReq oRequest = new NsCreateReq();
+        oRequest.setCsarId(csarId);
+        oRequest.setNsName(segInput.getNsServiceName());
+        oRequest.setDescription(segInput.getNsServiceDescription());
+        CustomerModel context = new CustomerModel();
+        context.setGlobalCustomerId(segInput.getNsOperationKey().getGlobalSubscriberId());
+        context.setServiceType(segInput.getNsOperationKey().getServiceType());
+        oRequest.setContext(context);
+        String createReq = JsonUtil.marshal(oRequest);
+        logInfoMsg("create ns request: \n" + createReq);
+        // Step4: Call NFVO or SDNO lcm to create ns
+        RestfulResponse createRsp = RestfulUtil.send(url, methodType, createReq);
+        ValidateUtil.assertObjectNotNull(createRsp);
+        logInfoMsg("create ns response status is : " + createRsp.getStatus());
+        logInfoMsg("create ns response content is : " + createRsp.getResponseContent());
 
-    RestfulResponse instRsp = RestfulUtil.send(url, methodType, instReq);    
-    ResourceOperationStatus nsOperInfo = (RequestsDatabase.getInstance())
-            .getResourceOperationStatus(segInput.getNsOperationKey().getServiceId(),
-                segInput.getNsOperationKey().getOperationId(),
+        // Step 5: save resource operation information
+        ResourceOperationStatus nsOperInfo = (RequestsDatabase.getInstance()).getResourceOperationStatus(
+                segInput.getNsOperationKey().getServiceId(), segInput.getNsOperationKey().getOperationId(),
                 segInput.getNsOperationKey().getNodeTemplateUUID());
-    ValidateUtil.assertObjectNotNull(instRsp);
-    if (!HttpCode.isSucess(instRsp.getStatus())) {
-        LOGGER.error("update segment operation status : fail to instantiate ns");
-        nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
-        nsOperInfo.setErrorCode(String.valueOf(instRsp.getStatus()));
-        nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.INSTANTIATE_NS_FAILED);
+        nsOperInfo.setStatus(RequestsDbConstant.Status.PROCESSING);
         (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-        throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
-            DriverExceptionID.FAIL_TO_INSTANTIATE_NS);
-      }
-    LOGGER.info("instantiate ns response status is : {}", instRsp.getStatus());
-    LOGGER.info("instantiate ns response content is : {}", instRsp.getResponseContent());
-    ValidateUtil.assertObjectNotNull(instRsp.getResponseContent());    
-    @SuppressWarnings("unchecked")
-    Map<String, String> rsp = JsonUtil.unMarshal(instRsp.getResponseContent(), Map.class);
-    String jobId = rsp.get(CommonConstant.JOB_ID);
-    if (ValidateUtil.isStrEmpty(jobId)) {
-      LOGGER.error("Invalid jobId from instantiate operation");
-      nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
-      nsOperInfo.setErrorCode(String.valueOf(instRsp.getStatus()));
-      nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.INSTANTIATE_NS_FAILED);
-      (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-      throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
-          DriverExceptionID.INVALID_RESPONSE_FROM_INSTANTIATE_OPERATION);
+
+        if(!HttpCode.isSucess(createRsp.getStatus())) {
+            logInfoMsg("update segment operation status : fail to create ns");
+            nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
+            nsOperInfo.setErrorCode(String.valueOf(createRsp.getStatus()));
+            (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+            throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_CREATE_NS);
+        }
+        @SuppressWarnings("unchecked")
+        Map<String, String> rsp = JsonUtil.unMarshal(createRsp.getResponseContent(), Map.class);
+        String nsInstanceId = rsp.get(CommonConstant.NS_INSTANCE_ID);
+        if(ValidateUtil.isStrEmpty(nsInstanceId)) {
+            logInfoMsg("Invalid instanceId from create operation");
+            throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
+                    DriverExceptionID.INVALID_RESPONSEE_FROM_CREATE_OPERATION);
+        }
+        logInfoMsg("create ns -> end");
+        return createRsp;
     }
-    LOGGER.info("instantiate ns -> end");
-    // Step 3: update segment operation job id
-    LOGGER.info("update resource operation status job id -> begin");
-    nsOperInfo.setJobId(jobId);
-    (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-    LOGGER.info("update segment operation job id -> end");
 
-    return instRsp;
-  }
+    /**
+     * delete network service <br>
+     * 
+     * @param nsOperationKey The operation key of the NS resource
+     * @param nsInstanceId The NS instance id
+     * @return
+     * @since ONAP Amsterdam Release
+     */
+    public RestfulResponse deleteNs(NsOperationKey nsOperationKey, String nsInstanceId) throws ApplicationException {
 
-  /**
-   * terminate network service <br>
-   * 
-   * @param nsOperationKey The operation key for NS resource
-   * @param nsInstanceId The NS instance id
-   * @return
-   * @since ONAP Amsterdam Release
-   */
-  public RestfulResponse terminateNs(NsOperationKey nsOperationKey, String nsInstanceId)
-      throws ApplicationException {
-    // Step1: save segment operation info for delete process
-    LOGGER.info("save segment operation for delete process");
-    ResourceOperationStatus nsOperInfo =
-        (RequestsDatabase.getInstance()).getResourceOperationStatus(nsOperationKey.getServiceId(),
-            nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateUUID());
-    nsOperInfo.setStatus(RequestsDbConstant.Status.PROCESSING);
-    (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+        logInfoMsg("delete ns -> begin");
+        // Step1: prepare url and methodType
+        String url = getUrl(nsInstanceId, CommonConstant.Step.DELETE);
+        String methodType = CommonConstant.MethodType.DELETE;
 
-    LOGGER.info("terminate ns -> begin");
-    // Step2: prepare url and method type
-    String url = getUrl(nsInstanceId, CommonConstant.Step.TERMINATE);
-    String methodType = CommonConstant.MethodType.POST;
+        // Step2: prepare restful parameters and options
+        logInfoMsg("delte ns sent message start.");
+        RestfulResponse deleteRsp = RestfulUtil.send(url, methodType, "");
+        ValidateUtil.assertObjectNotNull(deleteRsp);
 
-    // Step3: prepare restful parameters and options
-    Map<String, String> reqBody = new HashMap<>();
-    reqBody.put("nsInstanceId", nsInstanceId);
-    reqBody.put("terminationType", "graceful");
-    reqBody.put("gracefulTerminationTimeout", "60");
+        logInfoMsg("delete ns response status is : " + deleteRsp.getStatus());
+        logInfoMsg("delete ns response content is : " + deleteRsp.getResponseContent());
+        ResourceOperationStatus nsOperInfo = (RequestsDatabase.getInstance()).getResourceOperationStatus(
+                nsOperationKey.getServiceId(), nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateUUID());
+        if(!HttpCode.isSucess(deleteRsp.getStatus())) {
+            logInfoMsg("fail to delete ns");
+            nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
+            nsOperInfo.setErrorCode(String.valueOf(deleteRsp.getStatus()));
+            nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED);
+            (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+            throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_DELETE_NS);
+        }
 
-    // Step4: Call the NFVO or SDNO service to terminate service
-    RestfulResponse terminateRsp = RestfulUtil.send(url, methodType, JsonUtil.marshal(reqBody));
-    ValidateUtil.assertObjectNotNull(terminateRsp);
-    LOGGER.info("terminate ns response status is : {}", terminateRsp.getStatus());
-    LOGGER.info("terminate ns response content is : {}", terminateRsp.getResponseContent());
-    // Step 3: update segment operation
-    if (!HttpCode.isSucess(terminateRsp.getStatus())) {
-      LOGGER.error("fail to instantiate ns");
-      nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
-      nsOperInfo.setErrorCode(String.valueOf(terminateRsp.getStatus()));
-      nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED);
-      (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-
-      throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
-          DriverExceptionID.FAIL_TO_TERMINATE_NS);
-    }
-    @SuppressWarnings("unchecked")
-    Map<String, String> rsp = JsonUtil.unMarshal(terminateRsp.getResponseContent(), Map.class);
-    String jobId = rsp.get(CommonConstant.JOB_ID);
-    if (ValidateUtil.isStrEmpty(jobId)) {
-      LOGGER.error("Invalid jobId from terminate operation");
-      nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
-      nsOperInfo.setErrorCode(String.valueOf(terminateRsp.getStatus()));
-      nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED);
-      (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-      throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
-          DriverExceptionID.INVALID_RESPONSE_FROM_TERMINATE_OPERATION);
-    }
-    LOGGER.info("terminate ns -> end");
-
-    LOGGER.info("update segment job id -> begin");
-    nsOperInfo.setJobId(jobId);
-    (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-    LOGGER.info("update segment job id -> end");
-
-    return terminateRsp;
-  }
-
-  /**
-   * get ns progress by job Id <br>
-   * 
-   * @param nsOperationKey The OperationKey for NS resource
-   * @param jobId the job id
-   * @return
-   * @since ONAP Amsterdam Release
-   */
-  public RestfulResponse getNsProgress(NsOperationKey nsOperationKey, String jobId)
-      throws ApplicationException {
-
-    ValidateUtil.assertObjectNotNull(jobId);
-    // Step 1: query the current resource operation status
-    ResourceOperationStatus nsOperInfo =
-        (RequestsDatabase.getInstance()).getResourceOperationStatus(nsOperationKey.getServiceId(),
-            nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateUUID());
-
-    // Step 2: start query
-    LOGGER.info("query ns status -> begin");
-    String url = getUrl(jobId, CommonConstant.Step.QUERY);
-    String methodType = CommonConstant.MethodType.GET;
-    // prepare restful parameters and options
-    RestfulResponse rsp = RestfulUtil.send(url, methodType, "");
-    ValidateUtil.assertObjectNotNull(rsp);
-    LOGGER.info("query ns progress response status is : {}", rsp.getStatus());
-    LOGGER.info("query ns progress response content is : {}", rsp.getResponseContent());
-    // Step 3:check the response staus
-    if (!HttpCode.isSucess(rsp.getStatus())) {
-      LOGGER.info("fail to query job status");
-      nsOperInfo.setErrorCode(String.valueOf(rsp.getStatus()));
-      nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
-      nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.QUERY_JOB_STATUS_FAILED);
-      (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-      throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
-          DriverExceptionID.FAIL_TO_QUERY_JOB_STATUS);
-    }
-    // Step 4: Process Network Service Instantiate Response
-    NsProgressStatus nsProgress =
-        JsonUtil.unMarshal(rsp.getResponseContent(), NsProgressStatus.class);
-    ResponseDescriptor rspDesc = nsProgress.getResponseDescriptor();
-    // Step 5: update segment operation progress
-
-    nsOperInfo.setProgress(rspDesc.getProgress());
-    nsOperInfo.setStatusDescription(rspDesc.getStatusDescription());
-    (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-
-    // Step 6: update segment operation status
-    if (RequestsDbConstant.Progress.ONE_HUNDRED.equals(rspDesc.getProgress())
-        && RequestsDbConstant.Status.FINISHED.equals(rspDesc.getStatus())) {
-      LOGGER.info("job result is succeeded, operType is {}", nsOperInfo.getOperType());
-      nsOperInfo.setErrorCode(String.valueOf(rsp.getStatus()));
-
-      if (RequestsDbConstant.OperationType.CREATE.equals(nsOperInfo.getOperType())) {
+        // Step4: update service segment operation status
         nsOperInfo.setStatus(RequestsDbConstant.Status.FINISHED);
-      }
-      (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-    } else if (RequestsDbConstant.Status.ERROR.equals(rspDesc.getStatus())) {
-      LOGGER.error("job result is failed, operType is {}", nsOperInfo.getOperType());
-      nsOperInfo.setErrorCode(String.valueOf(rsp.getStatus()));
-      nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.QUERY_JOB_STATUS_FAILED);
-      nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
-      (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
-      throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
-          DriverExceptionID.JOB_STATUS_ERROR);
-    } else {
-      LOGGER.error("unexcepted response status");
+        nsOperInfo.setErrorCode(String.valueOf(deleteRsp.getStatus()));
+        (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+        logInfoMsg("update resource operaton status for delete -> end");
+        logInfoMsg("delete ns -> end");
+        return deleteRsp;
+
     }
-    LOGGER.info("query ns status -> end");
 
-    return rsp;
-  }
+    /**
+     * instantiate network service <br>
+     * 
+     * @param nsInstanceId The NS instance id
+     * @param segInput input parameters for current node from http request
+     * @return
+     * @since ONAP Amsterdam Release
+     */
+    public RestfulResponse instantiateNs(String nsInstanceId, NSResourceInputParameter segInput)
+            throws ApplicationException {
+        // Call the NFVO or SDNO service to instantiate service
+        logInfoMsg("instantiate ns -> begin");
+        // Step1: Prepare restful parameters and options
+        NsInstantiateReq oRequest = new NsInstantiateReq();
+        oRequest.setNsInstanceId(nsInstanceId);
+        NsParameters nsParameters = segInput.getNsParameters();
+        oRequest.setLocationConstraints(nsParameters.getLocationConstraints());
+        oRequest.setAdditionalParamForNs(nsParameters.getAdditionalParamForNs());
+        String instReq = JsonUtil.marshal(oRequest);
+        // Step2: prepare url and
+        String url = getUrl(nsInstanceId, CommonConstant.Step.INSTANTIATE);
+        String methodType = CommonConstant.MethodType.POST;
+        logInfoMsg("instantiate ns request: \n" + instReq);
+        RestfulResponse instRsp = RestfulUtil.send(url, methodType, instReq);
+        ResourceOperationStatus nsOperInfo = (RequestsDatabase.getInstance()).getResourceOperationStatus(
+                segInput.getNsOperationKey().getServiceId(), segInput.getNsOperationKey().getOperationId(),
+                segInput.getNsOperationKey().getNodeTemplateUUID());
+        ValidateUtil.assertObjectNotNull(instRsp);
+        if(!HttpCode.isSucess(instRsp.getStatus())) {
+            LOGGER.error(MessageEnum.RA_NS_EXC, "VFC Adapter", "", MsoLogger.ErrorCode.BusinessProcesssError,
+                    "update segment operation status : fail to instantiate ns");
+            nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
+            nsOperInfo.setErrorCode(String.valueOf(instRsp.getStatus()));
+            nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.INSTANTIATE_NS_FAILED);
+            (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+            throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_INSTANTIATE_NS);
+        }
+        logInfoMsg("instantiate ns response status is : " + instRsp.getStatus());
+        logInfoMsg("instantiate ns response content is : " + instRsp.getResponseContent());
 
-  /**
-   * get url for the operation <br>
-   * 
-   * @param variable variable should be put in the url
-   * @param step step of the operation (terminate,query,delete)
-   * @return
-   * @since ONAP Amsterdam Release
-   */
-  private String getUrl(String variable, String step) {
+        ValidateUtil.assertObjectNotNull(instRsp.getResponseContent());
+        @SuppressWarnings("unchecked")
+        Map<String, String> rsp = JsonUtil.unMarshal(instRsp.getResponseContent(), Map.class);
+        String jobId = rsp.get(CommonConstant.JOB_ID);
+        if(ValidateUtil.isStrEmpty(jobId)) {
+            LOGGER.error(MessageEnum.RA_NS_EXC, "VFC Adapter", "", MsoLogger.ErrorCode.BusinessProcesssError,
+                    "Invalid jobId from instantiate operation");
 
-    String url;
-    String originalUrl;
-    originalUrl = (String) nfvoUrlMap.get(step);
-    url = String.format(originalUrl, variable);
-    return url;
+            nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
+            nsOperInfo.setErrorCode(String.valueOf(instRsp.getStatus()));
+            nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.INSTANTIATE_NS_FAILED);
+            (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+            throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
+                    DriverExceptionID.INVALID_RESPONSE_FROM_INSTANTIATE_OPERATION);
+        }
+        logInfoMsg("update resource operation status job id -> begin");
+        // Step 3: update segment operation job id
+        nsOperInfo.setJobId(jobId);
+        (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+        logInfoMsg("update resource operation job id -> end");
+        logInfoMsg("instantiate ns -> end");
+        return instRsp;
+    }
 
-  }
+    /**
+     * terminate network service <br>
+     * 
+     * @param nsOperationKey The operation key for NS resource
+     * @param nsInstanceId The NS instance id
+     * @return
+     * @since ONAP Amsterdam Release
+     */
+    public RestfulResponse terminateNs(NsOperationKey nsOperationKey, String nsInstanceId) throws ApplicationException {
+        // Step1: save segment operation info for delete process
+        logInfoMsg("terminateNs process begin");
 
+        ResourceOperationStatus nsOperInfo = (RequestsDatabase.getInstance()).getResourceOperationStatus(
+                nsOperationKey.getServiceId(), nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateUUID());
+        nsOperInfo.setStatus(RequestsDbConstant.Status.PROCESSING);
+        (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+        logInfoMsg("updateResOperStatus end");
+        // Step2: prepare url and method type
+        String url = getUrl(nsInstanceId, CommonConstant.Step.TERMINATE);
+        String methodType = CommonConstant.MethodType.POST;
+
+        // Step3: prepare restful parameters and options
+        Map<String, String> reqBody = new HashMap<>();
+        reqBody.put("nsInstanceId", nsInstanceId);
+        reqBody.put("terminationType", "graceful");
+        reqBody.put("gracefulTerminationTimeout", "60");
+
+        // Step4: Call the NFVO or SDNO service to terminate service
+        String terminateReq = JsonUtil.marshal(reqBody);
+        logInfoMsg("terminate ns request: \n" + terminateReq);
+        RestfulResponse terminateRsp = RestfulUtil.send(url, methodType, terminateReq);
+        ValidateUtil.assertObjectNotNull(terminateRsp);
+        logInfoMsg("terminate ns response status is : " + terminateRsp.getStatus());
+        logInfoMsg("terminate ns response content is : " + terminateRsp.getResponseContent());
+
+        // Step 3: update segment operation
+        if(!HttpCode.isSucess(terminateRsp.getStatus())) {
+            LOGGER.error(MessageEnum.RA_NS_EXC, "VFC Adapter", "", MsoLogger.ErrorCode.BusinessProcesssError,
+                    "fail to instantiate ns");
+
+            nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
+            nsOperInfo.setErrorCode(String.valueOf(terminateRsp.getStatus()));
+            nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED);
+            (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+
+            throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_TERMINATE_NS);
+        }
+        @SuppressWarnings("unchecked")
+        Map<String, String> rsp = JsonUtil.unMarshal(terminateRsp.getResponseContent(), Map.class);
+        String jobId = rsp.get(CommonConstant.JOB_ID);
+        if(ValidateUtil.isStrEmpty(jobId)) {
+            LOGGER.error(MessageEnum.RA_NS_EXC, "VFC Adapter", "", MsoLogger.ErrorCode.BusinessProcesssError,
+                    "Invalid jobId from terminate operation");
+            nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
+            nsOperInfo.setErrorCode(String.valueOf(terminateRsp.getStatus()));
+            nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED);
+            (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+            throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
+                    DriverExceptionID.INVALID_RESPONSE_FROM_TERMINATE_OPERATION);
+        }
+        logInfoMsg("update resource status job id -> begin");
+
+        nsOperInfo.setJobId(jobId);
+        (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+
+        logInfoMsg("update resource status job id -> end");
+        logInfoMsg("terminate ns -> end");
+        return terminateRsp;
+    }
+
+    /**
+     * get ns progress by job Id <br>
+     * 
+     * @param nsOperationKey The OperationKey for NS resource
+     * @param jobId the job id
+     * @return
+     * @since ONAP Amsterdam Release
+     */
+    public RestfulResponse getNsProgress(NsOperationKey nsOperationKey, String jobId) throws ApplicationException {
+
+        logInfoMsg("query ns status -> begin");
+        ValidateUtil.assertObjectNotNull(jobId);
+        // Step 1: query the current resource operation status
+        ResourceOperationStatus nsOperInfo = (RequestsDatabase.getInstance()).getResourceOperationStatus(
+                nsOperationKey.getServiceId(), nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateUUID());
+
+        String url = getUrl(jobId, CommonConstant.Step.QUERY);
+        String methodType = CommonConstant.MethodType.GET;
+        // prepare restful parameters and options
+        logInfoMsg("query ns job request start.");
+        RestfulResponse rsp = RestfulUtil.send(url, methodType, "");
+        ValidateUtil.assertObjectNotNull(rsp);
+        logInfoMsg("query ns progress response status is : " + rsp.getStatus());
+        logInfoMsg("query ns progress response content is : " + rsp.getResponseContent());
+
+        // Step 3:check the response staus
+        if(!HttpCode.isSucess(rsp.getStatus())) {
+            LOGGER.error(MessageEnum.RA_NS_EXC, "VFC Adapter", "", MsoLogger.ErrorCode.BusinessProcesssError,
+                    "fail to query job status");
+            nsOperInfo.setErrorCode(String.valueOf(rsp.getStatus()));
+            nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
+            nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.QUERY_JOB_STATUS_FAILED);
+            (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+            throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_QUERY_JOB_STATUS);
+        }
+        // Step 4: Process Network Service Instantiate Response
+        NsProgressStatus nsProgress = JsonUtil.unMarshal(rsp.getResponseContent(), NsProgressStatus.class);
+        ResponseDescriptor rspDesc = nsProgress.getResponseDescriptor();
+        // Step 5: update segment operation progress
+
+        nsOperInfo.setProgress(rspDesc.getProgress());
+        nsOperInfo.setStatusDescription(rspDesc.getStatusDescription());
+        (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+
+        // Step 6: update segment operation status
+        if(RequestsDbConstant.Progress.ONE_HUNDRED.equals(rspDesc.getProgress())
+                && RequestsDbConstant.Status.FINISHED.equals(rspDesc.getStatus())) {
+            logInfoMsg("job result is succeeded, operType is " + nsOperInfo.getOperType());
+
+            nsOperInfo.setErrorCode(String.valueOf(rsp.getStatus()));
+
+            if(RequestsDbConstant.OperationType.CREATE.equals(nsOperInfo.getOperType())) {
+                nsOperInfo.setStatus(RequestsDbConstant.Status.FINISHED);
+            }
+            (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+        } else if(RequestsDbConstant.Status.ERROR.equals(rspDesc.getStatus())) {
+            LOGGER.error(MessageEnum.RA_NS_EXC, "VFC Adapter", "", MsoLogger.ErrorCode.BusinessProcesssError,
+                    "job result is failed, operType is " + nsOperInfo.getOperType());
+
+            nsOperInfo.setErrorCode(String.valueOf(rsp.getStatus()));
+            nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.QUERY_JOB_STATUS_FAILED);
+            nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
+            (RequestsDatabase.getInstance()).updateResOperStatus(nsOperInfo);
+            throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.JOB_STATUS_ERROR);
+        } else {
+            LOGGER.error(MessageEnum.RA_NS_EXC, "VFC Adapter", "", MsoLogger.ErrorCode.BusinessProcesssError,
+                    "unexcepted response status");
+        }
+        logInfoMsg("query ns status -> end");
+        return rsp;
+    }
+
+    /**
+     * get url for the operation <br>
+     * 
+     * @param variable variable should be put in the url
+     * @param step step of the operation (terminate,query,delete)
+     * @return
+     * @since ONAP Amsterdam Release
+     */
+    private String getUrl(String variable, String step) {
+
+        String url;
+        String originalUrl;
+        originalUrl = (String)nfvoUrlMap.get(step);
+        url = String.format(originalUrl, variable);
+        return url;
+
+    }
+
+    private void logInfoMsg(String msg) {
+        LOGGER.info(MessageEnum.RA_NS_EXC, msg, "org.openecomp.mso.adapters.vfc.VfcManager", "VFC Adapter");
+    }
 }
diff --git a/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/util/RestfulUtil.java b/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/util/RestfulUtil.java
index e8718fa..7690d80 100644
--- a/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/util/RestfulUtil.java
+++ b/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/util/RestfulUtil.java
@@ -75,7 +75,7 @@
             msbPort = msoPropertiesFactory.getMsoJavaProperties("MSO_PROP_TOPOLOGY").getProperty("msb-port", "8099");
 
         } catch(MsoPropertiesException e) {
-            LOGGER.error(MessageEnum.RA_NS_EXC, "VFC", "", MsoLogger.ErrorCode.AvailabilityError,
+            LOGGER.error(MessageEnum.RA_NS_EXC, "VFC Adapter", "", MsoLogger.ErrorCode.AvailabilityError,
                     "Get msb properties failed");
             e.printStackTrace();
         }
@@ -88,8 +88,7 @@
 
     public static RestfulResponse send(String url, String methodType, String content) {
         String msbUrl = getMsbHost() + url;
-        LOGGER.info(MessageEnum.RA_NS_EXC, msbUrl, "VFC", "");
-        LOGGER.debug("VFC Request Body:\n" + content);
+        LOGGER.info(MessageEnum.RA_NS_EXC, "Begin to sent message " + methodType +": " + msbUrl, "org.openecomp.mso.adapters.vfc.util.RestfulUtil","VFC Adapter");
 
         HttpRequestBase method = null;
         HttpResponse httpResponse = null;
@@ -158,8 +157,6 @@
             }
 
             method = null;
-
-            LOGGER.info(MessageEnum.RA_RESPONSE_FROM_SDNC, responseContent, "VFC", "");
             return createResponse(statusCode, responseContent);
 
         } catch(SocketTimeoutException e) {
@@ -197,12 +194,12 @@
     }
 
     private static void logError(String errMsg, Throwable t) {
-        LOGGER.error(MessageEnum.RA_NS_EXC, "VFC", "", MsoLogger.ErrorCode.AvailabilityError, errMsg, t);
+        LOGGER.error(MessageEnum.RA_NS_EXC, "VFC Adapter", "", MsoLogger.ErrorCode.AvailabilityError, errMsg, t);
         ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, errMsg);
     }
 
     private static void logError(String errMsg) {
-        LOGGER.error(MessageEnum.RA_NS_EXC, "VFC", "", MsoLogger.ErrorCode.AvailabilityError, errMsg);
+        LOGGER.error(MessageEnum.RA_NS_EXC, "VFC Adapter", "", MsoLogger.ErrorCode.AvailabilityError, errMsg);
         ALARMLOGGER.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, errMsg);
     }
 
@@ -213,39 +210,4 @@
         return rsp;
     }
 
-    /**
-     * @param request
-     * @return
-     */
-    // public static String getRequestBody(HttpServletRequest request) {
-    // String body = null;
-    // StringBuilder stringBuilder = new StringBuilder();
-    // BufferedReader bufferedReader = null;
-    // try {
-    // InputStream inputStream = request.getInputStream();
-    // if (inputStream != null) {
-    // bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
-    // char[] charBuffer = new char[128];
-    // int bytesRead = -1;
-    // while ((bytesRead = bufferedReader.read(charBuffer)) > 0)
-    // stringBuilder.append(charBuffer, 0, bytesRead);
-    // }
-    // } catch (IOException ex) {
-    // LOGGER.error(MessageEnum.RA_NS_EXC, "VFC", "", MsoLogger.ErrorCode.AvailabilityError,
-    // "read inputStream buffer catch exception:", ex);
-    // } finally {
-    // if (bufferedReader != null) {
-    // try {
-    // bufferedReader.close();
-    // } catch (IOException ex) {
-    // LOGGER.error(MessageEnum.RA_NS_EXC, "VFC", "", MsoLogger.ErrorCode.AvailabilityError,
-    // "close buffer catch exception:", ex);
-    // }
-    // }
-    // }
-    //
-    // body = stringBuilder.toString();
-    // return body;
-    // }
-
 }
diff --git a/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/util/ValidateUtil.java b/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/util/ValidateUtil.java
index 26f8d6e..c79d09e 100644
--- a/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/util/ValidateUtil.java
+++ b/adapters/mso-vfc-adapter/src/main/java/org/openecomp/mso/adapters/vfc/util/ValidateUtil.java
@@ -22,15 +22,15 @@
 
 import org.openecomp.mso.adapters.vfc.constant.HttpCode;
 import org.openecomp.mso.adapters.vfc.exceptions.ApplicationException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoLogger;
 
 public class ValidateUtil {
 
   /**
    * Log server.
    */
-  private static final Logger LOGGER = LoggerFactory.getLogger(ValidateUtil.class);
+  private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
 
   /**
    * Constructor<br/>
@@ -55,8 +55,8 @@
     if (null != paramValue && !paramValue.isEmpty()) {
       return;
     }
+    LOGGER.error(MessageEnum.RA_NS_EXC, "VFC Adapter", "", MsoLogger.ErrorCode.AvailabilityError, paramName + ": Parameter is null or empty.");
 
-    LOGGER.error(paramName + ": Parameter is null or empty.");
     throw new ApplicationException(HttpCode.BAD_REQUEST, paramName + ": Invalid parameter.");
   }
 
@@ -68,7 +68,8 @@
    */
   public static void assertObjectNotNull(Object object) throws ApplicationException {
     if (null == object) {
-      LOGGER.error("Object is null.");
+      LOGGER.error(MessageEnum.RA_NS_EXC, "VFC Adapter", "", MsoLogger.ErrorCode.AvailabilityError, "Object is null.");
+
       throw new ApplicationException(HttpCode.BAD_REQUEST, "Object is null.");
     }
 
diff --git a/common/src/main/resources/ResourceAdapter.properties b/common/src/main/resources/ResourceAdapter.properties
index 9995260..0dbbb3c 100644
--- a/common/src/main/resources/ResourceAdapter.properties
+++ b/common/src/main/resources/ResourceAdapter.properties
@@ -331,7 +331,12 @@
                   MSO-RA-5297I|\
                   Received Workflow Message: {0}|\
                   No resolution needed|\
-                  Received Workflow Message                                                                   
+                  Received Workflow Message   
+RA_NS_EXC=\
+                  MSO-RA-5298I|\
+                  VFC Adatper Message: {0}|\
+                  No resolution needed|\
+                  VFC Adatper Message                                                                                   
 RA_GENERAL_EXCEPTION_ARG=\
                   MSO-RA-9200E|\
                   Exception: {0}|\
