Callout hooks towards external server for create and delete operations 25/8625/2
authorhalil.cakal <halil.cakal@est.tech>
Mon, 13 Jun 2022 08:02:24 +0000 (09:02 +0100)
committerhalil.cakal <halil.cakal@est.tech>
Mon, 27 Jun 2022 11:22:21 +0000 (12:22 +0100)
Patch set 2: Commit message clean-up.

Issue-ID: NONRTRIC-756
Change-Id: I73bf9dd8788aeae2ca63ac0143a49bde943788e5
Signed-off-by: halil.cakal <halil.cakal@est.tech>
near-rt-ric-simulator/src/STD_2.0.0/a1.py
near-rt-ric-simulator/test/EXT_SRV/nginx.conf [changed mode: 0644->0755]
near-rt-ric-simulator/test/EXT_SRV/src/main.py [changed mode: 0644->0755]
near-rt-ric-simulator/test/EXT_SRV_TEST/basic_test.sh [changed mode: 0644->0755]
near-rt-ric-simulator/test/EXT_SRV_TEST/build_and_start.sh [changed mode: 0644->0755]
near-rt-ric-simulator/test/STD_2.0.0/basic_test.sh
near-rt-ric-simulator/test/STD_2.0.0/build_and_start.sh
near-rt-ric-simulator/test/common/test_common.sh

index 2dc7b55..28eccc6 100644 (file)
 #  ============LICENSE_END=================================================
 #
 
+import os
 import copy
 import datetime
 import json
 import logging
 import collections
 import time
+import requests
 
 from connexion import NoContent
 from flask import Flask, escape, request, Response, make_response
@@ -33,6 +35,9 @@ from maincommon import check_apipath, apipath, get_supported_interfaces_response
 APPL_JSON='application/json'
 APPL_PROB_JSON='application/problem+json'
 
+EXT_SRV_URL=os.getenv('EXT_SRV_URL')
+
+
 # API Function: Get all policy type ids
 def get_all_policy_types():
 
@@ -127,6 +132,14 @@ def put_policy(policyTypeId, policyId):
       pjson=create_problem_json(None, "Duplicate, the policy json already exists.", 400, None, policy_id)
       return Response(json.dumps(pjson), 400, mimetype=APPL_PROB_JSON)
 
+  #Callout hooks for external server
+  #When it fails, break and return 419 HTTP status code
+  if (EXT_SRV_URL is not None):
+    resp = callout_external_server(policy_id, data, 'PUT')
+    if (resp != retcode):
+      pjson=create_error_response(resp)
+      return Response(json.dumps(pjson), 500, mimetype=APPL_PROB_JSON)
+
   if (fp_previous is not None):
     del policy_fingerprint[fp_previous]
 
@@ -171,7 +184,6 @@ def get_policy(policyTypeId, policyId):
 
   return Response(json.dumps(policy_instances[policy_type_id][policy_id]), 200, mimetype=APPL_JSON)
 
-
 # API Function: Delete a policy
 def delete_policy(policyTypeId, policyId):
 
@@ -191,6 +203,14 @@ def delete_policy(policyTypeId, policyId):
     pjson=create_problem_json(None, "The requested policy does not exist.", 404, None, policy_id)
     return Response(json.dumps(pjson), 404, mimetype=APPL_PROB_JSON)
 
+  #Callout hooks for external server
+  #When it fails, break and return 419 HTTP status code
+  if (EXT_SRV_URL is not None):
+    resp = callout_external_server(policy_id, None, 'DELETE')
+    if (resp != 204):
+      pjson=create_error_response(resp)
+      return Response(json.dumps(pjson), 500, mimetype=APPL_PROB_JSON)
+
   if (is_duplicate_check()):
     fp_previous=calcFingerprint(policy_instances[policy_type_id][policy_id], policy_type_id)
   else:
@@ -202,7 +222,6 @@ def delete_policy(policyTypeId, policyId):
   callbacks.pop(policy_id)
   return Response('', 204, mimetype=APPL_JSON)
 
-
 # API Function: Get status for a policy
 def get_policy_status(policyTypeId, policyId):
 
@@ -224,16 +243,37 @@ def get_policy_status(policyTypeId, policyId):
 
   return Response(json.dumps(policy_status[policy_id]), status=200, mimetype=APPL_JSON)
 
+# Helper: Callout external server to notify it for policy operations
+# Returns 200, 201 and 204 for the success callout hooks, for the others returns 419
+def callout_external_server(policy_id, payload, operation):
+
+  target_url=EXT_SRV_URL + policy_id
+  try:
+    if (operation == 'PUT'):
+      #Suppress error when self-signed certificate is being used with verify flag
+      resp=requests.put(target_url, json=payload, timeout=10, verify=False)
+      return resp.status_code
+    elif (operation == 'DELETE'):
+      resp=requests.delete(target_url, timeout=10, verify=False)
+      return resp.status_code
+  except Exception:
+    #Return a generic unassigned HTTP status code as per iana, for all exceptions (419:Callout failed)
+    #https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+    return 419
+
 # Helper: Create a response object if forced http response code is set
 def get_forced_response():
+
   if (forced_settings['code'] is not None):
-    pjson=create_error_response(forced_settings['code'])
+    value=forced_settings['code']
+    pjson=create_error_response(int(value))
     forced_settings['code']=None
     return Response(json.dumps(pjson), pjson['status'], mimetype=APPL_PROB_JSON)
   return None
 
 # Helper: Delay if delayed response code is set
 def do_delay():
+
   if (forced_settings['delay'] is not None):
     try:
       val=int(forced_settings['delay'])
@@ -243,6 +283,7 @@ def do_delay():
 
 # Helper: Check if response shall be delayed or a forced response shall be sent
 def check_modified_response():
+
   do_delay()
   return get_forced_response()
 
@@ -265,19 +306,21 @@ def create_problem_json(type_of, title, status, detail, instance):
 # Helper: Create a problem json based on a generic http response code
 def create_error_response(code):
 
-    if code == '400':
+    if (code == 400):
       return(create_problem_json(None, "Bad request", 400, "Object in payload not properly formulated or not related to the method", None))
-    elif code == '404':
+    elif (code == 404):
       return(create_problem_json(None, "Not found", 404, "No resource found at the URI", None))
-    elif code == '405':
+    elif (code == 405):
       return(create_problem_json(None, "Method not allowed", 405, "Method not allowed for the URI", None))
-    elif code == '409':
+    elif (code == 409):
       return(create_problem_json(None, "Conflict", 409, "Request could not be processed in the current state of the resource", None))
-    elif code == '429':
+    elif (code == 419):
+      return(create_problem_json(None, "Callout failed", 419, "Callout hooks could not be processed on the external server", None))
+    elif (code == 429):
       return(create_problem_json(None, "Too many requests", 429, "Too many requests have been sent in a given amount of time", None))
-    elif code == '507':
+    elif (code == 507):
       return(create_problem_json(None, "Insufficient storage", 507, "The method could not be performed on the resource because the provider is unable to store the representation needed to successfully complete the request", None))
-    elif code == '503':
+    elif (code == 503):
       return(create_problem_json(None, "Service unavailable", 503, "The provider is currently unable to handle the request due to a temporary overload", None))
     else:
       return(create_problem_json(None, "Unknown", code, "Not implemented response code", None))
old mode 100644 (file)
new mode 100755 (executable)
index 7b3e620..0a3bd65
@@ -32,8 +32,8 @@ http {
     perl_set $allow_http 'sub { return $ENV{"ALLOW_HTTP"}; }';
 
     server { # simple reverse-proxy
-       listen      8085;
-        listen      [::]:8085;
+       listen      9095;
+        listen      [::]:9095;
         server_name  localhost;
        if ($allow_http != true) {
            return 444;
@@ -44,13 +44,13 @@ http {
             proxy_set_header   Host                 $host;
             proxy_set_header   X-Real-IP            $remote_addr;
             proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
-            proxy_pass      http://localhost:2222;
+            proxy_pass      http://localhost:3333;
         }
     }
 
     server { # simple reverse-proxy
-        listen      8185 ssl;
-        listen      [::]:8185 ssl;
+        listen      9195 ssl;
+        listen      [::]:9195 ssl;
         server_name  localhost;
         ssl_certificate     /usr/src/app/cert/cert.crt;
         ssl_certificate_key /usr/src/app/cert/key.crt;
@@ -61,7 +61,7 @@ http {
             proxy_set_header   Host                 $host;
             proxy_set_header   X-Real-IP            $remote_addr;
             proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
-            proxy_pass      http://localhost:2222;
+            proxy_pass      http://localhost:3333;
         }
     }
     ##
@@ -90,4 +90,4 @@ http {
     # gzip_buffers 16 8k;
     # gzip_http_version 1.1;
     # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
-}
\ No newline at end of file
+}
old mode 100644 (file)
new mode 100755 (executable)
index 4323d10..9587308
@@ -70,7 +70,7 @@ def forcedelay():
   else:
     return Response("Force delay: " + str(forced_settings['delay']) + " sec set for all external server responses until it is resetted ", 200, mimetype=TEXT_PLAIN)
 
-port_number = 2222
+port_number = 3333
 if len(sys.argv) >= 2:
   if isinstance(sys.argv[1], int):
     port_number = sys.argv[1]
old mode 100644 (file)
new mode 100755 (executable)
index 14490be..2deec7f
@@ -34,12 +34,12 @@ fi
 
 if [ $1 == "nonsecure" ]; then
     #Default http port for the simulator
-    PORT=8085
+    PORT=9095
     # Set http protocol
     HTTPX="http"
 else
     #Default https port for the simulator
-    PORT=8185
+    PORT=9195
     # Set https protocol
     HTTPX="https"
 fi
@@ -47,11 +47,11 @@ fi
 . ../common/test_common.sh
 . ../common/elapse_time_curl.sh
 
-echo "=== Simulator hello world ==="
+echo "=== External server hello world ==="
 RESULT="OK"
 do_curl GET / 200
 
-echo "=== Reset simulator a1policy instances ==="
+echo "=== Reset external server a1policy instances ==="
 RESULT="All a1 policy instances deleted"
 do_curl POST /serveradmin/deleteinstances 200
 
old mode 100644 (file)
new mode 100755 (executable)
index 4deea51..9e2e987
@@ -42,4 +42,4 @@ echo "Starting external server for A1 simulator callouts..."
 echo "PWD path: "$PWD
 
 #Run the container in interactive mode, unsecure port 8085, secure port 8185
-docker run --rm -it -p 8085:8085 -p 8185:8185 -e ALLOW_HTTP=true --volume "$PWD/certificate:/usr/src/app/cert" --name externalserversimulator external_server
+docker run --rm -it -p 9095:9095 -p 9195:9195 -e ALLOW_HTTP=true --volume "$PWD/certificate:/usr/src/app/cert" --name externalserversimulator external_server
index 084a368..fd49caa 100755 (executable)
 # Run the build_and_start with the same arg, except arg 'nonsecure|secure', as this script
 
 print_usage() {
-    echo "Usage: ./basic_test.sh nonsecure|secure duplicate-check|ignore-duplicate "
+    echo "Usage: ./basic_test.sh nonsecure|secure duplicate-check|ignore-duplicate ext-srv|ext-srv-secure|ignore-ext-srv"
     exit 1
 }
 
-if [ $# -ne 2 ]; then
+if [ $# -ne 3 ]; then
     print_usage
 fi
-if [ "$1" != "nonsecure" ] && [ "$1" != "secure" ]; then
+
+if [ $1 != "nonsecure" ] && [ $1 != "secure" ]; then
     print_usage
 fi
-if [ "$2" == "duplicate-check" ]; then
-    DUP_CHECK=1
-elif [ "$2" == "ignore-duplicate" ]; then
-    DUP_CHECK=0
-else
+
+if [ $2 != "duplicate-check" ] && [ $2 != "ignore-duplicate" ]; then
     print_usage
 fi
 
+if [ $3 != "ext-srv" ] && [ $3 != "ext-srv-secure" ] && [ $3 != "ignore-ext-srv" ]; then
+    print_usage
+fi
+
+
 if [ $1 == "nonsecure" ]; then
     #Default http port for the simulator
     PORT=8085
@@ -51,6 +54,28 @@ else
     HTTPX="https"
 fi
 
+if [ $2 == "duplicate-check" ]; then
+    DUP_CHECK=1
+else
+    DUP_CHECK=0
+fi
+
+if [ $3 == "ext-srv" ]; then
+    #Default http port for the external server
+    PORT_EXT_SRV=9095
+    # Set http protocol for external server
+    HTTPX_EXT_SRV="http"
+    EXT_SRV_EXIST=1
+elif [ $3 == "ext-srv-secure" ]; then
+    #Default https port for the external server
+    PORT_EXT_SRV=9195
+    # Set https protocol for external server
+    HTTPX_EXT_SRV="https"
+    EXT_SRV_EXIST=1
+else
+    EXT_SRV_EXIST=0
+fi
+
 . ../common/test_common.sh
 
 
@@ -70,6 +95,21 @@ echo "=== Reset simulator, all ==="
 RESULT="All policy instances and types deleted"
 do_curl POST /deleteall 200
 
+#Test all admin functions in the external server
+if [ $EXT_SRV_EXIST == 1 ]; then
+    echo "=== External server, hello world ==="
+    RESULT="OK"
+    do_curl_ext_srv GET / 200
+
+    echo "=== External server, reset all ==="
+    RESULT="All a1 policy instances deleted"
+    do_curl_ext_srv POST /serveradmin/deleteinstances 200
+
+    echo "=== External server, reset force delay ==="
+    RESULT="Force delay has been resetted for all external server responses"
+    do_curl_ext_srv POST /serveradmin/forcedelay 200
+fi
+
 echo "=== Get counter: interface ==="
 RESULT="STD_2.0.0"
 do_curl GET /counter/interface 200
@@ -144,6 +184,13 @@ res=$(cat jsonfiles/pi1.json)
 RESULT="json:$res"
 do_curl PUT /A1-P/v2/policytypes/STD_1/policies/pi1 201 jsonfiles/pi1.json
 
+if [ $EXT_SRV_EXIST == 1 ]; then
+    echo "=== External server, get a pi1 policy: pi1 ==="
+    res=$(cat jsonfiles/pi1.json)
+    RESULT="json:$res"
+    do_curl_ext_srv GET /a1policy/pi1 200
+fi
+
 echo "=== API: Get policy instance pi1 of type: STD_1 ==="
 res=$(cat jsonfiles/pi1.json)
 RESULT="json:$res"
@@ -154,11 +201,25 @@ res=$(cat jsonfiles/pi1.json)
 RESULT="json:$res"
 do_curl PUT /A1-P/v2/policytypes/STD_1/policies/pi1 200 jsonfiles/pi1.json
 
+if [ $EXT_SRV_EXIST == 1 ]; then
+    echo "=== External server, get a pi1 policy: pi1 ==="
+    res=$(cat jsonfiles/pi1.json)
+    RESULT="json:$res"
+    do_curl_ext_srv GET /a1policy/pi1 200
+fi
+
 echo "=== API: Update policy instance pi1 of type: STD_1==="
 res=$(cat jsonfiles/pi1_updated.json)
 RESULT="json:$res"
 do_curl PUT /A1-P/v2/policytypes/STD_1/policies/pi1 200 jsonfiles/pi1_updated.json
 
+if [ $EXT_SRV_EXIST == 1 ]; then
+    echo "=== External server, get a pi1 policy: pi1 ==="
+    res=$(cat jsonfiles/pi1_updated.json)
+    RESULT="json:$res"
+    do_curl_ext_srv GET /a1policy/pi1 200
+fi
+
 echo "=== API: Duplicate policy instance json,  pi2 of type: STD_1==="
 res=$(cat jsonfiles/pi1_updated.json)
 if [ $DUP_CHECK == 1 ]; then
@@ -171,20 +232,38 @@ else
     RESULT="json:$res"
     do_curl PUT /A1-P/v2/policytypes/STD_1/policies/pi2 201 jsonfiles/pi1_updated.json
 
+    if [ $EXT_SRV_EXIST == 1 ]; then
+        echo "=== External server, get a pi2 policy: pi2 ==="
+        res=$(cat jsonfiles/pi1_updated.json)
+        RESULT="json:$res"
+        do_curl_ext_srv GET /a1policy/pi2 200
+    fi
+
     echo "=== API: DELETE policy instance pi2 ==="
     RESULT=""
     do_curl DELETE /A1-P/v2/policytypes/STD_1/policies/pi2 204
+
+    if [ $EXT_SRV_EXIST == 1 ]; then
+        echo "=== External server, get a pi2 policy: policy instance not found ==="
+        RESULT="json:{\"title\": \"The A1 policy requested does not exist.\", \"status\": 404, \"instance\": \"pi2\"}"
+        do_curl_ext_srv GET /a1policy/pi2 404
+    fi
 fi
 
 echo "=== API: Get policy instances, shall contain pi1=="
 RESULT="json:[ \"pi1\" ]"
 do_curl GET /A1-P/v2/policytypes/STD_1/policies 200
 
+if [ $EXT_SRV_EXIST == 1 ]; then
+    echo "=== External server, get policy instances, shall contain pi1=="
+    RESULT="json:[ \"pi1\" ]"
+    do_curl_ext_srv GET /a1policies 200
+fi
+
 echo "=== Put a policy type: STD_2 ==="
 RESULT="Policy type STD_2 is OK."
 do_curl PUT  '/policytype?id=STD_2' 201 jsonfiles/std_2.json
 
-
 echo "=== API: Duplicate policy instance id pi1 of type: STD_2==="
 res=$(cat jsonfiles/pi1_updated.json)
 RESULT="json:{\"title\": \"The policy id already exist for other policy type.\", \"status\": 400, \"instance\": \"pi1\"}"
@@ -202,7 +281,6 @@ echo "=== Get counter: intstance ==="
 RESULT="1"
 do_curl GET /counter/num_instances 200
 
-
 echo "=== Set force response code 409. ==="
 RESULT="*"
 do_curl POST '/forceresponse?code=409' 200
@@ -263,10 +341,16 @@ echo "=== API: DELETE policy instance pi1 ==="
 RESULT=""
 do_curl DELETE /A1-P/v2/policytypes/STD_1/policies/pi1 204
 
-echo "=== API: Get policy instances, shall contain pi1 and pi2=="
+echo "=== API: Get policy instances, shall contain pi2=="
 RESULT="json:[ \"pi2\" ]"
 do_curl GET /A1-P/v2/policytypes/STD_1/policies 200
 
+if [ $EXT_SRV_EXIST == 1 ]; then
+    echo "=== External server, get policy instances, shall contain pi2=="
+    RESULT="json:[ \"pi2\" ]"
+    do_curl_ext_srv GET /a1policies 200
+fi
+
 echo "=== API: Get policy status ==="
 RESULT="json:{\"enforceStatus\": \"\", \"enforceReason\": \"\"}"
 do_curl GET /A1-P/v2/policytypes/STD_1/policies/pi2/status 200
index a58004a..e903cd5 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 #  ============LICENSE_START===============================================
-#  Copyright (C) 2021 Nordix Foundation. All rights reserved.
+#  Copyright (C) 2021-2022 Nordix Foundation. 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.
 # Make sure to run the simulator with the same arg as this script
 
 print_usage() {
-    echo "Usage: ./build_and_start.sh duplicate-check|ignore-duplicate "
+    echo "Usage: ./build_and_start.sh duplicate-check|ignore-duplicate ext-srv|ext-srv-secure|ignore-ext-srv"
     exit 1
 }
 
-if [ $# -ne 1 ]; then
+if [ $# -ne 2 ]; then
     print_usage
 fi
+
 if [ $1 == "duplicate-check" ]; then
     DUP_CHECK=1
 elif  [ $1 == "ignore-duplicate" ]; then
@@ -36,15 +37,60 @@ else
     print_usage
 fi
 
-echo "Building image"
-cd ../../
+if [ $2 == "ext-srv" ]; then
+    URL="http://localhost:9095/a1policy/"
+elif  [ $2 == "ext-srv-secure" ]; then
+    URL="https://localhost:9195/a1policy/"
+elif  [ $2 == "ignore-ext-srv" ]; then
+    URL=""
+else
+    print_usage
+fi
 
-#Build the image
-docker build -t a1test .
+URL_FLAG=""
+if [ ! -z "$URL" ]; then
+    URL_FLAG="-e EXT_SRV_URL=$URL"
+fi
+
+# Stop and remove container images if they run
 
+echo "Stopping A1 simulator image..."
 docker stop a1StdSimulator > /dev/null 2>&1
 docker rm -f a1StdSimulator > /dev/null 2>&1
 
-echo "Starting ric-sim"
-#Run the container in interactive mode, unsecure port 8085, secure port 8185
-docker run --rm -it -p 8085:8085 -p 8185:8185 -e A1_VERSION=STD_2.0.0 -e ALLOW_HTTP=true -e REMOTE_HOSTS_LOGGING=1 -e DUPLICATE_CHECK=$DUP_CHECK --volume "$PWD/certificate:/usr/src/app/cert" --name a1StdSimulator a1test
+echo "Stopping external server image..."
+docker stop externalserversimulator > /dev/null 2>&1
+docker rm -f externalserversimulator > /dev/null 2>&1
+
+# Initialize path variables for certificate and build operations
+
+dirstd2=$PWD
+
+cd ../../
+dirnrtsim=$PWD
+
+cd test/EXT_SRV/
+dirextsrv=$PWD
+
+# Build containers
+
+cd $dirnrtsim
+echo "Building A1 simulator image..."
+docker build -t a1test .
+
+if [ ! -z "$URL" ]; then
+    cd $dirextsrv
+    echo "Building external server image..."
+    docker build -t external_server .
+fi
+
+# Run containers
+
+# Runs external_server in detached mode
+# In order to tail logs use:: docker logs -f externalserversimulator
+if [ ! -z "$URL" ]; then
+    docker run -d --network host --rm -it -p 9095:9095 -p 9195:9195 -e ALLOW_HTTP=true --volume "$dirextsrv/certificate:/usr/src/app/cert" --name externalserversimulator external_server
+fi
+
+# Runs A1 simulator
+docker run --network host --rm -it -p 8085:8085 -p 8185:8185 -e A1_VERSION=STD_2.0.0 -e ALLOW_HTTP=true -e REMOTE_HOSTS_LOGGING=1 -e DUPLICATE_CHECK=$DUP_CHECK $URL_FLAG --volume "$dirnrtsim/certificate:/usr/src/app/cert" --name a1StdSimulator a1test
index a45a6ff..6d2f80e 100755 (executable)
@@ -73,4 +73,53 @@ do_curl() {
             fi
         fi
     fi
-}
\ No newline at end of file
+}
+
+do_curl_ext_srv() {
+    if [ $# -lt 3 ]; then
+        echo "Need 3 or more parameters, <http-operation> <url> <response-code> [file]: "$@
+        echo "Exiting test script....."
+        exit 1
+    fi
+    curlstr="curl -X "$1" -skw %{http_code} $HTTPX_EXT_SRV://localhost:"${PORT_EXT_SRV}${2}" -H accept:*/*"
+    if [ $# -gt 3 ]; then
+        curlstr=$curlstr" -H Content-Type:application/json --data-binary @"$4
+    fi
+    echo "  CMD (${BASH_LINENO[0]}):"$curlstr
+    res=$($curlstr)
+    status=${res:${#res}-3}
+    body=${res:0:${#res}-3}
+    if [ $status -ne $3 ]; then
+        echo "  Error status :"$status" Expected status: "$3
+        echo "  Body         :"$body
+        echo "Exiting test script....."
+        exit 1
+    else
+        echo "  OK, code           :"$status"     (Expected)"
+        echo "  Body               :"$body
+        if [ "$RESULT" == "*" ]; then
+            echo "  Body contents not checked"
+        elif [[ "$RESULT" == "json:"* ]]; then
+            result=${RESULT:5:${#RESULT}} #Remove 'json:' from the result string
+            res=$(python ../common/compare_json.py "$result" "$body")
+            if [ $res -eq 0 ]; then
+                echo "  Expected json body :"$result
+                echo "  Body as expected"
+            else
+                echo "  Expected json body :"$result
+                echo "Exiting....."
+                exit 1
+            fi
+        else
+            body="$(echo $body | tr -d '\n' )"
+            if [ "$RESULT" == "$body" ]; then
+                echo "  Expected body      :"$RESULT
+                echo "  Body as expected"
+            else
+                echo "  Expected body      :"$RESULT
+                echo "Exiting....."
+                exit 1
+            fi
+        fi
+    fi
+}