Updated function test environment 70/3270/2
authorBjornMagnussonXA <bjorn.magnusson@est.tech>
Thu, 19 Mar 2020 13:31:06 +0000 (14:31 +0100)
committerBjornMagnussonXA <bjorn.magnusson@est.tech>
Mon, 20 Apr 2020 11:28:15 +0000 (13:28 +0200)
Added interface stub for MR

Added simulator monitor

Added function test and test cases

Added a server for catching callbacks from the agent

Added test cases for SNDC A1-Controller NB

README files are generally not updated. Will be made in later commits.

Change-Id: Ibf35f70b3e6f2d3f9c117aaf26ecdb03f80158f8
Issue-ID: NONRTRIC-154
Signed-off-by: BjornMagnussonXA <bjorn.magnusson@est.tech>
66 files changed:
near-rt-ric-simulator/auto-test/.gitignore
near-rt-ric-simulator/auto-test/Dockerize_test.sh
near-rt-ric-simulator/auto-test/FTC1.sh [deleted file]
near-rt-ric-simulator/auto-test/FTC10.sh [new file with mode: 0755]
near-rt-ric-simulator/auto-test/FTC100.sh [new file with mode: 0755]
near-rt-ric-simulator/auto-test/FTC200.sh [new file with mode: 0755]
near-rt-ric-simulator/auto-test/FTC300.sh [new file with mode: 0755]
near-rt-ric-simulator/auto-test/FTC310.sh [new file with mode: 0755]
near-rt-ric-simulator/auto-test/FTC320.sh [new file with mode: 0755]
near-rt-ric-simulator/auto-test/FTC500.sh [new file with mode: 0755]
near-rt-ric-simulator/auto-test/FTC_SDNC.sh [new file with mode: 0755]
near-rt-ric-simulator/auto-test/Suite-interfaces.sh [new file with mode: 0755]
near-rt-ric-simulator/auto-test/testdata/OSC/1.json [new file with mode: 0644]
near-rt-ric-simulator/auto-test/testdata/OSC/2.json [new file with mode: 0644]
near-rt-ric-simulator/auto-test/testdata/OSC/pi1_template.json [new file with mode: 0644]
near-rt-ric-simulator/auto-test/testdata/OSC/pi2_template.json [new file with mode: 0644]
near-rt-ric-simulator/auto-test/testdata/OSC/sim_1.json [new file with mode: 0644]
near-rt-ric-simulator/auto-test/testdata/OSC/sim_2.json [new file with mode: 0644]
near-rt-ric-simulator/auto-test/testdata/STD/EMPTYTYPE.json [new file with mode: 0644]
near-rt-ric-simulator/auto-test/testdata/STD/pi1_template.json [new file with mode: 0644]
near-rt-ric-simulator/auto-test/utils/pa-logviewer.sh [new file with mode: 0755]
near-rt-ric-simulator/common/agent_api_functions.sh [new file with mode: 0644]
near-rt-ric-simulator/common/compare_json.py [new file with mode: 0644]
near-rt-ric-simulator/common/controller_api_functions.sh [new file with mode: 0644]
near-rt-ric-simulator/common/count_json_elements.py [new file with mode: 0644]
near-rt-ric-simulator/common/create_rics_json.py [new file with mode: 0644]
near-rt-ric-simulator/common/do_curl_function.sh [new file with mode: 0755]
near-rt-ric-simulator/common/extract_sdnc_reply.py [new file with mode: 0644]
near-rt-ric-simulator/common/ricsimulator_api_functions.sh [new file with mode: 0644]
near-rt-ric-simulator/common/test_env.sh
near-rt-ric-simulator/common/testcase_common.sh
near-rt-ric-simulator/common/testsuite_common.sh [new file with mode: 0644]
near-rt-ric-simulator/cr/.gitignore [new file with mode: 0644]
near-rt-ric-simulator/cr/Dockerfile [new file with mode: 0644]
near-rt-ric-simulator/cr/README.md [new file with mode: 0644]
near-rt-ric-simulator/cr/basic_test.sh [new file with mode: 0755]
near-rt-ric-simulator/cr/cr-build-start.sh [new file with mode: 0755]
near-rt-ric-simulator/cr/cr.py [new file with mode: 0644]
near-rt-ric-simulator/cr/requirements.txt [new file with mode: 0644]
near-rt-ric-simulator/mrstub/.gitignore [new file with mode: 0644]
near-rt-ric-simulator/mrstub/Dockerfile [new file with mode: 0644]
near-rt-ric-simulator/mrstub/README.md [new file with mode: 0644]
near-rt-ric-simulator/mrstub/basic_test.sh [new file with mode: 0755]
near-rt-ric-simulator/mrstub/mr.py [new file with mode: 0644]
near-rt-ric-simulator/mrstub/mrstub-build-start.sh [new file with mode: 0755]
near-rt-ric-simulator/mrstub/requirements.txt [new file with mode: 0644]
near-rt-ric-simulator/simulator-group/.gitignore [new file with mode: 0644]
near-rt-ric-simulator/simulator-group/consul_cbs/config.json [deleted file]
near-rt-ric-simulator/simulator-group/consul_cbs/consul/cbs_config.hcl
near-rt-ric-simulator/simulator-group/consul_cbs/consul/cbs_localhost_config.hcl
near-rt-ric-simulator/simulator-group/consul_cbs/docker-compose-template.yml [deleted file]
near-rt-ric-simulator/simulator-group/consul_cbs/docker-compose.yml [new file with mode: 0644]
near-rt-ric-simulator/simulator-group/consul_cbs/start.sh
near-rt-ric-simulator/simulator-group/control_panel/docker-compose.yml [new file with mode: 0644]
near-rt-ric-simulator/simulator-group/cr/docker-compose.yml [new file with mode: 0644]
near-rt-ric-simulator/simulator-group/dashboard/docker-compose.yml [deleted file]
near-rt-ric-simulator/simulator-group/mr/docker-compose.yml [new file with mode: 0644]
near-rt-ric-simulator/simulator-group/policy_agent/docker-compose.yml [new file with mode: 0644]
near-rt-ric-simulator/simulator-group/ric/.gitignore [new file with mode: 0644]
near-rt-ric-simulator/simulator-group/ric/cleanConsul.py
near-rt-ric-simulator/simulator-group/ric/docker-compose.yml
near-rt-ric-simulator/simulator-group/ric/prepareConsul.py
near-rt-ric-simulator/simulator-group/sdnc/docker-compose.yml
near-rt-ric-simulator/simulator-group/sim-monitor-start.sh [new file with mode: 0755]
near-rt-ric-simulator/simulator-group/sim-monitor.js [new file with mode: 0644]
near-rt-ric-simulator/simulator-group/simulators-start.sh [deleted file]

index 1c5ae4e..6215d91 100644 (file)
@@ -1,2 +1,10 @@
 logs
-.tmp_*
\ No newline at end of file
+.tmp_*
+.http*
+.p.json
+.tmp.json
+.docker-images-table
+.image-list
+.tmp.curl.json
+.consul*
+.ext.consul*
index 34532c9..dec3217 100755 (executable)
@@ -16,7 +16,7 @@ start_simulators
 
 consul_config_app         "../simulator-group/consul_cbs/config.json"
 
-start_dashboard
+start_control_panel
 
 start_sdnc
 
diff --git a/near-rt-ric-simulator/auto-test/FTC1.sh b/near-rt-ric-simulator/auto-test/FTC1.sh
deleted file mode 100755 (executable)
index 7c614a4..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env bash
-
-TC_ONELINE_DESCR="Auto test for Policy Agent refreshing configurations from consul/cbs"
-
-. ../common/testcase_common.sh $1
-
-#### TEST BEGIN ####
-
-clean_containers
-
-start_simulators
-
-consul_config_app         "../simulator-group/consul_cbs/config.json"
-
-start_policy_agent
-
-check_policy_agent_logs
-
-#### TEST COMPLETE ####
-
-store_logs          END
-
diff --git a/near-rt-ric-simulator/auto-test/FTC10.sh b/near-rt-ric-simulator/auto-test/FTC10.sh
new file mode 100755 (executable)
index 0000000..8808895
--- /dev/null
@@ -0,0 +1,170 @@
+#!/usr/bin/env bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+TC_ONELINE_DESCR="Basic use case, register rapp, create/update policy, delete policy, de-register rapp using both STD and OSC interface over REST and Dmaap"
+
+. ../common/testcase_common.sh $@
+. ../common/agent_api_functions.sh
+
+
+#### TEST BEGIN ####
+
+#Local vars in test script
+##########################
+# Path to callback receiver
+CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
+
+clean_containers
+
+start_ric_simulators  ricsim_g1 3 OSC_2.1.0
+
+start_ric_simulators  ricsim_g2 5 STD_1.1.3
+
+start_mr
+
+start_cr
+
+start_consul_cbs
+
+prepare_consul_config      NOSDNC  ".consul_config.json"
+consul_config_app                  ".consul_config.json"
+
+start_control_panel
+
+#start_sdnc
+
+start_policy_agent
+
+use_agent_rest
+
+api_get_status 200
+
+sim_print ricsim_g1_1 interface
+
+sim_print ricsim_g2_1 interface
+
+sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
+
+api_equal json:policy_types 2 60
+
+
+# Create policies
+use_agent_rest
+
+api_put_service 201 "rapp1" 3600 "$CR_PATH/callbacks/1"
+
+api_put_policy 201 "rapp1" ricsim_g1_1 1 2000 testdata/OSC/pi1_template.json 1
+
+sim_equal ricsim_g1_1 num_instances 1
+
+
+use_agent_dmaap
+
+api_put_policy 201 "rapp1" ricsim_g1_1 1 3000 testdata/OSC/pi1_template.json 1
+
+sim_equal ricsim_g1_1 num_instances 2
+
+
+use_agent_rest
+
+api_put_policy 201 "rapp1" ricsim_g2_1 NOTYPE 2100 testdata/STD/pi1_template.json 1
+
+sim_equal ricsim_g2_1 num_instances 1
+
+
+use_agent_dmaap
+
+api_put_policy 201 "rapp1" ricsim_g2_1 NOTYPE 3100 testdata/STD/pi1_template.json 1
+
+sim_equal ricsim_g2_1 num_instances 2
+
+
+#Update policies
+use_agent_rest
+
+api_put_service 200 "rapp1" 3600 "$CR_PATH/callbacks/1"
+
+api_put_policy 200 "rapp1" ricsim_g1_1 1 2000 testdata/OSC/pi1_template.json 1
+
+sim_equal ricsim_g1_1 num_instances 2
+
+
+use_agent_dmaap
+
+api_put_policy 200 "rapp1" ricsim_g1_1 1 3000 testdata/OSC/pi1_template.json 1
+
+sim_equal ricsim_g1_1 num_instances 2
+
+
+use_agent_rest
+
+
+api_put_policy 200 "rapp1" ricsim_g2_1 NOTYPE 2100 testdata/STD/pi1_template.json 1
+
+sim_equal ricsim_g2_1 num_instances 2
+
+
+use_agent_dmaap
+
+api_put_policy 200 "rapp1" ricsim_g2_1 NOTYPE 3100 testdata/STD/pi1_template.json 1
+
+sim_equal ricsim_g2_1 num_instances 2
+
+# Check policies
+api_get_policy 200 2000 testdata/OSC/pi1_template.json
+api_get_policy 200 3000 testdata/OSC/pi1_template.json
+api_get_policy 200 2100 testdata/STD/pi1_template.json
+api_get_policy 200 3100 testdata/STD/pi1_template.json
+
+# Remove policies
+
+use_agent_dmaap
+api_delete_policy 204 2000
+use_agent_rest
+api_delete_policy 204 3000
+use_agent_dmaap
+api_delete_policy 204 2100
+use_agent_rest
+api_delete_policy 204 3100
+
+sim_equal ricsim_g1_1 num_instances 0
+sim_equal ricsim_g2_1 num_instances 0
+
+# Check policy removal
+use_agent_rest
+api_get_policy 404 2000
+api_get_policy 404 3000
+api_get_policy 404 2100
+api_get_policy 404 3100
+
+# Remove the service
+use_agent_dmaap
+api_delete_services 204 "rapp1"
+
+api_get_services 404 "rapp1"
+
+
+
+check_policy_agent_logs
+
+#### TEST COMPLETE ####
+
+store_logs          END
+
+print_result
\ No newline at end of file
diff --git a/near-rt-ric-simulator/auto-test/FTC100.sh b/near-rt-ric-simulator/auto-test/FTC100.sh
new file mode 100755 (executable)
index 0000000..79fdd49
--- /dev/null
@@ -0,0 +1,324 @@
+#!/usr/bin/env bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+
+TC_ONELINE_DESCR="Full agent API walk through using agent REST/DMAAP and with/without SDNC A1 Controller"
+
+. ../common/testcase_common.sh  $@
+. ../common/agent_api_functions.sh
+. ../common/ricsimulator_api_functions.sh
+. ../common/controller_api_functions.sh
+
+#### TEST BEGIN ####
+
+#Local vars in test script
+##########################
+
+# Path to callback receiver
+CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
+
+# Tested variants of REST/DMAAP/SDNC config
+TESTED_VARIANTS="REST   DMAAP   REST+SDNC   DMAAP+SDNC"
+
+
+for interface in $TESTED_VARIANTS ; do
+
+    echo "#####################################################################"
+    echo "#####################################################################"
+    echo "### Testing agent: "$interface
+    echo "#####################################################################"
+    echo "#####################################################################"
+
+
+    # Clean container and start all needed containers #
+    clean_containers
+
+    start_ric_simulators ricsim_g1 1  OSC_2.1.0
+    start_ric_simulators ricsim_g2 1  STD_1.1.3
+
+    start_mr
+
+    start_cr
+
+    start_consul_cbs
+
+    if [ $interface == "SDNC" ] || [ $interface == "DMAAP+SDNC" ]; then
+        prepare_consul_config      SDNC    ".consul_config.json"
+    else
+        prepare_consul_config      NOSDNC  ".consul_config.json"
+    fi
+
+    consul_config_app                      ".consul_config.json"
+
+    start_control_panel
+
+    if [ $interface == "SDNC" ] || [ $interface == "DMAAP+SDNC" ]; then
+        start_sdnc
+    fi
+
+    start_policy_agent
+
+    if [ $interface == "DMAAP" ] || [ $interface == "DMAAP+SDNC" ]; then
+        use_agent_dmaap
+    else
+        use_agent_rest
+    fi
+
+
+    cr_equal received_callbacks 0
+    mr_equal requests_submitted 0
+
+    sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
+    sim_put_policy_type 201 ricsim_g1_1 2 testdata/OSC/sim_2.json
+
+    api_equal json:rics 2 60
+
+    api_equal json:policy_schemas 3 120
+
+    api_equal json:policy_types 3
+
+    api_equal json:policies 0
+
+    api_equal json:policy_ids 0
+
+
+
+
+    echo "############################################"
+    echo "############## Health check ################"
+    echo "############################################"
+
+    api_get_status 200
+
+    echo "############################################"
+    echo "##### Service registry and supervision #####"
+    echo "############################################"
+
+    api_get_services 404 "rapp1"
+
+    api_put_service 201 "rapp1" 1000 "$CR_PATH/1"
+
+    api_put_service 200 "rapp1" 2000 "$CR_PATH/1"
+
+
+    api_put_service 400 "rapp2" -1 "$CR_PATH/2"
+
+    api_put_service 400 "rapp2" "wrong" "$CR_PATH/2"
+
+    api_put_service 400 "rapp2" 100 "/test"
+
+    api_put_service 400 "rapp2" 100 "test-path"
+
+    api_put_service 201 "rapp2" 300 "ftp://localhost:80/test"
+
+    api_get_services 200 "rapp1" "rapp1" 2000 "$CR_PATH/1"
+
+    api_get_service_ids 200 "rapp1" "rapp2"
+
+
+    api_put_service 201 "rapp3" 5000 "$CR_PATH/3"
+
+
+    api_get_service_ids 200 "rapp1" "rapp2" "rapp3"
+
+
+    api_get_services 200 "rapp1" "rapp1" 2000 "$CR_PATH/1"
+
+    api_get_services 200 NOSERVICE "rapp1" 2000 "$CR_PATH/1" "rapp2" 300 "ftp://localhost:80/test" "rapp3" 5000 "$CR_PATH/3"
+
+    api_get_services 200
+
+    echo -e $YELLOW"TR2"$EYELLOW
+    api_put_services_keepalive 201 "rapp1"
+    echo -e $YELLOW"TR2"$EYELLOW
+    api_put_services_keepalive 201 "rapp3"
+
+    api_put_services_keepalive 200 "rapp1"
+
+    api_put_services_keepalive 200 "rapp3"
+
+    api_put_services_keepalive 404 "rapp5"
+
+    api_get_service_ids 200 "rapp1" "rapp2" "rapp3"
+
+    api_delete_services 204 "rapp1"
+
+    api_get_service_ids 200 "rapp2" "rapp3"
+
+
+    api_put_service 201 "rapp1" 50 "$CR_PATH/1"
+
+    api_get_service_ids 200 "rapp1" "rapp2" "rapp3"
+
+
+    api_delete_services 204 "rapp1"
+    api_delete_services 204 "rapp3"
+
+    api_equal json:services 1
+
+    api_delete_services 204 "rapp2"
+
+    api_equal json:services 0
+
+
+    echo "############################################"
+    echo "############## RIC Repository ##############"
+    echo "############################################"
+
+    api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1,2:AVAILABLE  ricsim_g2_1:me1_ricsim_g2_1,me2_ricsim_g2_1:EMPTYTYPE:AVAILABLE"
+
+    api_get_rics 200 1 "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1,2:AVAILABLE"
+
+    api_get_rics 404 47
+
+    api_get_rics 404 "test"
+
+
+    api_get_ric 200 me1_ricsim_g1_1 ricsim_g1_1
+
+    api_get_ric 200 me2_ricsim_g1_1 ricsim_g1_1
+
+    api_get_ric 200 me1_ricsim_g2_1 ricsim_g2_1
+
+    api_get_ric 200 me2_ricsim_g2_1 ricsim_g2_1
+
+    api_get_ric 404 test
+
+
+    echo "############################################"
+    echo "########### A1 Policy Management ###########"
+    echo "############################################"
+    echo -e $YELLOW"TR9"$EYELLOW
+    api_get_policy_schema 200 1 testdata/OSC/1.json
+    echo -e $YELLOW"TR9"$EYELLOW
+    api_get_policy_schema 200 2 testdata/OSC/2.json
+
+    api_get_policy_schema 404 3
+    echo -e $YELLOW"TR9"$EYELLOW
+    api_get_policy_schemas 200 NORIC testdata/OSC/1.json testdata/OSC/2.json NOFILE
+    echo -e $YELLOW"TR9"$EYELLOW
+    api_get_policy_schemas 200 ricsim_g1_1 testdata/OSC/1.json testdata/OSC/2.json
+
+    api_get_policy_schemas 200 ricsim_g2_1 NOFILE
+
+    api_get_policy_schemas 404 test
+
+
+
+    api_get_policy_types 200 NORIC 1 2 EMPTY
+
+    api_get_policy_types 200 ricsim_g1_1 1 2
+
+    api_get_policy_types 200 ricsim_g2_1 EMPTY
+
+    api_get_policy_types 404 dummy-ric
+
+
+
+    api_put_service 201 "rapp10" 3600 "$CR_PATH/1"
+    echo -e $YELLOW"TR10"$EYELLOW
+    api_put_policy 400 "unregistered-r-app" ricsim_g1_1 1 2000 testdata/OSC/pi1_template.json
+
+    api_put_policy 201 "rapp10" ricsim_g1_1 1 5000 testdata/OSC/pi1_template.json
+    api_put_policy 200 "rapp10" ricsim_g1_1 1 5000 testdata/OSC/pi1_template.json
+
+    api_put_policy 201 "rapp10" ricsim_g2_1 NOTYPE 5100 testdata/STD/pi1_template.json
+    api_put_policy 200 "rapp10" ricsim_g2_1 NOTYPE 5100 testdata/STD/pi1_template.json
+
+    VAL='NOT IN EFFECT'
+    api_get_policy_status 200 5000 OSC "$VAL" "false"
+    api_get_policy_status 200 5100 STD "UNDEFINED"
+
+
+    echo -e $YELLOW"TR10"$EYELLOW
+    api_equal json:policies 2
+    echo -e $YELLOW"TR10"$EYELLOW
+    api_equal json:policy_ids 2
+    echo -e $YELLOW"TR10"$EYELLOW
+    api_get_policy_ids 200 NORIC NOSERVICE NOTYPE 5000 5100
+    echo -e $YELLOW"TR10"$EYELLOW
+    api_get_policy_ids 200 ricsim_g1_1 NOSERVICE NOTYPE 5000
+
+    api_get_policy_ids 200 ricsim_g2_1 NOSERVICE NOTYPE 5100
+
+
+    api_get_policy_ids 200 NORIC "rapp10" NOTYPE 5000 5100
+    echo -e $YELLOW"TR10"$EYELLOW
+    api_get_policy_ids 200 NORIC NOSERVICE 1 5000
+
+    api_get_policy_ids 200 NORIC NOSERVICE 2 NOID
+
+    api_get_policy_ids 200 ricsim_g2_1 NOSERVICE 1 NOID
+
+
+    api_get_policy 200 5000 testdata/OSC/pi1_template.json
+
+    api_get_policy 200 5100 testdata/STD/pi1_template.json
+
+
+
+    api_get_policies 200 ricsim_g1_1 "rapp10" 1 5000 ricsim_g1_1 "rapp10" 1 testdata/OSC/pi1_template.json
+
+
+
+
+    echo -e $YELLOW"TR10"$EYELLOW
+    api_delete_policy 404 2000
+
+    api_delete_policy 404 1500
+
+    api_delete_policy 204 5000
+
+    api_equal json:policies 1
+
+    api_equal json:policy_ids 1
+
+    api_delete_policy 204 5100
+
+    api_equal json:policies 0
+
+    api_equal json:policy_ids 0
+
+    cr_equal received_callbacks 0
+
+    if [ $interface == "DMAAP" ] || [ $interface == "DMAAP+SDNC" ]; then
+        mr_greater requests_submitted 0
+        VAL=$(mr_read requests_submitted)
+        mr_equal requests_fetched $VAL
+        mr_equal responses_submitted $VAL
+        mr_equal responses_fetched $VAL
+        mr_equal current_requests 0
+        mr_equal current_responses 0
+    else
+        mr_equal requests_submitted 0
+    fi
+
+    check_policy_agent_logs
+    check_control_panel_logs
+
+    store_logs          $interface
+
+done
+
+#### TEST COMPLETE ####
+
+
+print_result
+
+auto_clean_containers
diff --git a/near-rt-ric-simulator/auto-test/FTC200.sh b/near-rt-ric-simulator/auto-test/FTC200.sh
new file mode 100755 (executable)
index 0000000..2f62c56
--- /dev/null
@@ -0,0 +1,158 @@
+#!/usr/bin/env bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+
+TC_ONELINE_DESCR="Testing of service registration timeouts and keepalive"
+
+. ../common/testcase_common.sh  $@
+. ../common/agent_api_functions.sh
+. ../common/ricsimulator_api_functions.sh
+
+
+#Local vars in test script
+##########################
+# Path to callback receiver
+CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
+
+
+#### TEST BEGIN ####
+
+clean_containers
+
+start_ric_simulators ricsim_g1 1  OSC_2.1.0
+
+start_mr
+
+start_cr
+
+start_consul_cbs
+
+prepare_consul_config      NOSDNC  ".consul_config.json"
+consul_config_app                  ".consul_config.json"
+
+start_control_panel
+
+#start_sdnc
+
+start_policy_agent
+
+use_agent_rest
+
+#Verify no callbacks or dmaap messages has been sent
+cr_equal received_callbacks 0
+mr_equal requests_submitted 0
+
+#Check agent alive
+api_get_status 200
+
+#Print simulator interface version
+sim_print ricsim_g1_1 interface
+
+api_put_service 201 "rapp1" 15 "$CR_PATH/rapp1"
+
+api_get_services 200 "rapp1" 15 "$CR_PATH/rapp1"
+
+api_put_service 201 "rapp2" 120 "$CR_PATH/rapp2"
+
+api_get_services 200 "rapp2" 120 "$CR_PATH/rapp2"
+
+api_put_service 200 "rapp1" 50 "$CR_PATH/rapp1"
+api_put_service 200 "rapp2" 180 "$CR_PATH/rapp2"
+
+api_get_services 200 "rapp1" 50 "$CR_PATH/rapp1"
+api_get_services 200 "rapp2" 180 "$CR_PATH/rapp2"
+
+api_get_service_ids 200 "rapp1" "rapp2"
+
+sleep_wait 30 "Waiting for keep alive timeout"
+
+api_get_services 200 "rapp1" 50 "$CR_PATH/rapp1"
+api_get_services 200 "rapp2" 180 "$CR_PATH/rapp2"
+
+sleep_wait 100 "Waiting for keep alive timeout"
+
+api_get_services 404 "rapp1"
+api_get_services 200 "rapp2" 180 "$CR_PATH/rapp2"
+
+api_delete_services 204 "rapp2"
+
+api_get_services 404 "rapp1"
+api_get_services 404 "rapp2"
+
+api_put_service 201 "rapp3" 60 "$CR_PATH/rapp3"
+
+api_get_services 200 "rapp3" 60 "$CR_PATH/rapp3"
+
+sleep_wait 30 "Waiting for keep alive timeout"
+
+api_put_service 200 "rapp3" 60 "$CR_PATH/rapp3"
+
+sleep_wait 100 "Waiting for keep alive timeout"
+
+api_get_services 404 "rapp3"
+
+api_put_service 201 "rapp4" 120 "$CR_PATH/rapp4"
+
+sleep_wait 60 "Waiting for keep alive timeout"
+
+api_get_services 200 "rapp4" 120 "$CR_PATH/rapp4"
+
+api_put_services_keepalive 200 "rapp4"
+
+sleep_wait 90 "Waiting for keep alive timeout"
+
+api_get_services 200 "rapp4" 120 "$CR_PATH/rapp4"
+
+api_delete_services 204 "rapp4"
+
+api_get_services 404 "rapp4"
+
+api_get_services 404 "rapp1"
+api_get_services 404 "rapp2"
+api_get_services 404 "rapp3"
+
+api_get_service_ids 200
+
+api_delete_services 404 "rapp1"
+api_delete_services 404 "rapp2"
+api_delete_services 404 "rapp3"
+api_delete_services 404 "rapp4"
+
+api_put_services_keepalive 404 "rapp1"
+api_put_services_keepalive 404 "rapp2"
+api_put_services_keepalive 404 "rapp3"
+api_put_services_keepalive 404 "rapp4"
+
+api_get_service_ids 200
+
+
+
+cr_equal received_callbacks 0
+mr_equal requests_submitted 0
+
+check_policy_agent_logs
+check_control_panel_logs
+
+#### TEST COMPLETE ####
+
+store_logs          END
+
+print_result
+
+auto_clean_containers
\ No newline at end of file
diff --git a/near-rt-ric-simulator/auto-test/FTC300.sh b/near-rt-ric-simulator/auto-test/FTC300.sh
new file mode 100755 (executable)
index 0000000..3b07f60
--- /dev/null
@@ -0,0 +1,90 @@
+#!/usr/bin/env bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+TC_ONELINE_DESCR="Resync 10000 policies using OSC interface over REST"
+
+. ../common/testcase_common.sh  $@
+. ../common/agent_api_functions.sh
+. ../common/ricsimulator_api_functions.sh
+
+#### TEST BEGIN ####
+
+#Local vars in test script
+##########################
+# Path to callback receiver
+CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
+
+clean_containers
+
+start_ric_simulators ricsim_g1 4 OSC_2.1.0
+
+start_mr
+
+start_cr
+
+start_consul_cbs
+
+prepare_consul_config      NOSDNC  ".consul_config.json"
+consul_config_app                  ".consul_config.json"
+
+start_control_panel
+
+
+start_policy_agent
+
+use_agent_rest
+
+api_get_status 200
+
+sim_print ricsim_g1_1 interface
+
+sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
+
+api_equal json:policy_types 1 120  #Wait for the agent to refresh types from the simulator
+
+api_put_service 201 "rapp1" 3600 "$CR_PATH/callbacks/1"
+
+api_put_policy 201 "rapp1" ricsim_g1_1 1 2000 testdata/OSC/pi1_template.json 10000
+
+sim_equal ricsim_g1_1 num_instances 10000
+
+sim_post_delete_instances 200 ricsim_g1_1
+
+sim_equal ricsim_g1_1 num_instances 0
+
+sim_equal ricsim_g1_1 num_instances 10000 300
+
+api_delete_policy 204 2435
+
+api_delete_policy 204 8693
+
+sim_post_delete_instances 200 ricsim_g1_1
+
+sim_post_delete_instances 200 ricsim_g1_1
+
+sim_equal ricsim_g1_1 num_instances 9998 300
+
+
+check_policy_agent_logs
+
+#### TEST COMPLETE ####
+
+store_logs          END
+
+print_result
\ No newline at end of file
diff --git a/near-rt-ric-simulator/auto-test/FTC310.sh b/near-rt-ric-simulator/auto-test/FTC310.sh
new file mode 100755 (executable)
index 0000000..0edd82e
--- /dev/null
@@ -0,0 +1,172 @@
+#!/usr/bin/env bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+TC_ONELINE_DESCR="Repeatedly create and delete 10000 policies in each RICs for 24h. Via agent REST"
+
+. ../common/testcase_common.sh  $@
+. ../common/agent_api_functions.sh
+. ../common/ricsimulator_api_functions.sh
+
+#### TEST BEGIN ####
+
+#Local vars in test script
+##########################
+# Path to callback receiver
+CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
+# Number of RICs per interface type (OSC and STD)
+NUM_RICS=4
+# Number of policy instances per RIC
+NUM_INSTANCES=10000
+
+clean_containers
+
+start_ric_simulators ricsim_g1 4 OSC_2.1.0
+
+start_ric_simulators ricsim_g2 4 STD_1.1.3
+
+start_mr
+
+start_cr
+
+start_consul_cbs
+
+prepare_consul_config      NOSDNC  ".consul_config.json"
+consul_config_app                  ".consul_config.json"
+
+start_control_panel
+
+start_policy_agent
+
+use_agent_rest
+
+api_get_status 200
+
+echo "Print the interface for group 1 simulators, shall be OSC"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_print ricsim_g1_$i interface
+done
+
+echo "Print the interface for group 2 simulators, shall be STD"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_print ricsim_g2_$i interface
+done
+
+echo "Load policy type in group 1 simulators"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_put_policy_type 201 ricsim_g1_$i 1 testdata/OSC/sim_1.json
+done
+
+echo "Check the number of instances in  group 1 simulators, shall be 0"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_equal ricsim_g1_$i num_instances 0
+done
+
+echo "Check the number of instances in  group 2 simulators, shall be 0"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_equal ricsim_g2_$i num_instances 0
+done
+
+echo "Wait for the agent to refresh types from the simulator"
+api_equal json:policy_types 2 120
+
+echo "Check the number of types in the agent for each ric is 1"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   api_equal json:policy_types?ric=ricsim_g1_$i 1 120
+done
+
+echo "Register a service"
+api_put_service 201 "rapp1" 0 "$CR_PATH/1"
+
+TEST_DURATION=$((24*3600))
+TEST_START=$SECONDS
+
+while [ $(($SECONDS-$TEST_START)) -lt $TEST_DURATION ]; do
+
+    echo ""
+    echo "#########################################################################################################"
+    echo -e $BOLD"INFO: Test executed for: "$(($SECONDS-$TEST_START)) "seconds. Target is: "$TEST_DURATION" seconds (24h)."$EBOLD
+    echo "#########################################################################################################"
+    echo ""
+
+
+    echo "Create 10000 instances in each OSC RIC"
+    INSTANCE_ID=200000
+    INSTANCES=0
+    for ((i=1; i<=$NUM_RICS; i++))
+    do
+        api_put_policy 201 "rapp1" ricsim_g1_$i 1 $INSTANCE_ID testdata/OSC/pi1_template.json $NUM_INSTANCES
+        sim_equal ricsim_g1_$i num_instances $NUM_INSTANCES
+        INSTANCE_ID=$(($INSTANCE_ID+$NUM_INSTANCES))
+        INSTANCES=$(($INSTANCES+$NUM_INSTANCES))
+    done
+
+    api_equal json:policy_ids $INSTANCES
+
+    echo "Create 10000 instances in each OSC RIC"
+    for ((i=1; i<=$NUM_RICS; i++))
+    do
+        api_put_policy 201 "rapp1" ricsim_g2_$i NOTYPE $INSTANCE_ID testdata/STD/pi1_template.json $NUM_INSTANCES
+        sim_equal ricsim_g2_$i num_instances $NUM_INSTANCES
+        INSTANCE_ID=$(($INSTANCE_ID+$NUM_INSTANCES))
+        INSTANCES=$(($INSTANCES+$NUM_INSTANCES))
+    done
+
+    api_equal json:policy_ids $INSTANCES
+
+
+    echo "Delete all instances in each OSC RIC"
+
+    INSTANCE_ID=200000
+    for ((i=1; i<=$NUM_RICS; i++))
+    do
+        api_delete_policy 204 $INSTANCE_ID $NUM_INSTANCES
+        INSTANCES=$(($INSTANCES-$NUM_INSTANCES))
+        sim_equal ricsim_g1_$i num_instances $NUM_INSTANCES
+        INSTANCE_ID=$(($INSTANCE_ID+$NUM_INSTANCES))
+    done
+
+    api_equal json:policy_ids $INSTANCES
+
+    echo "Delete all instances in each STD RIC"
+    INSTANCE_ID=200000
+    for ((i=1; i<=$NUM_RICS; i++))
+    do
+        api_delete_policy 204 $INSTANCE_ID $NUM_INSTANCES
+        INSTANCES=$(($INSTANCES-$NUM_INSTANCES))
+        sim_equal ricsim_g2_$i num_instances $NUM_INSTANCES
+        INSTANCE_ID=$(($INSTANCE_ID+$NUM_INSTANCES))
+    done
+
+    api_equal json:policy_ids 0
+done
+
+
+check_policy_agent_logs
+
+#### TEST COMPLETE ####
+
+store_logs          END
+
+print_result
\ No newline at end of file
diff --git a/near-rt-ric-simulator/auto-test/FTC320.sh b/near-rt-ric-simulator/auto-test/FTC320.sh
new file mode 100755 (executable)
index 0000000..2b1b96a
--- /dev/null
@@ -0,0 +1,202 @@
+#!/usr/bin/env bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+TC_ONELINE_DESCR="Create and delete 50 policies in each 50 RICs, 25 STD version, 25 OSC version. Via agent REST"
+
+. ../common/testcase_common.sh  $@
+. ../common/agent_api_functions.sh
+. ../common/ricsimulator_api_functions.sh
+
+#### TEST BEGIN ####
+
+#Local vars in test script
+##########################
+# Path to callback receiver
+CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
+# Number of RICs
+NUM_RICS=25
+# Number of instances per RIC
+NUM_INST=50
+
+# Clean and start all containers
+clean_containers
+
+start_ric_simulators ricsim_g1 $NUM_RICS OSC_2.1.0
+
+start_ric_simulators ricsim_g2 $NUM_RICS STD_1.1.3
+
+start_mr
+
+start_cr
+
+start_consul_cbs
+
+prepare_consul_config      NOSDNC  ".consul_config.json"
+consul_config_app                  ".consul_config.json"
+
+start_control_panel
+
+start_policy_agent
+
+use_agent_rest
+
+set_agent_debug
+
+# Main tests
+
+echo "Checking agent is alive"
+api_get_status 200
+
+
+echo "Print the interface for group 1 simulators, shall be OSC"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_print ricsim_g1_$i interface
+done
+
+echo "Print the interface for group 2 simulators, shall be STD"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_print ricsim_g2_$i interface
+done
+
+echo "Checking the number of policy instances in each group 1 simulator, shall be 0"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_equal ricsim_g1_$i num_instances 0
+done
+
+echo "Checking the number of policy instances in each group 2 simulator, shall be 0"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_equal ricsim_g1_$i num_instances 0
+done
+
+echo "Load policy type 1 in each group 1 simulator"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_put_policy_type 201 ricsim_g1_$i 1 testdata/OSC/sim_1.json
+done
+
+echo "Checking the number of policy types in each group 1 simulator, shall be 1"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_equal ricsim_g1_$i num_types 1
+done
+
+echo "Checking the number of policy types in each group 2 simulator, shall be 0"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_equal ricsim_g2_$i num_types 0
+done
+
+echo "Check the number of rics, shall be the configured number: ""$(($NUM_RICS*2))"
+api_equal json:rics "$(($NUM_RICS*2))" 120
+
+api_equal json:policy_types 2 120  #Wait for the agent to refresh types from the simulator
+
+sleep_wait 120 "Wait for the agent to refresh the types from all rics"
+
+echo "Check the number of types in the agent for each group 1 rics, shall be 1"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   api_equal json:policy_types?ric=ricsim_g1_$i 1
+done
+
+echo "Check the number of types in the agent for each group 2 rics, shall be 1"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   api_equal json:policy_types?ric=ricsim_g2_$i 1
+done
+
+echo "Register the service"
+api_put_service 201 "rapp1" 0 "$CR_PATH/1"
+
+echo "Loading "$NUM_INST" policies in each group 1 ric"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   inst=$((1000000+$i*$NUM_INST))
+   api_put_policy 201 "rapp1" ricsim_g1_$i 1 $inst testdata/OSC/pi1_template.json $NUM_INST
+done
+
+echo "Loading "$NUM_INST" policies in each group 2 ric"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   inst=$((2000000+$i*$NUM_INST))
+   api_put_policy 201 "rapp1" ricsim_g2_$i NOTYPE $inst testdata/STD/pi1_template.json $NUM_INST
+done
+
+echo "Check the number of types in the agent for each group 1 rics, shall be 1"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   api_equal json:policy_types?ric=ricsim_g1_$i 1
+done
+
+echo "Check the number of types in the agent for each group 2 rics, shall be 1"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   api_equal json:policy_types?ric=ricsim_g2_$i 1
+done
+
+echo "Checking the number of policy instances in each group 1 simulator, shall be "$NUM_INST
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_equal ricsim_g1_$i num_instances 50
+done
+
+echo "Checking the number of policy instances in each group 2 simulator, shall be "$NUM_INST
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_equal ricsim_g2_$i num_instances 50
+done
+
+echo "Deleting "$NUM_INST" policies in each group 1 ric"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   inst=$((1000000+$i*$NUM_INST))
+   api_delete_policy 201 $NUM_INST
+done
+
+echo "Deleting "$NUM_INST" policies in each group 2 ric"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   inst=$((2000000+$i*$NUM_INST))
+   api_delete_policy 201 $NUM_INST
+done
+
+echo "Checking the number of policy instances in each group 1 simulator, shall be 0"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_equal ricsim_g1_$i num_instances 50
+done
+
+echo "Checking the number of policy instances in each group 1 simulator, shall be 0"
+for ((i=1; i<=$NUM_RICS; i++))
+do
+   sim_equal ricsim_g2_$i num_instances 50
+done
+
+
+check_policy_agent_logs
+
+#### TEST COMPLETE ####
+
+store_logs          END
+
+print_result
\ No newline at end of file
diff --git a/near-rt-ric-simulator/auto-test/FTC500.sh b/near-rt-ric-simulator/auto-test/FTC500.sh
new file mode 100755 (executable)
index 0000000..41c0824
--- /dev/null
@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+
+TC_ONELINE_DESCR="Sample tests of the SDNC A1 controller restconf API"
+
+. ../common/testcase_common.sh  $@
+. ../common/controller_api_functions.sh
+. ../common/ricsimulator_api_functions.sh
+
+#### TEST BEGIN ####
+
+# Clean container and start all needed containers #
+clean_containers
+
+start_ric_simulators ricsim_g1 1  OSC_2.1.0
+start_ric_simulators ricsim_g2 1  STD_1.1.3
+
+start_sdnc
+
+# API tests
+echo -e $YELLOW"TR13"$EYELLOW
+controller_api_get_A1_policy_type 404 OSC ricsim_g1_1 1
+
+sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
+
+
+controller_api_get_A1_policy_ids 200 OSC ricsim_g1_1 1
+controller_api_get_A1_policy_ids 200 STD ricsim_g2_1
+
+controller_api_get_A1_policy_type 200 OSC ricsim_g1_1 1
+controller_api_get_A1_policy_type 200 OSC ricsim_g1_1 1 testdata/OSC/sim_1.json
+
+controller_api_put_A1_policy 202 OSC ricsim_g1_1 1 4000 testdata/OSC/pi1_template.json
+controller_api_put_A1_policy 201 STD ricsim_g2_1 5000   testdata/STD/pi1_template.json
+
+controller_api_get_A1_policy_ids 200 OSC ricsim_g1_1 1 4000
+controller_api_get_A1_policy_ids 200 STD ricsim_g2_1 5000
+
+controller_api_get_A1_policy_status 200 OSC ricsim_g1_1 1 4000
+controller_api_get_A1_policy_status 200 STD ricsim_g2_1 5000
+
+VAL='NOT IN EFFECT'
+controller_api_get_A1_policy_status 200 OSC ricsim_g1_1 1 4000 "$VAL" "false"
+controller_api_get_A1_policy_status 200 STD ricsim_g2_1 5000 "UNDEFINED"
+
+controller_api_delete_A1_policy 202 OSC ricsim_g1_1 1 4000
+controller_api_delete_A1_policy 204 STD ricsim_g2_1 5000
+
+
+
+store_logs          END
+
+#### TEST COMPLETE ####
+
+print_result
+
+auto_clean_containers
\ No newline at end of file
diff --git a/near-rt-ric-simulator/auto-test/FTC_SDNC.sh b/near-rt-ric-simulator/auto-test/FTC_SDNC.sh
new file mode 100755 (executable)
index 0000000..0a8dce5
--- /dev/null
@@ -0,0 +1,94 @@
+#!/usr/bin/env bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+TC_ONELINE_DESCR="Create 1 policy with SDNC and 1 policy without SDNC over agent REST"
+
+. ../common/testcase_common.sh  $@
+. ../common/agent_api_functions.sh
+
+#### TEST BEGIN ####
+
+VARIANTS="NOSDNC SDNC"
+
+for TEST in $VARIANTS ; do
+
+
+    clean_containers
+
+    start_ric_simulators ricsim_g1 1 OSC_2.1.0
+    start_ric_simulators ricsim_g2 1 STD_1.1.3
+
+    start_mr
+
+    start_cr
+
+    start_consul_cbs
+
+    prepare_consul_config      $TEST  ".consul_config.json"
+    consul_config_app                  ".consul_config.json"
+
+    start_control_panel
+
+    if [ $TEST == "SDNC" ]; then
+        start_sdnc
+    fi
+
+    start_policy_agent
+
+
+    set_agent_debug
+
+    use_agent_rest
+
+    echo "Using: "$TEST
+
+    api_get_status 200
+
+    sim_print ricsim_g1_1 interface
+    sim_print ricsim_g2_1 interface
+
+    sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
+
+    api_equal json:policy_types 2 120  #Wait for the agent to refresh types from the simulator
+
+    api_put_service 201 "rapp1" 3600 "http://callback-receiver:8090/callbacks/1"
+
+    api_put_policy 201 "rapp1" ricsim_g1_1 1 2000 testdata/OSC/pi1_template.json 10
+
+    api_put_policy 201 "rapp1" ricsim_g2_1 NOTYPE 3000 testdata/STD/pi1_template.json 10
+
+    sim_equal ricsim_g1_1 num_instances 10
+    sim_equal ricsim_g2_1 num_instances 10
+
+
+    check_policy_agent_logs
+    check_control_panel_logs
+
+    store_logs          $TEST
+
+    echo ""
+    echo -e $BOLD"Test complete for variant: "$TEST $EBOLD
+    echo ""
+
+done
+
+#### TEST COMPLETE ####
+
+print_result
+
diff --git a/near-rt-ric-simulator/auto-test/Suite-interfaces.sh b/near-rt-ric-simulator/auto-test/Suite-interfaces.sh
new file mode 100755 (executable)
index 0000000..38eb83a
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+TS_ONELINE_DESCR="Test suite - interface testing. Agent REST and SNDC controller resconf"
+
+. ../common/testsuite_common.sh
+
+suite_setup
+
+############# TEST CASES #################
+
+./FTC10.sh $1
+./FTC500.sh $1
+
+##########################################
+
+suite_complete
\ No newline at end of file
diff --git a/near-rt-ric-simulator/auto-test/testdata/OSC/1.json b/near-rt-ric-simulator/auto-test/testdata/OSC/1.json
new file mode 100644 (file)
index 0000000..5fe68ce
--- /dev/null
@@ -0,0 +1,40 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "title": "OSC_Type1_1.0.0",
+  "description": "Type 1 policy type",
+  "type": "object",
+  "properties": {
+    "scope": {
+      "type": "object",
+      "properties": {
+        "ueId": {
+          "type": "string"
+        },
+        "qosId": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "required": [
+        "ueId",
+        "qosId"
+      ]
+    },
+    "qosObjective": {
+      "type": "object",
+      "properties": {
+        "priorityLevel": {
+          "type": "number"
+        }
+      },
+      "additionalProperties": false,
+      "required": [
+        "priorityLevel"
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "required": [
+    "scope", "qosObjective"
+  ]
+}
diff --git a/near-rt-ric-simulator/auto-test/testdata/OSC/2.json b/near-rt-ric-simulator/auto-test/testdata/OSC/2.json
new file mode 100644 (file)
index 0000000..9f8a4d4
--- /dev/null
@@ -0,0 +1,36 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "title": "OSC_Type2_1.0.0",
+  "description": "Type 2 policy type",
+  "type": "object",
+  "properties": {
+    "scope": {
+      "type": "object",
+      "properties": {
+        "sliceId": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "required": [
+        "sliceId"
+      ]
+    },
+    "qoeObjectives": {
+      "type": "object",
+      "properties": {
+        "qoeScore": {
+          "type": "number"
+        }
+      },
+      "additionalProperties": false,
+      "required": [
+        "qoeScore"
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "required": [
+    "scope", "qoeObjectives"
+  ]
+}
diff --git a/near-rt-ric-simulator/auto-test/testdata/OSC/pi1_template.json b/near-rt-ric-simulator/auto-test/testdata/OSC/pi1_template.json
new file mode 100644 (file)
index 0000000..7795808
--- /dev/null
@@ -0,0 +1,9 @@
+{
+    "scope": {
+      "ueId": "ueXXX",
+      "qosId": "qosXXX"
+    },
+    "qosObjective": {
+      "priorityLevel": XXX
+    }
+  }
\ No newline at end of file
diff --git a/near-rt-ric-simulator/auto-test/testdata/OSC/pi2_template.json b/near-rt-ric-simulator/auto-test/testdata/OSC/pi2_template.json
new file mode 100644 (file)
index 0000000..c8ac887
--- /dev/null
@@ -0,0 +1,8 @@
+{
+    "scope": {
+      "sliceId": "sliceXXX"
+    },
+    "qoeObjectives": {
+      "qoeScore": XXX
+    }
+  }
\ No newline at end of file
diff --git a/near-rt-ric-simulator/auto-test/testdata/OSC/sim_1.json b/near-rt-ric-simulator/auto-test/testdata/OSC/sim_1.json
new file mode 100644 (file)
index 0000000..537d86f
--- /dev/null
@@ -0,0 +1,45 @@
+{
+  "name": "pt1",
+  "description": "pt1 policy type",
+  "policy_type_id": 1,
+  "create_schema": {
+    "$schema": "http://json-schema.org/draft-07/schema#",
+    "title": "OSC_Type1_1.0.0",
+    "description": "Type 1 policy type",
+    "type": "object",
+    "properties": {
+      "scope": {
+        "type": "object",
+        "properties": {
+          "ueId": {
+            "type": "string"
+          },
+          "qosId": {
+            "type": "string"
+          }
+        },
+        "additionalProperties": false,
+        "required": [
+          "ueId",
+          "qosId"
+        ]
+      },
+      "qosObjective": {
+        "type": "object",
+        "properties": {
+          "priorityLevel": {
+            "type": "number"
+          }
+        },
+        "additionalProperties": false,
+        "required": [
+          "priorityLevel"
+        ]
+      }
+    },
+    "additionalProperties": false,
+    "required": [
+      "scope", "qosObjective"
+    ]
+  }
+}
diff --git a/near-rt-ric-simulator/auto-test/testdata/OSC/sim_2.json b/near-rt-ric-simulator/auto-test/testdata/OSC/sim_2.json
new file mode 100644 (file)
index 0000000..a9eb8f3
--- /dev/null
@@ -0,0 +1,41 @@
+{
+  "name": "pt2",
+  "description": "Pt2 policy type",
+  "policy_type_id": 1,
+  "create_schema": {
+    "$schema": "http://json-schema.org/draft-07/schema#",
+    "title": "OSC_Type2_1.0.0",
+    "description": "Type 2 policy type",
+    "type": "object",
+    "properties": {
+      "scope": {
+        "type": "object",
+        "properties": {
+          "sliceId": {
+            "type": "string"
+          }
+        },
+        "additionalProperties": false,
+        "required": [
+          "sliceId"
+        ]
+      },
+      "qoeObjectives": {
+        "type": "object",
+        "properties": {
+          "qoeScore": {
+            "type": "number"
+          }
+        },
+        "additionalProperties": false,
+        "required": [
+          "qoeScore"
+        ]
+      }
+    },
+    "additionalProperties": false,
+    "required": [
+      "scope", "qoeObjectives"
+    ]
+  }
+}
diff --git a/near-rt-ric-simulator/auto-test/testdata/STD/EMPTYTYPE.json b/near-rt-ric-simulator/auto-test/testdata/STD/EMPTYTYPE.json
new file mode 100644 (file)
index 0000000..9e26dfe
--- /dev/null
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/near-rt-ric-simulator/auto-test/testdata/STD/pi1_template.json b/near-rt-ric-simulator/auto-test/testdata/STD/pi1_template.json
new file mode 100644 (file)
index 0000000..2a87513
--- /dev/null
@@ -0,0 +1,9 @@
+{
+  "scope": {
+    "ueId": "ueXXX",
+    "qosId": "qosXXX"
+  },
+  "qosObjective": {
+    "priorityLevel": XXX
+  }
+}
\ No newline at end of file
diff --git a/near-rt-ric-simulator/auto-test/utils/pa-logviewer.sh b/near-rt-ric-simulator/auto-test/utils/pa-logviewer.sh
new file mode 100755 (executable)
index 0000000..562bbea
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+#Setup trace on
+
+curl http://localhost:8081/actuator/loggers/org.oransc.policyagent.clients.AsyncRestClient -X POST  -H 'Content-Type: application/json' -d '{"configuredLevel":"debug"}'
+
+docker logs -f policy-agent-container
\ No newline at end of file
diff --git a/near-rt-ric-simulator/common/agent_api_functions.sh b/near-rt-ric-simulator/common/agent_api_functions.sh
new file mode 100644 (file)
index 0000000..fbcf240
--- /dev/null
@@ -0,0 +1,1078 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+# This is a script that contains specific test functions for Policy Agent API
+
+### API functiond towards the Policy Agent
+
+# Generic function to query the agent via the REST or DMAAP interface.
+# Used by all other agent api test functions
+# REST or DMAAP is controlled of the base url of $ADAPTER
+# arg: GET|PUT|POST|DELETE <url> [<file>]
+# (Not for test scripts)
+__do_curl_to_agent() {
+    echo "(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       paramError=0
+
+    if [ $# -lt 2 ] || [ $# -gt 3 ]; then
+               paramError=1
+    else
+               timeout=""
+               oper=""
+               file=''
+               httpcode=" -sw %{http_code}"
+               accept=''
+               content=''
+
+               if [ $# -gt 2 ]; then
+                       content=" -H Content-Type:application/json"
+               fi
+               if [ $1 == "GET" ]; then
+                       oper="GET"
+                       if [ $# -ne 2 ];then
+                               paramError=1
+                       fi
+               elif [ $1 == "PUT" ]; then
+                       oper="PUT"
+                       if [ $# -eq 3 ]; then
+                               file=" --data-binary @$3"
+                       fi
+                       accept=" -H accept:application/json"
+               elif [ $1 == "POST" ]; then
+                       oper="POST"
+                       accept=" -H accept:*/*"
+                       if [ $# -ne 2 ];then
+                               paramError=1
+                       fi
+               elif [ $1 == "DELETE" ]; then
+                       oper="DELETE"
+                       if [ $# -ne 2 ];then
+                               paramError=1
+                       fi
+               else
+                       paramError=1
+               fi
+       fi
+
+    if [ $paramError -eq 1 ]; then
+               ((RES_CONF_FAIL++))
+        echo "-Incorrect number of parameters to __do_curl_agent " $@ >> $HTTPLOG
+        echo "-Expected: GET|PUT|POST|DELETE <url> [<file>]" >> $HTTPLOG
+        echo "-Returning response 000" >> $HTTPLOG
+        echo "-000"
+        return 1
+    fi
+
+    if [ $ADAPTER == $RESTBASE ]; then
+        url=" "${ADAPTER}${2}
+        oper=" -X "$oper
+        curlString="curl"${oper}${timeout}${httpcode}${accept}${content}${url}${file}
+        echo " CMD: "$curlString >> $HTTPLOG
+               if [ $# -eq 3 ]; then
+                       echo " FILE: $(<$3)" >> $HTTPLOG
+               fi
+
+               # Do retry for configured response codes, otherwise only one attempt
+               maxretries=5
+               while [ $maxretries -ge 0 ]; do
+
+                       let maxretries=maxretries-1
+                       res=$($curlString)
+                       retcode=$?
+                       if [ $retcode -ne 0 ]; then
+                               echo " RETCODE: "$retcode >> $HTTPLOG
+                               echo "000"
+                               return 1
+                       fi
+                       retry=0
+                       echo " RESP: "$res >> $HTTPLOG
+                       status=${res:${#res}-3}
+                       if [ ! -z "${AGENT_RETRY_CODES}" ]; then
+                               for retrycode in $AGENT_RETRY_CODES; do
+                                       if [ $retrycode -eq $status ]; then
+                                               echo -e $RED" Retrying (according to set codes for retry), got status $status....."$ERED  >> $HTTPLOG
+                                               sleep 1
+                                               retry=1
+                                       fi
+                               done
+                       fi
+                       if [ $retry -eq 0 ]; then
+                               maxretries=-1
+                       fi
+               done
+        echo $res
+        return 0
+    else
+        requestUrl=$2
+        if [ $1 == "PUT" ] && [ $# -eq 3 ]; then
+            payload="$(cat $3 | tr -d '\n' | tr -d ' ' )"
+            echo "payload: "$payload >> $HTTPLOG
+            file=" --data-binary "$payload
+        fi
+               #urlencode the request url since it will be carried by send-request url
+               requestUrl=$(python -c "import urllib, sys; print urllib.quote(sys.argv[1])"  "$2")
+        url=" "${ADAPTER}"/send-request?url="${requestUrl}"&operation="${oper}
+        curlString="curl -X POST${timeout}${httpcode}${content}${url}${file}"
+        echo " CMD: "$curlString >> $HTTPLOG
+        res=$($curlString)
+        retcode=$?
+        if [ $retcode -ne 0 ]; then
+            echo " RETCODE: "$retcode >> $HTTPLOG
+            echo "000"
+            return 1
+        fi
+        echo " RESP: "$res >> $HTTPLOG
+        status=${res:${#res}-3}
+        if [ $status -ne 200 ]; then
+            echo "000"
+            return 1
+        fi
+        cid=${res:0:${#res}-3}
+        url=" "${ADAPTER}"/receive-response?correlationid="${cid}
+        curlString="curl -X GET"${timeout}${httpcode}${url}
+        echo " CMD: "$curlString >> $HTTPLOG
+        res=$($curlString)
+        retcode=$?
+        if [ $retcode -ne 0 ]; then
+            echo " RETCODE: "$retcode >> $HTTPLOG
+            echo "000"
+            return 1
+        fi
+        echo " RESP: "$res >> $HTTPLOG
+        status=${res:${#res}-3}
+               TS=$SECONDS
+               # wait of the reply from the agent...
+        while [ $status -eq 204 ]; do
+                       if [ $(($SECONDS - $TS)) -gt 90 ]; then
+                echo " RETCODE: (timeout after 90s)" >> $HTTPLOG
+                echo "000"
+                return 1
+                       fi
+            sleep 1
+            echo " CMD: "$curlString >> $HTTPLOG
+            res=$($curlString)
+            if [ $retcode -ne 0 ]; then
+                echo " RETCODE: "$retcode >> $HTTPLOG
+                echo "000"
+                return 1
+            fi
+            echo " RESP: "$res >> $HTTPLOG
+            status=${res:${#res}-3}
+        done
+        if [ $status -eq 200 ]; then
+            body=${res:0:${#res}-3}
+            echo $body
+            return 0
+        fi
+        echo "Status not 200, returning response 000" >> $HTTPLOG
+        echo "0000"
+        return 1
+    fi
+}
+
+
+#########################################################
+#### Test case functions A1 Policy management service
+#########################################################
+
+# This function compare the size, towards a target value, of a json array returned from <url> of the Policy Agent.
+# This is done immediately by setting PASS or FAIL or wait up to and optional timeout before setting PASS or FAIL
+# args: json:<url> <target-value> [<timeout-in-seconds]
+# (Function for test scripts)
+api_equal() {
+    echo "(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       if [ $# -eq 2 ] || [ $# -eq 3 ]; then
+               if [[ $1 == "json:"* ]]; then
+                       __var_test "Policy Agent" $LOCALHOST$POLICY_AGENT_EXTERNAL_PORT"/" $1 "=" $2 $3
+                       return 0
+               fi
+       fi
+
+       ((RES_CONF_FAIL++))
+       __print_err "needs two or three args: json:<json-array-param> <target-value> [ timeout ]" $@
+       return 1
+}
+
+# API Test function: GET /policies
+# args: <response-code> <ric-id>|NORIC <service-id>|NOSERVICE <policy-ype-id>|NOTYPE [ NOID | [<policy-id> <ric-id> <service-id> EMPTY|<policy-type-id> <template-file>]*]
+# (Function for test scripts)
+api_get_policies() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+       paramError=0
+       if [ $# -lt 4 ]; then
+               paramError=1
+       elif [ $# -eq 5 ] && [ $5 != "NOID" ]; then
+               paramError=1
+       elif [ $# -gt 4 ] && [ $(($#%5)) -ne 4 ]; then
+               paramError=1
+       fi
+
+    if [ $paramError -ne 0 ]; then
+        __print_err "<response-code> <ric-id>|NORIC <service-id>|NOSERVICE <policy-ype-id>|NOTYPE [ NOID | [<policy-id> <ric-id> <service-id> EMPTY|<policy-type-id> <template-file>]*]" $@
+        return 1
+    fi
+       queryparams=""
+       if [ $2 != "NORIC" ]; then
+               queryparams="?ric="$2
+       fi
+       if [ $3 != "NOSERVICE" ]; then
+               if [ -z $queryparams ]; then
+                       queryparams="?service="$3
+               else
+                       queryparams=$queryparams"&service="$3
+               fi
+       fi
+       if [ $4 != "NOTYPE" ]; then
+               if [ -z $queryparams ]; then
+                       queryparams="?type="$4
+               else
+                       queryparams=$queryparams"&type="$4
+               fi
+       fi
+
+       query="/policies"$queryparams
+    res="$(__do_curl_to_agent GET $query)"
+    status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $# -gt 4 ]; then
+               if [ $# -eq 5 ] && [ $5 == "NOID" ]; then
+                       targetJson="["
+               else
+                       body=${res:0:${#res}-3}
+                       targetJson="["
+                       arr=(${@:5})
+
+                       for ((i=0; i<$(($#-4)); i=i+5)); do
+
+                               if [ "$targetJson" != "[" ]; then
+                                       targetJson=$targetJson","
+                               fi
+                               targetJson=$targetJson"{\"id\":\"${arr[$i]}\",\"lastModified\":\"????\",\"ric\":\"${arr[$i+1]}\",\"service\":\"${arr[$i+2]}\",\"type\":"
+                               if [ "${arr[$i+3]}" == "EMPTY" ]; then
+                                       targetJson=$targetJson"\"\","
+                               else
+                                       targetJson=$targetJson"\"${arr[$i+3]}\","
+                               fi
+                               file=".p.json"
+                               sed 's/XXX/'${arr[$i]}'/g' ${arr[$i+4]} > $file
+                               json=$(cat $file)
+                               targetJson=$targetJson"\"json\":"$json"}"
+                       done
+               fi
+
+               targetJson=$targetJson"]"
+               echo "TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python ../common/compare_json.py "$targetJson" "$body" "id")
+
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+
+}
+
+# API Test function: GET /policy
+#args: <response-code>  <policy-id> [<template-file>]
+# (Function for test scripts)
+api_get_policy() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    if [ $# -lt 2 ] || [ $# -gt 3 ]; then
+        __print_err "<response-code>  <policy-id> [<template-file>] " $@
+        return 1
+    fi
+
+       query="/policy?id=$2"
+       res="$(__do_curl_to_agent GET $query)"
+       status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $# -eq 3 ]; then
+               #Create a policy json to compare with
+               body=${res:0:${#res}-3}
+               file=".p.json"
+               sed 's/XXX/'${2}'/g' $3 > $file
+               targetJson=$(< $file)
+               echo "TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python ../common/compare_json.py "$targetJson" "$body")
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# API Test function: PUT /policy
+# args: <response-code> <service-name> <ric-id> <policytype-id> <policy-id> <template-file> [<count>]
+# (Function for test scripts)
+api_put_policy() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    if [ $# -lt 6 ] || [ $# -gt 7 ]; then
+        __print_err "<response-code> <service-name> <ric-id> <policytype-id> <policy-id> <template-file> [<count>]" $@
+        return 1
+    fi
+
+       ric=$3
+       count=0
+       max=1
+
+       if [ $# -eq 7 ]; then
+               max=$7
+       fi
+
+       pid=$5
+       file=$6
+
+       while [ $count -lt $max ]; do
+               query="/policy?id=$pid&ric=$ric&service=$2"
+
+               if [ $4 == "NOTYPE" ]; then
+                       query="/policy?id=$pid&ric=$ric&service=$2"
+               else
+                       query="/policy?id=$pid&ric=$ric&service=$2&type=$4"
+               fi
+
+               file=".p.json"
+               sed 's/XXX/'${pid}'/g' $6 > $file
+       res="$(__do_curl_to_agent PUT $query $file)"
+       status=${res:${#res}-3}
+               echo -ne " Creating "$count"("$max")\033[0K\r"
+
+               if [ $status -ne $1 ]; then
+                       let pid=$pid+1
+                       echo " Created "$count"?("$max")"
+                       echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+
+               let pid=$pid+1
+               let count=$count+1
+               echo -ne " Created  "$count"("$max")\033[0K\r"
+       done
+       echo ""
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+
+# API Test function: DELETE /policy
+# args: <response-code> <policy-id> [count]
+# (Function for test scripts)
+api_delete_policy() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    if [ $# -lt 2 ] || [ $# -gt 3 ]; then
+        __print_err "<response-code> <policy-id> [count]" $@
+        return 1
+    fi
+
+       count=0
+       max=1
+
+       if [ $# -eq 3 ]; then
+               max=$3
+       fi
+
+       pid=$2
+
+       while [ $count -lt $max ]; do
+               query="/policy?id="$pid
+               res="$(__do_curl_to_agent DELETE $query)"
+               status=${res:${#res}-3}
+               echo -ne " Deleting "$count"("$max")\033[0K\r"
+
+               if [ $status -ne $1 ]; then
+                       echo " Deleted "$count"?("$max")"
+                       echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+               let pid=$pid+1
+               let count=$count+1
+               echo -ne " Deleted  "$count"("$max")\033[0K\r"
+       done
+       echo ""
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# API Test function: GET /policy_ids
+# args: <response-code> <ric-id>|NORIC <service-id>|NOSERVICE <type-id>|NOTYPE ([<policy-instance-id]*|NOID)
+# (Function for test scripts)
+api_get_policy_ids() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    if [ $# -lt 4 ]; then
+               __print_err "<response-code> <ric-id>|NORIC <service-id>|NOSERVICE <type-id>|NOTYPE ([<policy-instance-id]*|NOID)" $@
+               return 1
+       fi
+
+       queryparams=""
+
+       if [ $2 != "NORIC" ]; then
+               queryparams="?ric="$2
+       fi
+
+       if [ $3 != "NOSERVICE" ]; then
+               if [ -z $queryparams ]; then
+                       queryparams="?service="$3
+               else
+                       queryparams=$queryparams"&service="$3
+               fi
+       fi
+       if [ $4 != "NOTYPE" ]; then
+               if [ -z $queryparams ]; then
+                       queryparams="?type="$4
+               else
+                       queryparams=$queryparams"&type="$4
+               fi
+       fi
+
+       query="/policy_ids"$queryparams
+    res="$(__do_curl_to_agent GET $query)"
+    status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $# -gt 4 ]; then
+               body=${res:0:${#res}-3}
+               targetJson="["
+
+               for pid in ${@:5} ; do
+                       if [ "$targetJson" != "[" ]; then
+                               targetJson=$targetJson","
+                       fi
+                       if [ $pid != "NOID" ]; then
+                               targetJson=$targetJson"\"$pid\""
+                       fi
+               done
+
+               targetJson=$targetJson"]"
+               echo "TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python ../common/compare_json.py "$targetJson" "$body")
+
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# API Test function: GET /policy_schema
+# args: <response-code> <policy-type-id> [<schema-file>]
+# (Function for test scripts)
+api_get_policy_schema() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    if [ $# -lt 2 ] || [ $# -gt 3 ]; then
+        __print_err "<response-code> <policy-type-id> [<schema-file>]" $@
+        return 1
+    fi
+
+       query="/policy_schema?id=$2"
+       res="$(__do_curl_to_agent GET $query)"
+       status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $# -eq 3 ]; then
+
+               body=${res:0:${#res}-3}
+
+               targetJson=$(< $3)
+               echo "TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python ../common/compare_json.py "$targetJson" "$body")
+
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# API Test function: GET /policy_schemas
+# args: <response-code>  <ric-id>|NORIC [<schema-file>|NOFILE]*
+# (Function for test scripts)
+api_get_policy_schemas() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    if [ $# -lt 2 ]; then
+        __print_err "<response-code> <ric-id>|NORIC [<schema-file>|NOFILE]*" $@
+        return 1
+    fi
+
+       query="/policy_schemas"
+       if [ $2 != "NORIC" ]; then
+               query=$query"?ric="$2
+       fi
+
+       res="$(__do_curl_to_agent GET $query)"
+       status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $# -gt 2 ]; then
+               body=${res:0:${#res}-3}
+               targetJson="["
+
+               for file in ${@:3} ; do
+                       if [ "$targetJson" != "[" ]; then
+                               targetJson=$targetJson","
+                       fi
+                       if [ $file == "NOFILE" ]; then
+                               targetJson=$targetJson"{}"
+                       else
+                               targetJson=$targetJson$(< $3)
+                       fi
+               done
+
+               targetJson=$targetJson"]"
+               echo "TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python ../common/compare_json.py "$targetJson" "$body")
+
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# API Test function: GET /policy_status
+# arg: <response-code> <policy-id> (STD <enforce-status> [<reason>])|(OSC <instance-status> <has-been-deleted>)
+# (Function for test scripts)
+api_get_policy_status() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+    if [ $# -lt 4 ] || [ $# -gt 5 ]; then
+               __print_err "<response-code> <policy-id> (STD <enforce-status> [<reason>])|(OSC <instance-status> <has-been-deleted>)" $@
+               return 1
+       fi
+
+       targetJson=""
+
+       if [ $3 == "STD" ]; then
+               targetJson="{\"enforceStatus\":\"$4\""
+               if [ $# -eq 5 ]; then
+                       targetJson=$targetJson",\"reason\":\"$5\""
+               fi
+               targetJson=$targetJson"}"
+       elif [ $3 == "OSC" ]; then
+               targetJson="{\"instance_status\":\"$4\""
+               if [ $# -eq 5 ]; then
+                       targetJson=$targetJson",\"has_been_deleted\":\"$5\""
+               fi
+               targetJson=$targetJson",\"created_at\":\"????\"}"
+       else
+               __print_err "<response-code> (STD <enforce-status> [<reason>])|(OSC <instance-status> <has-been-deleted>)" $@
+               return 1
+       fi
+
+       query="/policy_status?id="$2
+
+       res="$(__do_curl_to_agent GET $query)"
+    status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       echo "TARGET JSON: $targetJson" >> $HTTPLOG
+       body=${res:0:${#res}-3}
+       res=$(python ../common/compare_json.py "$targetJson" "$body")
+
+       if [ $res -ne 0 ]; then
+               echo -e $RED" FAIL, returned body not correct"$ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# API Test function: GET /policy_types
+# args: <response-code> [<ric-id>|NORIC [<policy-type-id>|EMPTY [<policy-type-id>]*]]
+# (Function for test scripts)
+api_get_policy_types() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    if [ $# -lt 1 ]; then
+               __print_err "<response-code> [<ric-id>|NORIC [<policy-type-id>|EMPTY [<policy-type-id>]*]]" $@
+               return 1
+       fi
+
+       if [ $# -eq 1 ]; then
+               query="/policy_types"
+       elif [ $2 == "NORIC" ]; then
+               query="/policy_types"
+       else
+               query="/policy_types?ric=$2"
+       fi
+
+    res="$(__do_curl_to_agent GET $query)"
+    status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $# -gt 2 ]; then
+               body=${res:0:${#res}-3}
+               targetJson="["
+
+               for pid in ${@:3} ; do
+                       if [ "$targetJson" != "[" ]; then
+                               targetJson=$targetJson","
+                       fi
+                       if [ $pid == "EMPTY" ]; then
+                               pid=""
+                       fi
+                       targetJson=$targetJson"\"$pid\""
+               done
+
+               targetJson=$targetJson"]"
+               echo "TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python ../common/compare_json.py "$targetJson" "$body")
+
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+#########################################################
+#### Test case functions Health check
+#########################################################
+
+# API Test function: GET /status
+# args: <response-code>
+# (Function for test scripts)
+api_get_status() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+    if [ $# -ne 1 ]; then
+               __print_err "<response-code>" $@
+               return 1
+       fi
+    query="/status"
+    res="$(__do_curl_to_agent GET $query)"
+    status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+#########################################################
+#### Test case functions RIC Repository
+#########################################################
+
+# API Test function: GET /ric
+# args: <reponse-code> <management-element-id> [<ric-id>]
+# (Function for test scripts)
+api_get_ric() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+    if [ $# -lt 2 ] || [ $# -gt 3 ]; then
+               __print_err "<reponse-code> <management-element-id> [<ric-id>]" $@
+               return 1
+       fi
+
+       query="/ric?managedElementId="$2
+
+    res="$(__do_curl_to_agent GET $query)"
+    status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $# -eq 3 ]; then
+               body=${res:0:${#res}-3}
+               if [ "$body" != "$3" ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# API test function: GET /rics
+# args: <reponse-code> <policy-type-id>|NOTYPE [<space-separate-string-of-ricinfo>]
+# example of <space-separate-string-of-ricinfo> = "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1,2,4 ricsim_g1_1:me2_........."
+# format of ric-info:  <ric-id>:<list-of-mes>:<list-of-policy-type-ids>
+# (Function for test scripts)
+api_get_rics() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    if [ $# -lt 2 ]; then
+               __print_err "<reponse-code> <policy-type-id>|NOTYPE [<space-separate-string-of-ricinfo>]" $@
+               return 1
+       fi
+
+       query="/rics"
+       if [ $2 != "NOTYPE" ]; then
+       query="/rics?policyType="$2
+       fi
+
+    res="$(__do_curl_to_agent GET $query)"
+    status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $# -gt 2 ]; then
+               body=${res:0:${#res}-3}
+               res=$(python ../common/create_rics_json.py ".tmp_rics.json" "$3" )
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, could not create target ric info json"$ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+
+               targetJson=$(<.tmp_rics.json)
+       echo "TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python ../common/compare_json.py "$targetJson" "$body")
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+##################################################################
+#### API Test case functions Service registry and supervision ####
+##################################################################
+
+# API test function: PUT /service
+# args: <response-code>  <service-name> <keepalive-timeout> <callbackurl>
+# (Function for test scripts)
+api_put_service() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+    if [ $# -ne 4 ]; then
+        __print_err "<response-code>  <service-name> <keepalive-timeout> <callbackurl>" $@
+        return 1
+    fi
+
+    query="/service"
+    json="{\"callbackUrl\": \""$4"\",\"keepAliveIntervalSeconds\": \""$3"\",\"serviceName\": \""$2"\"}"
+    file=".tmp.json"
+       echo "$json" > $file
+
+    res="$(__do_curl_to_agent PUT $query $file)"
+    status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# API test function: GET /services
+#args: <response-code> [ (<query-service-name> <target-service-name> <keepalive-timeout> <callbackurl>) | (NOSERVICE <target-service-name> <keepalive-timeout> <callbackurl> [<target-service-name> <keepalive-timeout> <callbackurl>]* )]
+# (Function for test scripts)
+api_get_services() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+       #Number of accepted parameters: 1, 2, 4, 7, 10, 13,...
+       paramError=1
+       if [ $# -eq 1 ]; then
+               paramError=0
+       elif [ $# -eq 2 ] && [ $2 != "NOSERVICE" ]; then
+               paramError=0
+       elif [ $# -eq 5 ]; then
+               paramError=0
+       elif [ $# -gt 5 ] && [ $2 == "NOSERVICE" ]; then
+               argLen=$(($#-2))
+               if [ $(($argLen%3)) -eq 0 ]; then
+                       paramError=0
+               fi
+       fi
+
+    if [ $paramError -ne 0 ]; then
+               __print_err "<response-code> [ (<query-service-name> <target-service-name> <keepalive-timeout> <callbackurl>) | (NOSERVICE <target-service-name> <keepalive-timeout> <callbackurl> [<target-service-name> <keepalive-timeout> <callbackurl>]* )]" $@
+               return 1
+       fi
+
+    query="/services"
+
+    if [ $# -gt 1 ] && [ $2 != "NOSERVICE" ]; then
+       query="/services?name="$2
+       fi
+
+    res="$(__do_curl_to_agent GET $query)"
+    status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $# -gt 2 ]; then
+               variableArgCount=$(($#-2))
+               body=${res:0:${#res}-3}
+       targetJson="["
+               shift; shift;
+               cntr=0
+               while [ $cntr -lt $variableArgCount ]; do
+                       servicename=$1; shift;
+                       timeout=$1; shift;
+                       callback=$1; shift;
+                       if [ $cntr -gt 0 ]; then
+                               targetJson=$targetJson","
+                       fi
+                       # timeSinceLastActivitySeconds value cannot be checked since value varies
+                       targetJson=$targetJson"{\"serviceName\": \""$servicename"\",\"keepAliveIntervalSeconds\": "$timeout",\"timeSinceLastActivitySeconds\":\"????\",\"callbackUrl\": \""$callback"\"}"
+                       let cntr=cntr+3
+               done
+               targetJson=$targetJson"]"
+               echo "TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python ../common/compare_json.py "$targetJson" "$body" "serviceName")
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# API test function: GET /services  (only checking service names)
+# args: <response-code> [<service-name>]*"
+# (Function for test scripts)
+api_get_service_ids() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    if [ $# -lt 1 ]; then
+               __print_err "<response-code> [<service-name>]*" $@
+               return 1
+       fi
+
+    query="/services"
+    res="$(__do_curl_to_agent GET $query)"
+    status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       body=${res:0:${#res}-3}
+       targetJson="["
+       for rapp in ${@:2} ; do
+               if [ "$targetJson" != "[" ]; then
+                       targetJson=$targetJson","
+               fi
+               targetJson=$targetJson"{\"callbackUrl\":\"????\",\"keepAliveIntervalSeconds\":\"????\",\"serviceName\":\""$rapp"\",\"timeSinceLastActivitySeconds\":\"????\"}"
+       done
+
+       targetJson=$targetJson"]"
+       echo "TARGET JSON: $targetJson" >> $HTTPLOG
+       res=$(python ../common/compare_json.py "$targetJson" "$body" "serviceName")
+
+       if [ $res -ne 0 ]; then
+               echo -e $RED" FAIL, returned body not correct"$ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# API test function: DELETE /services
+# args: <response-code> <service-name>
+# (Function for test scripts)
+api_delete_services() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    if [ $# -ne 2 ]; then
+               __print_err "<response-code> <service-name>" $@
+               return 1
+       fi
+
+    query="/services?name="$2
+    res="$(__do_curl_to_agent DELETE $query)"
+    status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# API test function: PUT /services/keepalive
+# args: <response-code> <service-name>
+# (Function for test scripts)
+api_put_services_keepalive() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    if [ $# -ne 2 ]; then
+               __print_err "<response-code> <service-name>" $@
+               return 1
+       fi
+
+    query="/services/keepalive?name="$2
+    res="$(__do_curl_to_agent PUT $query)"
+    status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
diff --git a/near-rt-ric-simulator/common/compare_json.py b/near-rt-ric-simulator/common/compare_json.py
new file mode 100644 (file)
index 0000000..7110f48
--- /dev/null
@@ -0,0 +1,65 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+import os
+import json
+import sys
+
+# Deep compare of two json obects
+# If a parameter value in the target json is set to '????' then the result json value is not checked for the that parameter
+# Any included json array will be sorted before comparison
+# An optional array key can be given to sort array of objects containing that key
+
+def comparejson(jsonTarget,jsonResult,arrayKey):
+
+    if isinstance(jsonTarget, dict):
+        if (len(jsonTarget) != len(jsonResult)):
+            return 1
+        for key in jsonTarget.keys():
+            if (jsonResult.get(key) is None):
+                return 1
+            if (comparejson(jsonTarget.get(key), jsonResult.get(key), arrayKey) != 0):
+                return 1
+    elif isinstance(jsonTarget, list):
+        if (len(jsonTarget) != len(jsonResult)):
+            return 1
+        if (arrayKey is None):
+            jsonTarget.sort()
+            jsonResult.sort()
+        else:
+            jsonTarget.sort(key=lambda k: k[arrayKey])
+            jsonResult.sort(key=lambda k: k[arrayKey])
+
+        for i in range(len(jsonTarget)):
+            if (comparejson(jsonTarget[i], jsonResult[i], arrayKey) != 0):
+                return 1
+    else:
+        if (jsonTarget != "????") and (jsonTarget != jsonResult):
+            return 1
+    return 0
+
+try:
+    jsonTarget = json.loads(sys.argv[1])
+    jsonResult = json.loads(sys.argv[2])
+    arrayKey = None
+    if (len(sys.argv) > 3):
+        arrayKey = sys.argv[3]
+    print(comparejson(jsonTarget,jsonResult,arrayKey))
+
+except Exception as e:
+    print (1)
+sys.exit()
\ No newline at end of file
diff --git a/near-rt-ric-simulator/common/controller_api_functions.sh b/near-rt-ric-simulator/common/controller_api_functions.sh
new file mode 100644 (file)
index 0000000..ed298f1
--- /dev/null
@@ -0,0 +1,352 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+# This is a script that contains specific test functions for A1 Controller API
+
+# Generic function to query the RICs via the A1-controller API.
+# args: <operation> <url> [<body>]
+# <operation>: getA1Policy,putA1Policy,getA1PolicyType,deleteA1Policy,getA1PolicyStatus
+# response: <json-body><3-digit-response-code>
+# (Not for test scripts)
+__do_curl_to_controller() {
+    echo " (${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+    if [ $# -ne 2 ] && [ $# -ne 3 ]; then
+               ((RES_CONF_FAIL++))
+        echo "-Incorrect number of parameters to __do_curl_to_controller " $@ >> $HTTPLOG
+        echo "-Expected: <operation> <url> [<body>]" >> $HTTPLOG
+        echo "-Returning response 000" >> $HTTPLOG
+        echo "000"
+        return 1
+    fi
+    if [ $# -eq 2 ]; then
+        json='{"input":{"near-rt-ric-url":"'$2'"}}'
+    else
+        # Escape quotes in the body
+        body=$(echo "$3" | sed 's/"/\\"/g')
+        json='{"input":{"near-rt-ric-url":"'$2'","body":"'"$body"'"}}'
+    fi
+    echo "$json" > .sndc.payload.json
+    echo "  FILE: $json"  >> $HTTPLOG
+    curlString="curl -sw %{http_code} -X POST http://$SDNC_USER:$SDNC_PWD@localhost:$SDNC_EXTERNAL_PORT$SDNC_API_URL$1 -H accept:application/json -H Content-Type:application/json --data-binary @.sndc.payload.json"
+    echo "  CMD: "$curlString >> $HTTPLOG
+    res=$($curlString)
+    retcode=$?
+    echo "  RESP: "$res >> $HTTPLOG
+    if [ $retcode -ne 0 ]; then
+        echo "  RETCODE: "$retcode >> $HTTPLOG
+        echo "000"
+        return 1
+    fi
+
+       status=${res:${#res}-3}
+
+    if [ $status -ne 200 ]; then
+        echo "000"
+        return 1
+    fi
+    body=${res:0:${#res}-3}
+    echo "$body" > .sdnc-reply.json
+    res=$(python ../common/extract_sdnc_reply.py .sdnc-reply.json)
+    echo "  EXTRACED BODY+CODE: "$res >> $HTTPLOG
+    echo "$res"
+    return 0
+}
+
+# Controller API Test function: getA1Policy (return ids only)
+# arg: <response-code> (OSC <ric-id> <policy-type-id> [ <policy-id> [<policy-id>]* ]) | ( STD <ric-id> [ <policy-id> [<policy-id>]* ] )
+# (Function for test scripts)
+controller_api_get_A1_policy_ids() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    paramError=1
+    if [ $# -gt 3 ] && [ $2 == "OSC" ]; then
+        url="http://$3:$RIC_SIM_INTERNAL_PORT/a1-p/policytypes/$4/policies"
+               paramError=0
+    elif [ $# -gt 2 ] && [ $2 == "STD" ]; then
+        url="http://$3:$RIC_SIM_INTERNAL_PORT/A1-P/v1/policies"
+        paramError=0
+       fi
+
+    if [ $paramError -ne 0 ]; then
+               __print_err "<response-code> (OSC <ric-id> <policy-type-id> [ <policy-id> [<policy-id>]* ]) | ( STD <ric-id> [ <policy-id> [<policy-id>]* ] )" $@
+               return 1
+       fi
+
+    res=$(__do_curl_to_controller getA1Policy "$url")
+    retcode=$?
+    status=${res:${#res}-3}
+
+    if [ $? -ne 0 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status "(likely remote server error)"$ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+    body=${res:0:${#res}-3}
+
+       targetJson="["
+    start=4
+    if [ $2 == "OSC" ]; then
+        start=5
+    fi
+    for pid in ${@:$start} ; do
+        if [ "$targetJson" != "[" ]; then
+            targetJson=$targetJson","
+        fi
+        targetJson=$targetJson"\"$pid\""
+    done
+    targetJson=$targetJson"]"
+
+       echo " TARGET JSON: $targetJson" >> $HTTPLOG
+
+       res=$(python ../common/compare_json.py "$targetJson" "$body")
+
+       if [ $res -ne 0 ]; then
+               echo -e $RED" FAIL, returned body not correct"$ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+
+# Controller API Test function: getA1PolicyType
+# arg: <response-code> OSC <ric-id> <policy-type-id> [<policy-type-file>]
+# (Function for test scripts)
+controller_api_get_A1_policy_type() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    paramError=1
+    if [ $# -gt 3 ] && [ $2 == "OSC" ]; then
+        url="http://$3:$RIC_SIM_INTERNAL_PORT/a1-p/policytypes/$4"
+               paramError=0
+       fi
+
+    if [ $paramError -ne 0 ]; then
+               __print_err "<response-code> OSC <ric-id> <policy-type-id> [<policy-type-file>]" $@
+               return 1
+       fi
+
+    res=$(__do_curl_to_controller getA1PolicyType "$url")
+    retcode=$?
+    status=${res:${#res}-3}
+
+    if [ $? -ne 0 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status "(likely remote server error)"$ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+    body=${res:0:${#res}-3}
+
+       if [ $# -eq 5 ]; then
+
+               body=${res:0:${#res}-3}
+
+               targetJson=$(< $5)
+               echo " TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python ../common/compare_json.py "$targetJson" "$body")
+
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# Controller API Test function: deleteA1Policy
+# arg: <response-code> (STD <ric-id> <policy-id>) | (OSC <ric-id> <policy-type-id> <policy-id>)
+# (Function for test scripts)
+controller_api_delete_A1_policy() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    paramError=1
+    if [ $# -eq 5 ] && [ $2 == "OSC" ]; then
+        url="http://$3:$RIC_SIM_INTERNAL_PORT/a1-p/policytypes/$4/policies/$5"
+               paramError=0
+    elif [ $# -eq 4 ] && [ $2 == "STD" ]; then
+        url="http://$3:$RIC_SIM_INTERNAL_PORT/A1-P/v1/policies/$4"
+        paramError=0
+       fi
+
+    if [ $paramError -ne 0 ]; then
+               __print_err "<response-code> (STD <ric-id> <policy-id>) | (OSC <ric-id> <policy-type-id> <policy-id>)" $@
+               return 1
+       fi
+
+    res=$(__do_curl_to_controller deleteA1Policy "$url")
+    retcode=$?
+    status=${res:${#res}-3}
+
+    if [ $? -ne 0 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status "(likely remote server error)"$ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# Controller API Test function: putA1Policy
+# arg: <response-code> (STD <ric-id> <policy-id> <template-file> ) | (OSC <ric-id> <policy-type-id> <policy-id> <template-file>)
+# (Function for test scripts)
+controller_api_put_A1_policy() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    paramError=1
+    if [ $# -eq 6 ] && [ $2 == "OSC" ]; then
+        url="http://$3:$RIC_SIM_INTERNAL_PORT/a1-p/policytypes/$4/policies/$5"
+        body=$(sed 's/XXX/'${5}'/g' $6)
+
+               paramError=0
+    elif [ $# -eq 5 ] && [ $2 == "STD" ]; then
+        url="http://$3:$RIC_SIM_INTERNAL_PORT/A1-P/v1/policies/$4"
+        body=$(sed 's/XXX/'${4}'/g' $5)
+        paramError=0
+       fi
+
+    if [ $paramError -ne 0 ]; then
+               __print_err "<response-code> (STD <ric-id> <policy-id>) | (OSC <ric-id> <policy-type-id> <policy-id>)" $@
+               return 1
+       fi
+
+    res=$(__do_curl_to_controller putA1Policy "$url" "$body")
+    retcode=$?
+    status=${res:${#res}-3}
+
+    if [ $? -ne 0 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status "(likely remote server error)"$ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+
+# Controller API Test function: getA1PolicyStatus
+# arg: <response-code> (STD <ric-id> <policy-id> <enforce-status> [<reason>]) | (OSC <ric-id> <policy-type-id> <policy-id> <instance-status> <has-been-deleted>)
+# (Function for test scripts)
+controller_api_get_A1_policy_status() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+    targetJson=""
+    paramError=1
+    if [ $# -ge 5 ] && [ $2 == "OSC" ]; then
+        url="http://$3:$RIC_SIM_INTERNAL_PORT/a1-p/policytypes/$4/policies/$5/status"
+        if [ $# -gt 5 ]; then
+            targetJson="{\"instance_status\":\"$6\""
+            targetJson=$targetJson",\"has_been_deleted\":\"$7\""
+            targetJson=$targetJson",\"created_at\":\"????\"}"
+        fi
+               paramError=0
+    elif [ $# -ge 4 ] && [ $2 == "STD" ]; then
+        url="http://$3:$RIC_SIM_INTERNAL_PORT/A1-P/v1/policies/$4/status"
+        if [ $# -gt 4 ]; then
+            targetJson="{\"enforceStatus\":\"$5\""
+            if [ $# -eq 6 ]; then
+                targetJson=$targetJson",\"reason\":\"$6\""
+            fi
+            targetJson=$targetJson"}"
+        fi
+        paramError=0
+       fi
+
+    if [ $paramError -ne 0 ]; then
+               __print_err "<response-code> (STD <ric-id> <policy-id> <enforce-status> [<reason>]) | (OSC <ric-id> <policy-type-id> <policy-id> <instance-status> <has-been-deleted>)" $@
+               return 1
+       fi
+
+    res=$(__do_curl_to_controller getA1PolicyStatus "$url")
+    retcode=$?
+    status=${res:${#res}-3}
+
+    if [ $? -ne 0 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status "(likely remote server error)"$ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               return 1
+       fi
+
+       if [ ! -z "$targetJson" ]; then
+
+               body=${res:0:${#res}-3}
+               echo " TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python ../common/compare_json.py "$targetJson" "$body")
+
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       return 1
+               fi
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
\ No newline at end of file
diff --git a/near-rt-ric-simulator/common/count_json_elements.py b/near-rt-ric-simulator/common/count_json_elements.py
new file mode 100644 (file)
index 0000000..936e3f8
--- /dev/null
@@ -0,0 +1,35 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+import os
+import json
+import sys
+
+# Print the length of json array, -1 will be printed in any problem is encountered
+
+try:
+    with open(sys.argv[1]) as json_file:
+        jsonarray = json.load(json_file)
+
+        if isinstance(jsonarray, list):
+            print(len(jsonarray))
+        else:
+            print(-1)
+
+except Exception as e:
+    print(-1)
+sys.exit()
\ No newline at end of file
diff --git a/near-rt-ric-simulator/common/create_rics_json.py b/near-rt-ric-simulator/common/create_rics_json.py
new file mode 100644 (file)
index 0000000..d6a095b
--- /dev/null
@@ -0,0 +1,63 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+import os
+import json
+import sys
+import re
+
+
+
+#Create a ric info json, example input: ricsim_g1_1:kista_ricsim_g1_1,stockholm_ricsim_g1_1:1,2,4 ricsim_g1_2:kista_ricsim_g1_2,stockholm_ricsim_g1_2:2
+#Format of string <ric-id>:<comma-separated-list-of-me's>:<comma-separated-list-of-policy-type-ids>
+#To indicate that no types exist, use 'NOTYPE'. Ex. ricsim_g1_1:kista_ricsim_g1_1,stockholm_ricsim_g1_1:NOTYPE
+#To indicate that special STD zero length name type, use 'EMPTYTYPE'. Ex. ricsim_g1_1:kista_ricsim_g1_1,stockholm_ricsim_g1_1:EMPTYTYPE
+#Save in indicated file
+
+try:
+    file_name = sys.argv[1]
+    ric_string = sys.argv[2]
+    ric_string=ric_string.strip()
+    ric_string = re.sub(' +',' ',ric_string)
+    ric_arr=[]
+    rics=ric_string.split(' ')
+    for i in range(len(rics)):
+        ricDict={}
+        items=rics[i].split(':')
+        ricDict['ricName']=items[0]
+        ricDict['managedElementIds']=items[1].split(',')
+        if (items[2] == "EMPTYTYPE"):
+            empty_arr=[]
+            empty_arr.append("")
+            ricDict['policyTypes']=empty_arr
+        elif (items[2] == "NOTYPE"):
+            empty_arr=[]
+            ricDict['policyTypes']=empty_arr
+        else:
+            ricDict['policyTypes']=items[2].split(',')
+        ricDict['state']=items[3]
+        ric_arr.append(ricDict)
+
+    with open(file_name, 'w') as f:
+        json.dump(ric_arr, f)
+
+    print(0)
+
+except Exception as e:
+    print(str(e))
+    print(1)
+sys.exit()
\ No newline at end of file
diff --git a/near-rt-ric-simulator/common/do_curl_function.sh b/near-rt-ric-simulator/common/do_curl_function.sh
new file mode 100755 (executable)
index 0000000..e1d890d
--- /dev/null
@@ -0,0 +1,84 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+
+
+# Function to execute curl towards a container (or process) and compare + print result
+# Intended use is for basic test scripts where testing is done with curl and the returned response and payload need to be checked.
+# args: GET|PUT|POST|DELETE <url> <target-response-code> [<json-file>]
+# All calls made to 'localhost:'<port>.
+# Expects env PORT set to intended port number
+# Expects env RESULT to contain the target response body.
+#   RESULT="*" means that returned payload is not checked, may container any text
+#   RESULT="<text>" menans that the returned payload has to match the <text> exactly
+#   RESULT="json:<returned-payload>" means that the returned json payload is compared with the expected result (order of json keys and index is irrelevant)
+# Env BODY contains the response body after the call
+# Any error will stop script execution
+# How to use in a test script:  source this file into your bash test script to the make the function available.
+
+do_curl() {
+    echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    if [ $# -lt 3 ]; then
+        echo "Need 3 or more parameters, <http-operation> <url> <response-code> [file]: "$@
+        echo "Exting test script....."
+        exit 1
+    fi
+    curlstr="curl -X "$1" -sw %{http_code} localhost:$PORT$2 -H accept:*/*"
+    if [ $# -gt 3 ]; then
+        curlstr=$curlstr" -H Content-Type:application/json --data-binary @"$4
+    fi
+    echo "  CMD:"$curlstr
+    res=$($curlstr)
+    status=${res:${#res}-3}
+    body=${res:0:${#res}-3}
+    export body
+    if [ $status -ne $3 ]; then
+        echo "  Error status:"$status" Expected status: "$3
+        echo "  Body: "$body
+        echo "Exting 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}}
+            #Find dir of the common dir
+            DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+            res=$(python ${DIR}/compare_json.py "$result" "$body")
+            if [ $res -eq 0 ]; then
+                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 "  Body as expected"
+            else
+                echo "  Expected body: "$RESULT
+                echo "Exiting....."
+                exit 1
+            fi
+        fi
+    fi
+}
\ No newline at end of file
diff --git a/near-rt-ric-simulator/common/extract_sdnc_reply.py b/near-rt-ric-simulator/common/extract_sdnc_reply.py
new file mode 100644 (file)
index 0000000..cb80e5e
--- /dev/null
@@ -0,0 +1,41 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+import os
+import json
+import sys
+
+# Extract the response code and optional response message body from and SDNC A1 Controller API reply
+
+try:
+    with open(sys.argv[1]) as json_file:
+        reply = json.load(json_file)
+
+        output=reply['output']
+        status=str(output['http-status'])
+        while(len(status) < 3):
+            status="0"+status
+        resp=status
+        if ( 'body' in output.keys()):
+            body=str(output['body'])
+            bodyJson=json.loads(body)
+            resp=str(json.dumps(bodyJson))+str(status)
+        print(resp)
+
+except Exception as e:
+    print("000")
+sys.exit()
\ No newline at end of file
diff --git a/near-rt-ric-simulator/common/ricsimulator_api_functions.sh b/near-rt-ric-simulator/common/ricsimulator_api_functions.sh
new file mode 100644 (file)
index 0000000..049e43d
--- /dev/null
@@ -0,0 +1,203 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+
+### Admin API functions for the RIC simulator
+
+
+# Excute a curl cmd towards a ricsimulator and check the response code.
+# args: <expected-response-code> <curl-cmd-string> [<file>]
+__execute_curl_to_sim() {
+       echo ${FUNCNAME[1]} "line: "${BASH_LINENO[1]} >> $HTTPLOG
+       echo " CMD: $2" >> $HTTPLOG
+       if [ $# -eq 3 ]; then
+               echo " FILE: $(<$3)"  >> $HTTPLOG
+       fi
+       res="$($2)"
+       echo " RESP: $res" >> $HTTPLOG
+       retcode=$?
+    if [ $retcode -ne 0 ]; then
+               echo " RETCODE: "$retcode
+        echo -e $RED"  ERROR - fatal error when executing curl."$ERED
+        return 1
+    fi
+    status=${res:${#res}-3}
+    if [ $status -eq $1 ]; then
+        echo -e $GREEN" OK"$EGREEN
+        return 0
+    fi
+    echo -e $RED"  ERROR - expected http response: "$1" but got http response: "$status $ERED
+    return 1
+}
+
+# Tests if a variable value in the ricsimulator is equal to a target value and and optional timeout.
+# Arg: <ric-id> <variable-name> <target-value> - This test set pass or fail depending on if the variable is
+# equal to the target or not.
+# Arg: <ric-id> <variable-name> <target-value> <timeout-in-sec>  - This test waits up to the timeout seconds
+# before setting pass or fail depending on if the variable value becomes equal to the target
+# value or not.
+# (Function for test scripts)
+sim_equal() {
+
+       if [ $# -eq 3 ] || [ $# -eq 4 ]; then
+               app=$1
+               port=$(__find_sim_port $app)
+               __var_test $app "$LOCALHOST$port/counter/" $2 "=" $3 $4
+               return 0
+       else
+               ((RES_CONF_FAIL++))
+               __print_err "needs three or four args: <ric-id> <sim-param> <target-value> [ timeout ]"
+               return 1
+       fi
+}
+
+# Print a variable value from the RIC sim.
+# args: <ric-id> <variable-name>
+# (Function for test scripts)
+sim_print() {
+
+       if [ $# != 2 ]; then
+               ((RES_CONF_FAIL++))
+       __print_err "need two args, <ric-id> <sim-param>" $@
+               exit 1
+       fi
+       app=$1
+       port=$(__find_sim_port $app)
+       echo -e $BOLD"INFO(${BASH_LINENO[0]}): $app, $2 = $(__do_curl $LOCALHOST$port/counter/$2)"$EBOLD
+}
+
+# Simulator API: Put a policy type in a ric
+# args: <response-code> <ric-id> <policy-type-id> <policy-type-file>
+# (Function for test scripts)
+sim_put_policy_type() {
+       echo -e $BOLD"CONF(${BASH_LINENO[0]}): "${FUNCNAME[0]} $@ $EBOLD
+       if [ $# -ne 4 ]; then
+               ((RES_CONF_FAIL++))
+               __print_err "<response-code> <ric-id> <policy-type-id> <policy-type-file>" $@
+               return 1
+       fi
+       app=$2
+       res=$(__find_sim_port $app)
+
+    curlString="curl -X PUT -sw %{http_code} $LOCALHOST"$res"/policytype?id="$3" -H Content-Type:application/json --data-binary @"$4
+
+       __execute_curl_to_sim $1 "$curlString" $4
+       return $?
+}
+
+# DSimulator API: Delete a policy type in a ric
+# <response-code> <ric-id> <policy-type-id>
+# (Function for test scripts)
+sim_delete_policy_type() {
+       echo -e $BOLD"CONF(${BASH_LINENO[0]}): "${FUNCNAME[0]} $@ $EBOLD
+       if [ $# -ne 3 ]; then
+               ((RES_CONF_FAIL++))
+               __print_err "<response-code> <ric-id> <policy_type_id>" $@
+               return 1
+       fi
+       app=$2
+       res=$(__find_sim_port $app)
+
+    curlString="curl -X DELETE -sw %{http_code} $LOCALHOST"$res"/policytype?id="$3
+
+    __execute_curl_to_sim $1 "$curlString"
+       return $?
+}
+
+# Simulator API: Delete instances (and status), for one ric
+# <response-code> <ric-id>
+# (Function for test scripts)
+sim_post_delete_instances() {
+       echo -e $BOLD"CONF(${BASH_LINENO[0]}): "${FUNCNAME[0]} $@ $EBOLD
+       if [ $# -ne 2 ]; then
+               ((RES_CONF_FAIL++))
+               __print_err "<response-code> <ric-id>" $@
+               return 1
+       fi
+       app=$2
+       res=$(__find_sim_port $app)
+
+    curlString="curl -X POST -sw %{http_code} $LOCALHOST"$res"/deleteinstances"
+
+    __execute_curl_to_sim $1 "$curlString"
+       return $?
+}
+
+# Simulator API: Delete all (instances/types/statuses/settings), for one ric
+# <response-code> <ric-id>
+# (Function for test scripts)
+sim_post_delete_all() {
+       echo -e $BOLD"CONF(${BASH_LINENO[0]}): "${FUNCNAME[0]} $@ $EBOLD
+       if [ $# -ne 3 ]; then
+               ((RES_CONF_FAIL++))
+               __print_err "<response-code> <numericic-id>" $@
+               return 1
+       fi
+       app=$2
+       res=$(__find_sim_port $app)
+
+    curlString="curl -X POST -sw %{http_code} $LOCALHOST"$res"/deleteall"
+
+    __execute_curl_to_sim $1 "$curlString"
+       return $?
+}
+
+# Simulator API: Set (or reset) response code for next A1 message, for one ric
+# <response-code> <ric-id> [<forced_response_code>]
+# (Function for test scripts)
+sim_post_forcedresponse() {
+       echo -e $BOLD"CONF(${BASH_LINENO[0]}): "${FUNCNAME[0]} $@ $EBOLD
+       if [ $# -ne 3 ]; then
+               ((RES_CONF_FAIL++))
+               __print_err "<response-code> <ric-id> <forced_response_code>" $@
+               return 1
+       fi
+       app=$2
+       res=$(__find_sim_port $app)
+
+    curlString="curl -X POST -sw %{http_code} $LOCALHOST"$res"/forceresponse"
+       if [ $# -eq 3 ]; then
+               curlString=$curlString"?code="$3
+       fi
+
+    __execute_curl_to_sim $1 "$curlString"
+       return $?
+}
+
+# Simulator API: Set (or reset) A1 response delay, for one ric
+# <response-code> <ric-id> [<delay-in-seconds>]
+# (Function for test scripts)
+sim_post_forcedelay() {
+       echo -e $BOLD"CONF(${BASH_LINENO[0]}): "${FUNCNAME[0]} $@ $EBOLD
+       if [ $# -ne 3 ]; then
+               ((RES_CONF_FAIL++))
+               __print_err "<response-code> <ric-id> [<delay-in-seconds>]" $@
+               return 1
+       fi
+       app=$2
+       res=$(__find_sim_port $app)
+
+    curlString="curl -X POST -sw %{http_code} $LOCALHOST$res/delay"
+       if [ $# -eq 3 ]; then
+               curlString=$curlString"?delay="$3
+       fi
+
+    __execute_curl_to_sim $1 "$curlString"
+       return $?
+}
\ No newline at end of file
index 82afa16..3bda601 100755 (executable)
-#!/usr/bin/env bash
+#!/bin/bash
 
-# Set the images for the Policy Agent app to use for the auto tests. Do not add the image tag.
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  You may obtain a copy of the License at
 #
-# Local Policy Agent image and tag, shall point to locally built image (non-nexus path)
-export POLICY_AGENT_LOCAL_IMAGE=o-ran-sc/nonrtric-policy-agent
-# Remote image
-export POLICY_AGENT_REMOTE_IMAGE=nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-policy-agent
-# SDNC A1 Adapter remote image
-export SDNC_A1_ADAPTER_IMAGE=nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-a1-controller:1.7.4
-# Dashboard remote image
-export DASHBOARD_IMAGE=nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-dashboard:1.0.1
-
-# Common env var for auto-test.
-
-POLICY_AGENT_PORT=8081
-POLICY_AGENT_LOGPATH="/var/log/policy-agent/application.log"  #Path the application log in the Policy Agent container
-DOCKER_SIM_NWNAME="nonrtric-docker-net"                       #Name of docker private network
-CONSUL_HOST="consul-server"                                   #Host name of consul
-CONSUL_PORT=8500                                              #Port number of consul
-CONFIG_BINDING_SERVICE="config-binding-service"               #Host name of CBS
-PA_APP_BASE="policy-agent"                                    #Base name for Policy Agent container
+#       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=================================================
+#
+
+# Set up the image and tags for the test. Do not add the image tag to the image names.
+
+# NOTE: A env var for each container is created by the test script.
+# This var will point to the local or remote var depending on how
+# the test script is started. The name format is <container-name>_IMAGE, ie with 'LOCAL' or 'REMOTE'.
+
+# Local Policy Agent image and tag
+POLICY_AGENT_LOCAL_IMAGE="o-ran-sc/nonrtric-policy-agent"
+POLICY_AGENT_LOCAL_IMAGE_TAG="1.0.0-SNAPSHOT"
+# Remote Policy Agent image and tag
+POLICY_AGENT_REMOTE_IMAGE="nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-policy-agent"
+POLICY_AGENT_REMOTE_IMAGE_TAG="1.0.0"
+
+
+# Control Panel local image and tag
+CONTROL_PANEL_LOCAL_IMAGE="o-ran-sc/nonrtric-controlpanel"
+CONTROL_PANEL_LOCAL_IMAGE_TAG="1.0.0-SNAPSHOT"
+# Control Panel remote image and tag
+CONTROL_PANEL_REMOTE_IMAGE="nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-controlpanel"
+CONTROL_PANEL_REMOTE_IMAGE_TAG="1.0.0"
+
+
+# SDNC A1 Controller local image and tag
+SDNC_A1_CONTROLLER_LOCAL_IMAGE="o-ran-sc/nonrtric-a1-controller"
+SDNC_A1_CONTROLLER_LOCAL_IMAGE_TAG="1.0.0-SNAPSHOT"
+# SDNC A1 Controller remote image and tag
+SDNC_A1_CONTROLLER_REMOTE_IMAGE="nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-a1-controller"
+SDNC_A1_CONTROLLER_REMOTE_IMAGE_TAG="1.7.4"
+
+
+#SDNC DN remote image and tag
+SDNC_DB_REMOTE_IMAGE="mysql/mysql-server"
+SDNC_DB_REMOTE_IMAGE_TAG="5.6"
+#No local image for DB, remote image always used
+
+
+# Near RT RIC Simulator local image and tag
+RIC_SIM_LOCAL_IMAGE="nexus3.o-ran-sc.org:10004/o-ran-sc/a1-simulator"
+RIC_SIM_LOCAL_IMAGE_TAG="latest"
+# Near RT RIC Simulator remote image and tag
+RIC_SIM_REMOTE_IMAGE="nexus3.o-ran-sc.org:10004/o-ran-sc/a1-simulator"
+RIC_SIM_REMOTE_IMAGE_TAG="1.0.1"
+
+
+#Consul remote image and tag
+CONSUL_REMOTE_IMAGE="consul"
+CONSUL_REMOTE_IMAGE_TAG="1.7.2"
+#No local image for Consul, remote image always used
+
+
+#CBS remote image and tag
+CBS_REMOTE_IMAGE="nexus3.onap.org:10001/onap/org.onap.dcaegen2.platform.configbinding.app-app"
+CBS_REMOTE_IMAGE="onap/org.onap.dcaegen2.platform.configbinding.app-app"
+CBS_REMOTE_IMAGE_TAG="2.3.0"
+#No local image for CBS, remote image always used
+
+
+#MR stub image and tag
+MRSTUB_LOCAL_IMAGE="mrstub"
+MRSTUB_LOCAL_IMAGE_TAG="latest"
+#No remote image for MR stub, local image always used
+
+#Callback receiver image and tag
+CR_LOCAL_IMAGE="callback-receiver"
+CR_LOCAL_IMAGE_TAG="latest"
+#No remote image for CR, local image always used
+
+# Common env var for auto-test. Vars used by docker-compose need to be exported
+export DOCKER_SIM_NWNAME="nonrtric-docker-net"                  # Name of docker private network
+
+export POLICY_AGENT_EXTERNAL_PORT=8081                          # Policy Agent container external port (host -> container)
+export POLICY_AGENT_INTERNAL_PORT=8081                          # Policy Agent container internal port (container -> container)
+export POLICY_AGENT_APP_NAME="policy-agent"                     # Name for Policy Agent container
+POLICY_AGENT_LOGPATH="/var/log/policy-agent/application.log"    # Path the application log in the Policy Agent container
+
+export MR_EXTERNAL_PORT=3905                                    # MR stub container external port (host -> container)
+export MR_INTERNAL_PORT=3905                                    # MR stub container internal port (container -> container)
+export MR_APP_NAME="message-router"                             # Name for the MR
+
+export CR_EXTERNAL_PORT=8090                                    # Callback receiver container external port (host -> container)
+export CR_INTERNAL_PORT=8090                                    # Callback receiver container internal port (container -> container)
+export CR_APP_NAME="callback-receiver"                          # Name for the Callback receiver
+
+export CONSUL_HOST="consul-server"                              # Host name of consul
+export CONSUL_EXTERNAL_PORT=8500                                # Consul container external port (host -> container)
+export CONSUL_INTERNAL_PORT=8500                                # Consul container internal port (container -> container)
+export CONSUL_APP_NAME="polman-consul"                          # Name for consul container
+
+export CBS_APP_NAME="polman-cbs"                                # Name for CBS container
+export CBS_EXTERNAL_PORT=10000                                  # CBS container external port (host -> container)
+export CBS_INTERNAL_PORT=10000                                  # CBS container internal port (container -> container)
+export CONFIG_BINDING_SERVICE="config-binding-service"          # Host name of CBS
+
+export RIC_SIM_BASE="g"                                         # Base name of the RIC Simulator container, shall be the group code
+                                                                # Note, a prefix is added to each container name by the .env file in the 'ric' dir
+RIC_SIM_PREFIX="ricsim"                                         # Prefix added to ric container name, added in the .env file in the 'ric' dir
+export RIC_SIM_INTERNAL_PORT=8085                               # RIC Simulator container internal port (container -> container).
+                                                                # (externl ports allocated by docker)
+
+export SDNC_APP_NAME="a1-controller"                            # Name of the SNDC A1 Controller container
+export SDNC_EXTERNAL_PORT=8282                                  # SNDC A1 Controller container external port (host -> container)
+export SDNC_INTERNAL_PORT=8181                                  # SNDC A1 Controller container internal port (container -> container)
+export SDNC_DB_APP_NAME="sdnc-db"                               # Name of the SDNC DB container
+SDNC_USER="admin"                                               # SDNC username
+SDNC_PWD="Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U"          # SNDC PWD
+SDNC_API_URL="/restconf/operations/A1-ADAPTER-API:"             # Base url path for SNDC API
+
+export CONTROL_PANEL_APP_NAME="control-panel"                   # Name of the Control Panel container
+export CONTROL_PANEL_EXTERNAL_PORT=8080                         # Control Panel container external port (host -> container)
+export CONTROL_PANEL_INTERNAL_PORT=8080                         # Control Panel container external port (host -> container)
+CONTROL_PANEL_LOGPATH="/logs/nonrtric-controlpanel.log"         # Path the application log in the Control Panel container
+
+RESTBASE="http://localhost:"$POLICY_AGENT_EXTERNAL_PORT         # Base url to the R-APP interface
+DMAAPBASE="http://localhost:"$MR_EXTERNAL_PORT                  # Base url to the Dmaap adapter
+ADAPTER=$RESTBASE                                               # Adapter holds the address the agent R-APP interface (REST OR DMAAP)
+                                                                # The values of this var is swiched between the two base url when needed
\ No newline at end of file
index b4ceb0d..088995f 100755 (executable)
@@ -1,36 +1,59 @@
-#!/usr/bin/env bash
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
 
+# This is a script that contains all the functions needed for auto test
+# Arg: local|remote|remote-remove [auto-clean]
+
+#Formatting for 'echo' cmd
+BOLD="\033[1m"
+EBOLD="\033[0m"
+RED="\033[31m\033[1m"
+ERED="\033[0m"
+GREEN="\033[32m\033[1m"
+EGREEN="\033[0m"
+YELLOW="\033[33m\033[1m"
+EYELLOW="\033[0m"
+
+# Just resetting any previous echo formatting...
+echo -ne $EBOLD$ERED$EGREEN
+
+# source test environment variables
 . ../common/test_env.sh
 
-echo "Test case started as: ${BASH_SOURCE[$i+1]} "$1 $2 $3
-echo "Numbers of ric simulator started" $2
+echo "Test case started as: ${BASH_SOURCE[$i+1]} "$@
 
-# This is a script that contains all the functions needed for auto test
-# Arg: local | remote (1, 2, 3, 4....)
+#Vars for A1 interface version and container count
+G1_A1_VERSION=""
+G2_A1_VERSION=""
+G3_A1_VERSION=""
+G1_COUNT=0
+G2_COUNT=0
+G3_COUNT=0
 
-STARTED_POLICY_AGENT="" #Policy Agent app names added to this var to keep track of started container in the script
-START_ARG=$1
-IMAGE_TAG="1.0.0-SNAPSHOT"
-IMAGE_TAG_REMOTE="latest"
-RIC_NUMBER=$2
-SDNC=$3
+#Localhost constant
+LOCALHOST="http://localhost:"
 
-if [ $# -lt 1 ] || [ $# -gt 4 ]; then
-       echo "Expected arg: local  | remote  and numbers of the rics and SDNC "
-       exit 1
-elif [ $1 == "local" ]; then
-       if [ -z $POLICY_AGENT_LOCAL_IMAGE ]; then
-               echo "POLICY_AGENT_LOCAL_IMAGE not set in test_env"
-               exit 1
-       fi
-       POLICY_AGENT_IMAGE=$POLICY_AGENT_LOCAL_IMAGE":"$IMAGE_TAG
-elif [ $1 == "remote" ]; then
-    if [ -z $POLICY_AGENT_REMOTE_IMAGE ]; then
-        echo "POLICY_AGENT_REMOTE_IMAGE not set in test_env"
-        exit 1
-    fi
-    POLICY_AGENT_IMAGE=$POLICY_AGENT_REMOTE_IMAGE":"$IMAGE_TAG_REMOTE
-fi
+# Make curl retries for http response codes set in this env var, space separated list of codes
+AGENT_RETRY_CODES=""
+
+# Var to hold 'auto' in case containers shall be stopped when test case ends
+AUTO_CLEAN=""
 
 # Set a description string for the test case
 if [ -z "$TC_ONELINE_DESCR" ]; then
@@ -38,18 +61,36 @@ if [ -z "$TC_ONELINE_DESCR" ]; then
        echo "No test case description found, TC_ONELINE_DESCR should be set on in the test script , using "$TC_ONELINE_DESCR
 fi
 
-ATC=$(basename "${BASH_SOURCE[$i+1]}" .sh)
+# Counter for test suites
+if [ -f .tmp_tcsuite_ctr ]; then
+       tmpval=$(< .tmp_tcsuite_ctr)
+       ((tmpval++))
+       echo $tmpval > .tmp_tcsuite_ctr
+fi
 
+# Create a test case id, ATC (Auto Test Case), from the name of the test case script.
+# FTC1.sh -> ATC == FTC1
+ATC=$(basename "${BASH_SOURCE[$i+1]}" .sh)
 
 # Create the logs dir if not already created in the current dir
 if [ ! -d "logs" ]; then
     mkdir logs
 fi
-
 TESTLOGS=$PWD/logs
 
+# Create a http message log for this testcase
+HTTPLOG=$PWD"/.httplog_"$ATC".txt"
+echo "" > $HTTPLOG
+
+# Create a log dir for the test case
 mkdir -p $TESTLOGS/$ATC
 
+# Clear the log dir for the test case
+rm $TESTLOGS/$ATC/*.log &> /dev/null
+rm $TESTLOGS/$ATC/*.txt &> /dev/null
+rm $TESTLOGS/$ATC/*.json &> /dev/null
+
+# Log all output from the test case to a TC log
 TCLOG=$TESTLOGS/$ATC/TC.log
 exec &>  >(tee ${TCLOG})
 
@@ -57,6 +98,9 @@ exec &>  >(tee ${TCLOG})
 RES_TEST=0
 RES_PASS=0
 RES_FAIL=0
+RES_CONF_FAIL=0
+
+#Var for measuring execution time
 TCTEST_START=$SECONDS
 
 echo "-------------------------------------------------------------------------------------------------"
@@ -67,318 +111,1037 @@ echo "-- Description: "$TC_ONELINE_DESCR
 echo "-------------------------------------------------------------------------------------------------"
 echo "-----------------------------------      Test case setup      -----------------------------------"
 
+echo -e $BOLD"Checking configured image setting for this test case"$EBOLD
+
+#Temp var to check for image variable name errors
+IMAGE_ERR=0
+#Create a file with image info for later printing as a table
+image_list_file=".image-list"
+echo -e " Container\tImage\ttag" > $image_list_file
+
+# Check if image env var is set and if so export the env var with image to use (used by docker compose files)
+# arg: <image name> <script start-arg> <target-variable-name> <image-variable-name> <image-tag-variable-name>
+__check_image_var() {
+       if [ $# -ne 5 ]; then
+               echo "Expected arg: <image name> <script start-arg> <target-variable-name> <image-variable-name> <image-tag-variable-name>"
+               ((IMAGE_ERR++))
+               return
+       fi
+       tmp=${1}"\t"
+       #Create var from the input var names
+       image="${!4}"
+       tag="${!5}"
+
+       if [ -z $image ]; then
+               echo -e $RED"\$"$4" not set in test_env"$ERED
+               ((IMAGE_ERR++))
+               echo ""
+               tmp=$tmp"<no-image>\t"
+       else
+               tmp=$tmp$image"\t"
+       fi
+       if [ -z $tag ]; then
+               echo -e $RED"\$"$5" not set in test_env"$ERED
+               ((IMAGE_ERR++))
+               echo ""
+               tmp=$tmp"<no-tag>\t"
+       else
+               tmp=$tmp$tag
+       fi
+       echo -e "$tmp" >> $image_list_file
+       #Export the env var
+       export "${3}"=$image":"$tag
+
+       #echo " Configured image for ${1} (script start arg=${2}): "$image":"$tag
+}
+
+# Check that image env setting are available
+echo ""
+if [ $# -lt 1 ] || [ $# -gt 2 ]; then
+       echo "Expected arg: local|remote|remote-remove [auto-clean]"
+       exit 1
+elif [ $1 == "local" ]; then
+
+       #Local agent image
+       __check_image_var " Policy Agent" $1 "POLICY_AGENT_IMAGE" "POLICY_AGENT_LOCAL_IMAGE" "POLICY_AGENT_LOCAL_IMAGE_TAG"
+
+       #Local Control Panel image
+       __check_image_var " Control Panel" $1 "CONTROL_PANEL_IMAGE" "CONTROL_PANEL_LOCAL_IMAGE" "CONTROL_PANEL_LOCAL_IMAGE_TAG"
+
+       #Local SNDC image
+       __check_image_var " SDNC A1 Controller" $1 "SDNC_A1_CONTROLLER_IMAGE" "SDNC_A1_CONTROLLER_LOCAL_IMAGE" "SDNC_A1_CONTROLLER_LOCAL_IMAGE_TAG"
+
+       #Local ric sim image
+       __check_image_var " RIC Simulator" $1 "RIC_SIM_IMAGE" "RIC_SIM_LOCAL_IMAGE" "RIC_SIM_LOCAL_IMAGE_TAG"
+
+elif [ $1 == "remote" ] || [ $1 == "remote-remove" ]; then
+
+       #Remote agent image
+       __check_image_var " Policy Agent" $1 "POLICY_AGENT_IMAGE" "POLICY_AGENT_REMOTE_IMAGE" "POLICY_AGENT_REMOTE_IMAGE_TAG"
+
+       #Remote Control Panel image
+       __check_image_var " Control Panel" $1 "CONTROL_PANEL_IMAGE" "CONTROL_PANEL_REMOTE_IMAGE" "CONTROL_PANEL_REMOTE_IMAGE_TAG"
+
+       #Remote SDNC image
+       __check_image_var " SDNC A1 Controller" $1 "SDNC_A1_CONTROLLER_IMAGE" "SDNC_A1_CONTROLLER_REMOTE_IMAGE" "SDNC_A1_CONTROLLER_REMOTE_IMAGE_TAG"
+
+       #Remote ric sim image
+       __check_image_var " RIC Simulator" $1 "RIC_SIM_IMAGE" "RIC_SIM_REMOTE_IMAGE" "RIC_SIM_REMOTE_IMAGE_TAG"
+
+else
+       echo "Expected arg: local|remote|remote-remove [auto-clean]"
+       exit 1
+fi
+
+if [ $# -eq 2 ]; then
+       if [ $2 == "auto-clean" ]; then
+               echo "Stting automatic cleaning of container when test case ends"
+               AUTO_CLEAN="auto"
+       else
+               echo "Expected arg: local|remote|remote-remove [auto-clean]"
+               exit 1
+       fi
+fi
+
+# These images are not built as part of this project official images, just check that env vars are set correctly
+__check_image_var " Message Router" $1 "MRSTUB_IMAGE" "MRSTUB_LOCAL_IMAGE" "MRSTUB_LOCAL_IMAGE_TAG"
+__check_image_var " Callback Receiver" $1 "CR_IMAGE" "CR_LOCAL_IMAGE" "CR_LOCAL_IMAGE_TAG"
+__check_image_var " Consul" $1 "CONSUL_IMAGE" "CONSUL_REMOTE_IMAGE" "CONSUL_REMOTE_IMAGE_TAG"
+__check_image_var " CBS" $1 "CBS_IMAGE" "CBS_REMOTE_IMAGE" "CBS_REMOTE_IMAGE_TAG"
+__check_image_var " SDNC DB" $1 "SDNC_DB_IMAGE" "SDNC_DB_REMOTE_IMAGE" "SDNC_DB_REMOTE_IMAGE_TAG"
+
+#Errors in image setting - exit
+if [ $IMAGE_ERR -ne 0 ]; then
+       exit 1
+fi
+
+#Print a tables of the image settings
+echo -e $BOLD"Images configured for start arg: "$1 $EBOLD
+column -t -s $'\t' $image_list_file
+
+echo ""
+
 
+#Set the SIM_GROUP var
+echo -e $BOLD"Setting var to main dir of all container/simulator scripts"$EBOLD
 if [ -z "$SIM_GROUP" ]; then
-               SIM_GROUP=$PWD/../simulator-group
-               if [ ! -d  $SIM_GROUP ]; then
-                       echo "Trying to set env var SIM_GROUP to dir 'simulator-group' in the integration repo, but failed."
-                       echo "Please set the SIM_GROUP manually in the test_env.sh"
-                       exit 1
-               else
-                       echo "SIM_GROUP auto set to: " $SIM_GROUP
-               fi
+       SIM_GROUP=$PWD/../simulator-group
+       if [ ! -d  $SIM_GROUP ]; then
+               echo "Trying to set env var SIM_GROUP to dir 'simulator-group' in the nontrtric repo, but failed."
+               echo -e $RED"Please set the SIM_GROUP manually in the test_env.sh"$ERED
+               exit 1
+       else
+               echo " SIM_GROUP auto set to: " $SIM_GROUP
+       fi
 elif [ $SIM_GROUP = *simulator_group ]; then
-                       echo "Env var SIM_GROUP does not seem to point to dir 'simulator-group' in the integration repo, check test_env.sh"
-                       exit 1
+       echo -e $RED"Env var SIM_GROUP does not seem to point to dir 'simulator-group' in the repo, check common/test_env.sh"$ERED
+       exit 1
+else
+       echo " SIM_GROUP env var already set to: " $SIM_GROUP
 fi
 
 echo ""
 
-if [ $1 !=  "manual-container" ] && [ $1 !=  "manual-app" ]; then
-       #echo -e "Policy Agent image tag set to: \033[1m" $IMAGE_TAG"\033[0m"
-       echo "Configured image for Policy Agent app(s) (${1}): "$POLICY_AGENT_IMAGE
-       tmp_im=$(docker images ${POLICY_AGENT_IMAGE} | grep -v REPOSITORY)
+#Temp var to check for image pull errors
+IMAGE_ERR=0
+
+#Function to check if image exist and stop+remove the container+pull new images as needed
+#args <script-start-arg> <descriptive-image-name> <container-base-name> <image-with-tag>
+__check_and_pull_image() {
+
+       echo -e " Checking $BOLD$2$EBOLD container(s) with basename: $BOLD$3$EBOLD using image: $BOLD$4$EBOLD"
+       format_string="\"{{.Repository}}\\t{{.Tag}}\\t{{.CreatedSince}}\\t{{.Size}}\""
+       tmp_im=$(docker images --format $format_string ${4})
 
        if [ $1 == "local" ]; then
                if [ -z "$tmp_im" ]; then
-                       echo "Local image (non nexus) "$POLICY_AGENT_IMAGE" does not exist in local registry, need to be built"
-                       exit 1
+                       echo -e "  "$2" (local image): \033[1m"$4"\033[0m $RED does not exist in local registry, need to be built (or manually pulled)"$ERED
+                       ((IMAGE_ERR++))
+                       return 1
                else
-                       echo -e "Policy Agent local image: \033[1m"$tmp_im"\033[0m"
-                       echo "If the Policy Agent image seem outdated, rebuild the image and run the test again."
+                       echo -e "  "$2" (local image): \033[1m"$4"\033[0m "$GREEN"OK"$EGREEN
                fi
-       elif [ $1 == "remote" ]; then
-           if [ -z "$tmp_im" ]; then
-                       echo "Pulling Policy Agent image from nexus: "$POLICY_AGENT_IMAGE
-                       docker pull $POLICY_AGENT_IMAGE  > /dev/null
-                       tmp_im=$(docker images ${POLICY_AGENT_IMAGE} | grep -v REPOSITORY)
+       elif [ $1 == "remote" ] || [ $1 == "remote-remove" ]; then
+               if [ $1 == "remote-remove" ]; then
+                       echo -ne "  Attempt to stop and remove container(s), if running - \033[0K\r"
+                       tmp="$(docker ps -aq --filter name=${3})"
+                       if [ $? -eq 0 ] && [ ! -z "$tmp" ]; then
+                               docker stop $tmp &> /dev/null
+                               if [ $? -ne 0 ]; then
+                                       ((IMAGE_ERR++))
+                                       echo ""
+                                       echo -e $RED"  Container(s) could not be stopped - try manual stopping the container(s)"$ERED
+                                       return 1
+                               fi
+                       fi
+                       echo -ne "  Attempt to stop and remove container(s), if running - "$GREEN"stopped"$EGREEN"\033[0K\r"
+                       tmp="$(docker ps -aq --filter name=${3})" &> /dev/null
+                       if [ $? -eq 0 ] && [ ! -z "$tmp" ]; then
+                               docker rm $tmp &> /dev/null
+                               if [ $? -ne 0 ]; then
+                                       ((IMAGE_ERR++))
+                                       echo ""
+                                       echo -e $RED"  Container(s) could not be removed - try manual removal of the container(s)"$ERED
+                                       return 1
+                               fi
+                       fi
+                       echo -e "  Attempt to stop and remove container(s), if running - "$GREEN"stopped removed"$EGREEN
+                       echo -ne "  Removing image - \033[0K\r"
+                       tmp="$(docker images -q ${4})" &> /dev/null
+                       if [ $? -eq 0 ] && [ ! -z "$tmp" ]; then
+                               docker rmi $4 &> /dev/null
+                               if [ $? -ne 0 ]; then
+                                       ((IMAGE_ERR++))
+                                       echo ""
+                                       echo -e $RED"  Image could not be removed - try manual removal of the image"$ERED
+                                       return 1
+                               fi
+                               echo -e "  Removing image - "$GREEN"removed"$EGREEN
+                       else
+                               echo -e "  Removing image - "$GREEN"image not in repository"$EGREEN
+                       fi
+                       tmp_im=""
+               fi
+               if [ -z "$tmp_im" ]; then
+                       echo -ne "  Pulling image\033[0K\r"
+                       docker pull $4   > /dev/null
+                       tmp_im=$(docker images ${4} | grep -v REPOSITORY)
                        if [ -z "$tmp_im" ]; then
-                               echo "Image could not be pulled"
-                               exit 1
+                               echo ""
+                               echo -e "  Pulling image -$RED could not be pulled"$ERED
+                               ((IMAGE_ERR++))
+                               return 1
                        fi
-                       echo -e "Policy Agent image: \033[1m"$tmp_im"\033[0m"
+                       echo -e "  Pulling image -$GREEN Pulled $EGREEN"
                else
-                       echo -e "Policy Agent image: \033[1m"$tmp_im"\033[0m"
-                       echo "!! If the Policy Agent image seem outdated, consider removing it from your docker registry and run the test again."
+                       echo -e "  Pulling image -$GREEN OK $EGREEN(exists in local repository)"
                fi
        fi
+       return 0
+}
+
+
+echo -e $BOLD"Pulling configured images, if needed"$EBOLD
+
+app="Policy Agent";             __check_and_pull_image $1 "$app" $POLICY_AGENT_APP_NAME $POLICY_AGENT_IMAGE
+app="Non-RT RIC Control Panel"; __check_and_pull_image $1 "$app" $CONTROL_PANEL_APP_NAME $CONTROL_PANEL_IMAGE
+app="SDNC A1 Controller";       __check_and_pull_image $1 "$app" $SDNC_APP_NAME $SDNC_A1_CONTROLLER_IMAGE
+app="Near-RT RIC Simulator";    __check_and_pull_image $1 "$app" $RIC_SIM_PREFIX"_"$RIC_SIM_BASE $RIC_SIM_IMAGE
+
+app="Consul";                   __check_and_pull_image $1 "$app" $CONSUL_APP_NAME $CONSUL_IMAGE
+app="CBS";                      __check_and_pull_image $1 "$app" $CBS_APP_NAME $CBS_IMAGE
+app="SDNC DB";                  __check_and_pull_image $1 "$app" $SDNC_APP_NAME $SDNC_DB_IMAGE
+
+# MR stub image not checked, will be built by this script - only local image
+# CR stub image not checked, will be built by this script - only local image
+
+
+#Errors in image setting - exit
+if [ $IMAGE_ERR -ne 0 ]; then
+       echo ""
+       echo "#################################################################################################"
+       echo -e $RED"One or more images could not be pulled or containers using the images could not be stopped/removed"$ERED
+       echo "#################################################################################################"
+       echo ""
+       exit 1
 fi
 
 echo ""
 
-echo "Building images for the simulators"
-if [ -z "$SIM_DIR" ]; then
-               SIM_DIR=$(find . -type d -path "*a1-interface/near-rt-ric-simulator/scripts*" 2>/dev/null -print -quit)
-               if [ ! -d  $SIM_DIR ]; then
-                       echo "Trying to set env var SIM_DIR to dir 'a1-interface/near-rt-ric-simulator/scripts' in the sim repo, but failed."
-                       echo "It might be that you did not download the repository of the Near-rt-ric simulator.In that case, run the command:"
-                       echo "git clone 'https://gerrit.o-ran-sc.org/oransc/sim/a1-interface'"
-                       echo "Otherwise, please set the SIM_DIR manually in the test_env.sh"
-                       exit 1
-               else
-                       echo "SIM_DIR auto set to: " $SIM_DIR
-               fi
+echo -e $BOLD"Building images needed for test"$EBOLD
+
+curdir=$PWD
+cd $curdir
+cd ../mrstub
+echo " Building mrstub image: mrstub:latest"
+docker build -t mrstub . &> /dev/null
+if [ $? -eq 0 ]; then
+       echo -e  $GREEN" Build Ok"$EGREEN
+else
+       echo -e $RED" Build Failed"$ERED
+       ((RES_CONF_FAIL++))
 fi
-cd $SIM_DIR
-docker build -t ric-simulator:latest . &> /dev/null
 cd $curdir
 
-echo ""
+cd ../cr
+echo " Building Callback Receiver image: callback-receiver:latest"
+docker build -t callback-receiver . &> /dev/null
+if [ $? -eq 0 ]; then
+       echo -e  $GREEN" Build Ok"$EGREEN
+else
+       echo -e $RED" Build Failed"$ERED
+       ((RES_CONF_FAIL++))
+fi
+cd $curdir
 
-echo "Local registry images for simulators:"
-echo "Consul:             " $(docker images | grep consul)
-echo "CBS:                " $(docker images | grep platform.configbinding.app)
-echo "RIC:                " $(docker images | grep ric-simulator)
 echo ""
 
+# Create a table of the images used in the script
+echo -e $BOLD"Local docker registry images used in the this test script"$EBOLD
 
-__consul_config() {
+docker_tmp_file=.docker-images-table
+format_string="{{.Repository}}\\t{{.Tag}}\\t{{.CreatedSince}}\\t{{.Size}}"
+echo -e " Application\tRepository\tTag\tCreated Since\tSize" > $docker_tmp_file
+echo -e " Policy Agent\t$(docker images --format $format_string $POLICY_AGENT_IMAGE)" >>   $docker_tmp_file
+echo -e " Control Panel\t$(docker images --format $format_string $CONTROL_PANEL_IMAGE)" >>   $docker_tmp_file
+echo -e " SDNC A1 Controller\t$(docker images --format $format_string $SDNC_A1_CONTROLLER_IMAGE)" >>   $docker_tmp_file
+echo -e " RIC Simulator\t$(docker images --format $format_string $RIC_SIM_IMAGE)" >>   $docker_tmp_file
+echo -e " Message Router\t$(docker images --format $format_string $MRSTUB_IMAGE)" >>   $docker_tmp_file
+echo -e " Callback Receiver\t$(docker images --format $format_string $CR_IMAGE)" >>   $docker_tmp_file
+echo -e " Consul\t$(docker images --format $format_string $CONSUL_IMAGE)" >>   $docker_tmp_file
+echo -e " CBS\t$(docker images --format $format_string $CBS_IMAGE)" >>   $docker_tmp_file
+echo -e " SDNC DB\t$(docker images --format $format_string $SDNC_DB_IMAGE)" >>   $docker_tmp_file
 
-       appname=$PA_APP_BASE
+column -t -s $'\t' $docker_tmp_file
 
-       echo "Configuring consul for " $appname " from " $1
-       curl -s http://127.0.0.1:${CONSUL_PORT}/v1/kv/${appname}?dc=dc1 -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -H 'X-Requested-With: XMLHttpRequest' --data-binary "@"$1 >/dev/null
-}
+echo ""
 
+echo -e $BOLD"======================================================="$EBOLD
+echo -e $BOLD"== Common test setup completed -  test script begins =="$EBOLD
+echo -e $BOLD"======================================================="$EBOLD
+echo ""
 
-consul_config_app() {
+# Function to print the test result, shall be the last cmd in a test script
+# args: -
+# (Function for test scripts)
+print_result() {
+
+       TCTEST_END=$SECONDS
+       duration=$((TCTEST_END-TCTEST_START))
+
+       echo "-------------------------------------------------------------------------------------------------"
+       echo "-------------------------------------     Test case: "$ATC
+       echo "-------------------------------------     Ended:     "$(date)
+       echo "-------------------------------------------------------------------------------------------------"
+       echo "-- Description: "$TC_ONELINE_DESCR
+       echo "-- Execution time: " $duration " seconds"
+       echo "-------------------------------------------------------------------------------------------------"
+       echo "-------------------------------------     RESULTS"
+       echo ""
 
-    __consul_config $1
 
-}
+       total=$((RES_PASS+RES_FAIL))
+       if [ $RES_TEST -eq 0 ]; then
+               echo -e "\033[1mNo tests seem to have been executed. Check the script....\033[0m"
+               echo -e "\033[31m\033[1m ___  ___ ___ ___ ___ _____   ___ _   ___ _   _   _ ___ ___ \033[0m"
+               echo -e "\033[31m\033[1m/ __|/ __| _ \_ _| _ \_   _| | __/_\ |_ _| | | | | | _ \ __|\033[0m"
+               echo -e "\033[31m\033[1m\__ \ (__|   /| ||  _/ | |   | _/ _ \ | || |_| |_| |   / _| \033[0m"
+               echo -e "\033[31m\033[1m|___/\___|_|_\___|_|   |_|   |_/_/ \_\___|____\___/|_|_\___|\033[0m"
+       elif [ $total != $RES_TEST ]; then
+               echo -e "\033[1mTotal number of tests does not match the sum of passed and failed tests. Check the script....\033[0m"
+               echo -e "\033[31m\033[1m ___  ___ ___ ___ ___ _____   ___ _   ___ _   _   _ ___ ___ \033[0m"
+               echo -e "\033[31m\033[1m/ __|/ __| _ \_ _| _ \_   _| | __/_\ |_ _| | | | | | _ \ __|\033[0m"
+               echo -e "\033[31m\033[1m\__ \ (__|   /| ||  _/ | |   | _/ _ \ | || |_| |_| |   / _| \033[0m"
+               echo -e "\033[31m\033[1m|___/\___|_|_\___|_|   |_|   |_/_/ \_\___|____\___/|_|_\___|\033[0m"
+       elif [ $RES_CONF_FAIL -ne 0 ]; then
+               echo -e "\033[1mOne or more configure regest has failed. Check the script log....\033[0m"
+               echo -e "\033[31m\033[1m ___  ___ ___ ___ ___ _____   ___ _   ___ _   _   _ ___ ___ \033[0m"
+               echo -e "\033[31m\033[1m/ __|/ __| _ \_ _| _ \_   _| | __/_\ |_ _| | | | | | _ \ __|\033[0m"
+               echo -e "\033[31m\033[1m\__ \ (__|   /| ||  _/ | |   | _/ _ \ | || |_| |_| |   / _| \033[0m"
+               echo -e "\033[31m\033[1m|___/\___|_|_\___|_|   |_|   |_/_/ \_\___|____\___/|_|_\___|\033[0m"
+       elif [ $RES_PASS = $RES_TEST ]; then
+               echo -e "All tests \033[32m\033[1mPASS\033[0m"
+               echo -e "\033[32m\033[1m  ___  _   ___ ___ \033[0m"
+               echo -e "\033[32m\033[1m | _ \/_\ / __/ __| \033[0m"
+               echo -e "\033[32m\033[1m |  _/ _ \\__ \__ \\ \033[0m"
+               echo -e "\033[32m\033[1m |_|/_/ \_\___/___/ \033[0m"
+               echo ""
+
+               # Update test suite counter
+               if [ -f .tmp_tcsuite_pass_ctr ]; then
+                       tmpval=$(< .tmp_tcsuite_pass_ctr)
+                       ((tmpval++))
+                       echo $tmpval > .tmp_tcsuite_pass_ctr
+               fi
+               if [ -f .tmp_tcsuite_pass ]; then
+                       echo " - "$ATC " -- "$TC_ONELINE_DESCR"  Execution time: "$duration" seconds" >> .tmp_tcsuite_pass
+               fi
+       else
+               echo -e "One or more tests with status  \033[31m\033[1mFAIL\033[0m "
+               echo -e "\033[31m\033[1m  ___ _   ___ _    \033[0m"
+               echo -e "\033[31m\033[1m | __/_\ |_ _| |   \033[0m"
+               echo -e "\033[31m\033[1m | _/ _ \ | || |__ \033[0m"
+               echo -e "\033[31m\033[1m |_/_/ \_\___|____|\033[0m"
+               echo ""
+               # Update test suite counter
+               if [ -f .tmp_tcsuite_fail_ctr ]; then
+                       tmpval=$(< .tmp_tcsuite_fail_ctr)
+                       ((tmpval++))
+                       echo $tmpval > .tmp_tcsuite_fail_ctr
+               fi
+               if [ -f .tmp_tcsuite_fail ]; then
+                       echo " - "$ATC " -- "$TC_ONELINE_DESCR"  Execution time: "$duration" seconds" >> .tmp_tcsuite_fail
+               fi
+       fi
 
+       echo "++++ Number of tests:          "$RES_TEST
+       echo "++++ Number of passed tests:   "$RES_PASS
+       echo "++++ Number of failed tests:   "$RES_FAIL
+       echo ""
+       echo "++++ Number of failed configs: "$RES_CONF_FAIL
+       echo "-------------------------------------     Test case complete    ---------------------------------"
+       echo "-------------------------------------------------------------------------------------------------"
+       echo ""
+}
 
+#####################################################################
+###### Functions for start, configuring, stoping, cleaning etc ######
+#####################################################################
 
-start_ric_simulator() {
 
-  DOCKER_SIM_NWNAME="nonrtric-docker-net"
-  echo "Creating docker network $DOCKER_SIM_NWNAME, if needed"
-  docker network ls| grep $DOCKER_SIM_NWNAME > /dev/null || docker network create $DOCKER_SIM_NWNAME
+# Stop and remove all containers
+# args: -
+# (Function for test scripts)
+clean_containers() {
 
-  echo "start ric simulator"
-  curdir=$PWD
-  cd $SIM_GROUP
-  cd ric/
+       echo -e $BOLD"Stopping and removing all running containers, by container name"$EBOLD
+
+       CONTAINTER_NAMES=("Policy Agent           " $POLICY_AGENT_APP_NAME\
+                                         "Non-RT RIC Simulator(s)" $RIC_SIM_PREFIX\
+                                         "Message Router         " $MR_APP_NAME\
+                                         "Callback Receiver      " $CR_APP_NAME\
+                                         "Control Panel          " $CONTROL_PANEL_APP_NAME\
+                                         "SDNC A1 Controller     " $SDNC_APP_NAME\
+                                         "SDNC DB                " $SDNC_DB_APP_NAME\
+                                         "CBS                    " $CBS_APP_NAME\
+                                         "Consul                 " $CONSUL_APP_NAME)
+
+       nw=0 # Calc max width of container name, to make a nice table
+       for (( i=1; i<${#CONTAINTER_NAMES[@]} ; i+=2 )) ; do
+               if [ ${#CONTAINTER_NAMES[i]} -gt $nw ]; then
+                       nw=${#CONTAINTER_NAMES[i]}
+               fi
+       done
 
-  docker-compose up --scale ric-simulator=$RIC_NUMBER -d
+       for (( i=0; i<${#CONTAINTER_NAMES[@]} ; i+=2 )) ; do
+               APP="${CONTAINTER_NAMES[i]}"
+               CONTR="${CONTAINTER_NAMES[i+1]}"
+               for((w=${#CONTR}; w<$nw; w=w+1)); do
+                       CONTR="$CONTR "
+               done
+               echo -ne " $APP: $CONTR - ${GREEN}stopping${EGREEN}\033[0K\r"
+               docker stop $(docker ps -qa --filter name=${CONTR}) &> /dev/null
+               echo -ne " $APP: $CONTR - ${GREEN}stopped${EGREEN}\033[0K\r"
+               docker rm $(docker ps -qa --filter name=${CONTR}) &> /dev/null
+               echo -e  " $APP: $CONTR - ${GREEN}stopped removed${EGREEN}"
+       done
 
-  cd $curdir
        echo ""
 }
 
-start_dashboard() {
-
-  DOCKER_SIM_NWNAME="nonrtric-docker-net"
-  echo "Creating docker network $DOCKER_SIM_NWNAME, if needed"
-  docker network ls| grep $DOCKER_SIM_NWNAME > /dev/null || docker network create $DOCKER_SIM_NWNAME
-
-  echo "start Control Panel"
-  curdir=$PWD
-  cd $SIM_GROUP
-  cd dashboard/
+# Function stop and remove all container in the end of the test script, if the arg 'auto-clean' is given at test script start
+# args: -
+# (Function for test scripts)
+auto_clean_containers() {
+       echo
+       if [ "$AUTO_CLEAN" == "auto" ]; then
+               echo -e $BOLD"Initiating automatic cleaning of started containers"$EBOLD
+               clean_containers
+       fi
+}
 
-  docker-compose up -d
+# Function to sleep a test case for a numner of seconds. Prints the optional text args as info
+# args: <sleep-time-in-sec> [any-text-in-quoteds-to-printed]
+# (Function for test scripts)
+sleep_wait() {
 
-  cd $curdir
+       echo -e $BOLD"INFO(${BASH_LINENO[0]}): "${FUNCNAME[0]}"," $@ $EBOLD
+       if [ $# -lt 1 ]; then
+               ((RES_CONF_FAIL++))
+               __print_err "need at least one arg, <sleep-time-in-sec> [any-text-to-printed]" $@
+               exit 1
+       fi
+       #echo "---- Sleep for " $1 " seconds ---- "$2
+       start=$SECONDS
+       duration=$((SECONDS-start))
+       while [ $duration -lt $1 ]; do
+               echo -ne "  Slept for ${duration} seconds\033[0K\r"
+               sleep 1
+               duration=$((SECONDS-start))
+       done
+       echo -ne "  Slept for ${duration} seconds\033[0K\r"
        echo ""
 }
 
-start_sdnc() {
-
-  if [ $SDNC == "sdnc" ]; then
-    DOCKER_SIM_NWNAME="nonrtric-docker-net"
-    echo "Creating docker network $DOCKER_SIM_NWNAME, if needed"
-    docker network ls| grep $DOCKER_SIM_NWNAME > /dev/null || docker network create $DOCKER_SIM_NWNAME
+# Print error info for the call in the parent script (test case). Arg: <error-message-to-print>
+# Not to be called from the test script itself.
+__print_err() {
+    echo -e $RED ${FUNCNAME[1]} " "$1" " ${BASH_SOURCE[2]} " line" ${BASH_LINENO[1]} $ERED
+       if [ $# -gt 1 ]; then
+               echo -e $RED" Got: "${FUNCNAME[1]} ${@:2} $ERED
+       fi
+}
 
-    echo "start sdnc"
-    curdir=$PWD
-    cd $SIM_GROUP
-    cd sdnc/
 
-    docker-compose up -d a1-controller
+# Helper function to get a the port of a specific ric simulatpor
+# args: <ric-id>
+# (Not for test scripts)
+__find_sim_port() {
+    name=$1" " #Space appended to prevent matching 10 if 1 is desired....
+    cmdstr="docker ps --filter name=${name} --format \"{{.Names}} {{.Ports}}\" | grep '${name}' | sed s/0.0.0.0:// | cut -f 2 -d ' ' | cut -f 1 -d '-'"
+       res=$(eval $cmdstr)
+       if [[ "$res" =~ ^[0-9]+$ ]]; then
+               echo $res
+       else
+               echo "0"
+    fi
+}
 
-    cd $curdir
-         echo ""
+# Function to create the docker network for the test
+# Not to be called from the test script itself.
+__create_docker_network() {
+       tmp=$(docker network ls -q --filter name=$DOCKER_SIM_NWNAME)
+       if [ $? -ne 0 ]; then
+               echo -e $RED" Could not check if docker network $DOCKER_SIM_NWNAME exists"$ERED
+               return 1
+       fi
+       if [ -z tmp ]; then
+               echo -e "Creating docker network:$BOLD $DOCKER_SIM_NWNAME $EBOLD"
+               docker network create $DOCKER_SIM_NWNAME
+               if [ $? -ne 0 ]; then
+                       echo -e $RED" Could not create docker network $DOCKER_SIM_NWNAME"$ERED
+                       return 1
+               fi
+       else
+               echo -e " Docker network $DOCKER_SIM_NWNAME already exists$GREEN OK $EGREEN"
        fi
 }
 
-prepare_consul_config() {
-  echo "prepare consul config"
-  curdir=$PWD
-  cd $SIM_GROUP
-  cd ric/
+# Check if container is started by calling url on localhost using a port, expects response code 2XX
+# args: <container-name> <port> <url>
+# Not to be called from the test script itself.
+__check_container_start() {
+       if [ $# -ne 3 ]; then
+               ((RES_CONF_FAIL++))
+               __print_err "need 3 args, <container-name> <port> <url>" $@
+               return 1
+       fi
+       echo -ne " Container $BOLD$1$EBOLD starting\033[0K\r"
+       appname=$1
+       localport=$2
+       url=$3
+       pa_started=false
+       for i in {1..10}; do
+               if [ $(docker inspect --format '{{ .State.Running }}' $appname) ]; then
+                               echo -e " Container $BOLD$1$EBOLD$GREEN running$EGREEN on$BOLD image $(docker inspect --format '{{ .Config.Image }}' ${appname}) $EBOLD"
+                               pa_started=true
+                               break
+                       else
+                               sleep $i
+               fi
+       done
+       if ! [ $pa_started  ]; then
+               ((RES_CONF_FAIL++))
+               echo ""
+               echo -e $RED" Container $BOLD${appname}$EBOLD could not be started"$ERED
+               return 1
+       fi
+       if [ $localport -eq 0 ]; then
+               while [ $localport -eq 0 ]; do
+                       echo -ne " Waiting for container ${appname} to publish its ports...\033[0K\r"
+                       localport=$(__find_sim_port $appname)
+                       sleep 1
+                       echo -ne " Waiting for container ${appname} to publish its ports...retrying....\033[0K\r"
+               done
+               echo -ne " Waiting for container ${appname} to publish its ports...retrying....$GREEN OK $EGREEN"
+               echo ""
+       fi
+
+       pa_st=false
+       echo -ne " Waiting for container ${appname} service status...\033[0K\r"
+       for i in {1..20}; do
+               result="$(__do_curl $LOCALHOST${localport}${url})"
+               if [ $? -eq 0 ]; then
+                       if [ ${#result} -gt 15 ]; then
+                               #If response is too long, truncate
+                               result="...response text too long, omitted"
+                       fi
+                       echo -ne " Waiting for container $BOLD${appname}$EBOLD service status, result: $result\033[0K\r"
+                       echo -ne " Container $BOLD${appname}$EBOLD$GREEN is alive$EGREEN, responds to service status:$GREEN $result $EGREEN"
+                       pa_st=true
+                       break
+               else
+                       #echo " Retrying in $i seconds"
+                       echo -ne " Waiting for container ${appname} service status...retrying in $i seconds\033[0K\r"
+                       sleep $i
+               fi
+       done
 
-  python3 cleanConsul.py
-  python3 prepareConsul.py
+       if [ "$pa_st" = "false"  ]; then
+               ((RES_CONF_FAIL++))
+               echo -e $RED" Container ${appname} did not respond to service status"$ERED
+               return 0
+       fi
 
-  cd $curdir
        echo ""
+       return 0
+}
 
 
-}
+# Function to start a container and wait until it responds on the given port and url.
+#args: <docker-compose-dir> NODOCKERARGS|<docker-compose-arg> <app-name> <port-number> <alive-url> [<app-name> <port-number> <alive-url>]*
+__start_container() {
 
+       variableArgCount=$(($#-2))
+       if [ $# -lt 5 ] && [ [ $(($variableArgCount%3)) -ne 0 ]; then
+               ((RES_CONF_FAIL++))
+       __print_err "need 5 or more args,  <docker-compose-dir> NODOCKERARGS|<docker-compose-arg> <app-name> <port-number> <alive-url> [<app-name> <port-number> <alive-url>]*" $@
+               exit 1
+       fi
 
-# Start all simulators in the simulator group
-start_simulators() {
+       __create_docker_network
 
-       echo "Starting all simulators"
        curdir=$PWD
        cd $SIM_GROUP
+       cd $1
+
+       if [ "$2" == "NODOCKERARGS" ]; then
+               docker-compose up -d &> /dev/null
+       else
+               docker-compose up -d $2 &> /dev/null
+       fi
+
+       shift; shift;
+       cntr=0
+       while [ $cntr -lt $variableArgCount ]; do
+               app=$1; shift;
+               port=$1; shift;
+               url=$1; shift;
+               let cntr=cntr+3
+
+               __check_container_start "$app" "$port" "$url"
+       done
 
-       $SIM_GROUP/simulators-start.sh
        cd $curdir
        echo ""
+       return 0
 }
 
+####################
+### Consul functions
+####################
 
+# Function to load config from a file into consul for the Policy Agent
+# arg: <json-config-file>
+# (Function for test scripts)
+consul_config_app() {
+
+       echo -e $BOLD"Configuring Consul"$EBOLD
+
+       if [ $# -ne 1 ]; then
+               ((RES_CONF_FAIL++))
+       __print_err "need one arg,  <json-config-file>" $@
+               exit 1
+       fi
+
+       echo " Loading config for "$POLICY_AGENT_APP_NAME" from "$1
+
+       curl -s $LOCALHOST${CONSUL_EXTERNAL_PORT}/v1/kv/${POLICY_AGENT_APP_NAME}?dc=dc1 -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -H 'X-Requested-With: XMLHttpRequest' --data-binary "@"$1 >/dev/null
+       if [ $? -ne 0 ]; then
+               echo -e $RED" FAIL - json config could not be loaded to consul" $ERED
+               ((RES_CONF_FAIL++))
+               return 1
+       fi
+       body="$(__do_curl $LOCALHOST$CBS_EXTERNAL_PORT/service_component_all/$POLICY_AGENT_APP_NAME)"
+
+       if [ $? -ne 0 ]; then
+               echo -e $RED" FAIL - json config could not be loaded from consul/cbs, contents cannot be checked." $ERED
+               ((RES_CONF_FAIL++))
+               return 1
+       else
+               targetJson=$(< $1)
+               targetJson="{\"config\":"$targetJson"}"
+               echo "TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python ../common/compare_json.py "$targetJson" "$body")
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL - policy json config read from consul/cbs is not equal to the intended json config...." $ERED
+                       ((RES_CONF_FAIL++))
+                       return 1
+               else
+                       echo -e $GREEN" Config loaded ok to consul"$EGREEN
+               fi
+       fi
 
-clean_containers() {
-       echo "Stopping all containers, Policy Agent app(s) and simulators with name prefix 'policy-agent'"
-       docker stop $(docker ps -q --filter name=/policy-agent) &> /dev/null
-       echo "Removing all containers, Policy Agent app and simulators with name prefix 'policy-agent'"
-       docker rm $(docker ps -a -q --filter name=/policy-agent) &> /dev/null
-       echo "Stopping all containers, Policy Agent app(s) and simulators with name prefix 'ric-simulator'"
-       docker stop $(docker ps -q --filter name=ric-simulator) &> /dev/null
-       echo "Removing all containers, Policy Agent app and simulators with name prefix 'ric-simulator'"
-       docker rm $(docker ps -a -q --filter name=ric-simulator) &> /dev/null
-       echo "Removing all containers, Policy Agent app and simulators with name prefix 'dashboard'"
-       docker rm $(docker ps -a -q --filter name=dashboard) &> /dev/null
-       echo "Removing all containers, Policy Agent app and simulators with name prefix 'a1-controller'"
-       docker rm $(docker ps -a -q --filter name=a1-controller) &> /dev/null
-       echo "Removing all containers, Policy Agent app and simulators with name prefix 'sdnc_db_container'"
-       docker rm $(docker ps -a -q --filter name=sdnc_db_container) &> /dev/null
-       echo "Removing all containers, Policy Agent app and simulators with name prefix 'cbs'"
-       docker rm $(docker ps -a -q --filter name=polman_cbs) &> /dev/null
-       echo "Removing all containers, Policy Agent app and simulators with name prefix 'consul'"
-       docker rm $(docker ps -a -q --filter name=polman_consul) &> /dev/null
-       echo "Removing unused docker networks with substring 'nonrtric' in network name"
-       docker network rm $(docker network ls -q --filter name=nonrtric)
        echo ""
+
 }
 
-start_policy_agent() {
+# Function to perpare the consul configuration according to the current simulator configuration
+# args: SDNC|NOSDNC <output-file>
+# (Function for test scripts)
+prepare_consul_config() {
+       echo -e $BOLD"Prepare Consul config"$EBOLD
 
-       appname=$PA_APP_BASE
+       echo " Writing consul config for "$POLICY_AGENT_APP_NAME" to file: "$2
 
-       if [ $START_ARG == "local" ] || [ $START_ARG == "remote" ]; then
-               __start_policy_agent_image $appname
+       if [ $# != 2 ];  then
+               ((RES_CONF_FAIL++))
+       __print_err "need two args,  SDNC|NOSDNC <output-file>" $@
+               exit 1
        fi
-}
 
-__start_policy_agent_image() {
+       if [ $1 == "SDNC" ]; then
+               echo -e " Config$BOLD including SDNC$EBOLD configuration"
+       elif [ $1 == "NOSDNC" ];  then
+               echo -e " Config$BOLD excluding SDNC$EBOLD configuration"
+       else
+               ((RES_CONF_FAIL++))
+       __print_err "need two args,  SDNC|NOSDNC <output-file>" $@
+               exit 1
+       fi
 
-       appname=$1
-       localport=$POLICY_AGENT_PORT
+       config_json="\n            {"
+       if [ $1 == "SDNC" ]; then
+               config_json=$config_json"\n   \"controller\": ["
+               config_json=$config_json"\n                     {"
+               config_json=$config_json"\n                       \"name\": \"$SDNC_APP_NAME\","
+               config_json=$config_json"\n                       \"baseUrl\": \"http://$SDNC_APP_NAME:$SDNC_INTERNAL_PORT\","
+               config_json=$config_json"\n                       \"userName\": \"$SDNC_USER\","
+               config_json=$config_json"\n                       \"password\": \"$SDNC_PWD\""
+               config_json=$config_json"\n                     }"
+               config_json=$config_json"\n   ],"
+       fi
 
-       echo "Creating docker network $DOCKER_SIM_NWNAME, if needed"
 
-       docker network ls| grep $DOCKER_SIM_NWNAME > /dev/null || docker network create $DOCKER_SIM_NWNAME
+       config_json=$config_json"\n   \"streams_publishes\": {"
+       config_json=$config_json"\n                            \"dmaap_publisher\": {"
+       config_json=$config_json"\n                              \"type\": \"$MR_APP_NAME\","
+       config_json=$config_json"\n                              \"dmaap_info\": {"
+       config_json=$config_json"\n                                \"topic_url\": \"http://$MR_APP_NAME:$MR_INTERNAL_PORT/events/A1-POLICY-AGENT-WRITE\""
+       config_json=$config_json"\n                              }"
+       config_json=$config_json"\n                            }"
+       config_json=$config_json"\n   },"
+       config_json=$config_json"\n   \"streams_subscribes\": {"
+       config_json=$config_json"\n                             \"dmaap_subscriber\": {"
+       config_json=$config_json"\n                               \"type\": \"$MR_APP_NAME\","
+       config_json=$config_json"\n                               \"dmaap_info\": {"
+       config_json=$config_json"\n                                   \"topic_url\": \"http://$MR_APP_NAME:$MR_INTERNAL_PORT/events/A1-POLICY-AGENT-READ/users/policy-agent\""
+       config_json=$config_json"\n                                 }"
+       config_json=$config_json"\n                               }"
+       config_json=$config_json"\n   },"
+
+       config_json=$config_json"\n   \"ric\": ["
+
+       rics=$(docker ps | grep ricsim | awk '{print $NF}')
+
+       if [ $? -ne 0 ] || [ -z "$rics" ]; then
+               echo -e $RED" FAIL - the names of the running RIC Simulator cannot be retrieved." $ERED
+               ((RES_CONF_FAIL++))
+               return 1
+       fi
 
-       echo "Starting Policy Agent: " $appname " with ports mapped to " $localport " in docker network "$DOCKER_SIM_NWNAME
-       docker run -d -p $localport":8081" --network=$DOCKER_SIM_NWNAME -e CONSUL_HOST=$CONSUL_HOST -e CONSUL_PORT=$CONSUL_PORT -e CONFIG_BINDING_SERVICE=$CONFIG_BINDING_SERVICE -e HOSTNAME=$appname --name $appname $POLICY_AGENT_IMAGE
-       #docker run -d -p 8081:8081 --network=nonrtric-docker-net -e CONSUL_HOST=CONSUL_HOST=$CONSUL_HOST -e CONSUL_PORT=$CONSUL_PORT -e CONFIG_BINDING_SERVICE=$CONFIG_BINDING_SERVICE -e HOSTNAME=policy-agent
-       sleep 3
-       set +x
-       pa_started=false
-       for i in {1..10}; do
-               if [ $(docker inspect --format '{{ .State.Running }}' $appname) ]
-                       then
-                               echo " Image: $(docker inspect --format '{{ .Config.Image }}' ${appname})"
-                               echo "Policy Agent container ${appname} running"
-                               pa_started=true
-                               break
-                       else
-                               sleep $i
-               fi
+       cntr=0
+       for ric in $rics; do
+               if [ $cntr -gt 0 ]; then
+                       config_json=$config_json"\n          ,"
+               fi
+               config_json=$config_json"\n          {"
+               config_json=$config_json"\n            \"name\": \"$ric\","
+               config_json=$config_json"\n            \"baseUrl\": \"http://$ric:$RIC_SIM_INTERNAL_PORT\","
+               if [ $1 == "SDNC" ]; then
+                       config_json=$config_json"\n            \"controller\": \"$SDNC_APP_NAME\","
+               fi
+               config_json=$config_json"\n            \"managedElementIds\": ["
+               config_json=$config_json"\n              \"me1_$ric\","
+               config_json=$config_json"\n              \"me2_$ric\""
+               config_json=$config_json"\n            ]"
+               config_json=$config_json"\n          }"
+               let cntr=cntr+1
        done
-       if ! [ $pa_started  ]; then
-               echo "Policy Agent container ${appname} could not be started"
+
+       config_json=$config_json"\n           ]"
+       config_json=$config_json"\n}"
+
+
+       printf "$config_json">$2
+
+       echo ""
+}
+
+
+# Start Consul and CBS
+# args: -
+# (Function for test scripts)
+start_consul_cbs() {
+
+       echo -e $BOLD"Starting Consul and CBS"$EBOLD
+
+       __start_container consul_cbs NODOCKERARGS  "$CONSUL_APP_NAME" "$CONSUL_EXTERNAL_PORT" "/ui/dc1/kv" \
+                                                    "$CBS_APP_NAME" "$CBS_EXTERNAL_PORT" "/healthcheck"
+}
+
+###########################
+### RIC Simulator functions
+###########################
+
+# Start one group (ricsim_g1, ricsim_g2 or ricsim_g3) with a number of RIC Simulators using a given A interface
+# args:  ricsim_g1|ricsim_g2|ricsim_g3 <count> <interface-id>
+# (Function for test scripts)
+start_ric_simulators() {
+
+       echo -e $BOLD"Starting RIC Simulators"$EBOLD
+
+       if [ $# != 3 ]; then
+               ((RES_CONF_FAIL++))
+       __print_err "need three args,  ricsim_g1|ricsim_g2|ricsim_g3 <count> <interface-id>" $@
+               exit 1
+       fi
+       echo " $2 simulators using basename: $1 on interface: $3"
+       #Set env var for simulator count and A1 interface vesion for the given group
+       if [ $1 == "ricsim_g1" ]; then
+               G1_COUNT=$2
+               G1_A1_VERSION=$3
+       elif [ $1 == "ricsim_g2" ]; then
+               G2_COUNT=$2
+               G2_A1_VERSION=$3
+       elif [ $1 == "ricsim_g3" ]; then
+               G3_COUNT=$2
+               G3_A1_VERSION=$3
+       else
+               ((RES_CONF_FAIL++))
+       __print_err "need three args, gricsim_g1|ricsim_g2|ricsim_g3 <count> <interface-id>" $@
                exit 1
        fi
 
-       pa_st=false
-       echo "Waiting for Policy Agent ${appname} service status..."
-       for i in {1..10}; do
-               result="$(__do_curl http://127.0.0.1:${localport}/status)"
-               if [ $? -eq 0 ]; then
-                       echo "Policy Agent ${appname} responds to service status: " $result
-                       echo "Policy Agent is alive."
-                       pa_st=true
-                       break
-               else
-                       sleep $i
-               fi
+       # Create .env file to compose project, all ric container will get this prefix
+       echo "COMPOSE_PROJECT_NAME="$RIC_SIM_PREFIX > $SIM_GROUP/ric/.env
+
+       export G1_A1_VERSION
+       export G2_A1_VERSION
+       export G3_A1_VERSION
+
+       docker_args="--scale g1=$G1_COUNT --scale g2=$G2_COUNT --scale g3=$G3_COUNT"
+       app_data=""
+       cntr=1
+       while [ $cntr -le $2 ]; do
+               app=$1"_"$cntr
+               port=0
+               app_data="$app_data $app $port /"
+               let cntr=cntr+1
        done
 
-       if [ "$pa_st" = "false"  ]; then
-               echo "Policy Agent ${appname} did not respond to service status"
-               exit 1
+       __start_container ric "$docker_args" $app_data
+
+}
+
+###########################
+### Control Panel functions
+###########################
+
+# Start the Control Panel container
+# args: -
+# (Function for test scripts)
+start_control_panel() {
+
+       echo -e $BOLD"Starting Control Panel"$EBOLD
+
+       __start_container control_panel NODOCKERARGS $CONTROL_PANEL_APP_NAME $CONTROL_PANEL_EXTERNAL_PORT "/"
+
+}
+
+##################
+### SDNC functions
+##################
+
+# Start the SDNC A1 Controller
+# args: -
+# (Function for test scripts)
+start_sdnc() {
+
+       echo -e $BOLD"Starting SDNC A1 Controller"$EBOLD
+
+       __start_container sdnc NODOCKERARGS $SDNC_APP_NAME $SDNC_EXTERNAL_PORT "/apidoc/explorer"
+
+}
+
+#####################
+### MR stub functions
+#####################
+
+# Start the Message Router stub interface in the simulator group
+# args: -
+# (Function for test scripts)
+start_mr() {
+
+       echo -e $BOLD"Starting Message Router 'mrstub'"$EBOLD
+
+       __start_container mr NODOCKERARGS $MR_APP_NAME $MR_EXTERNAL_PORT "/"
+
+}
+
+################
+### CR functions
+################
+
+# Start the Callback reciver in the simulator group
+# args: -
+# (Function for test scripts)
+start_cr() {
+
+       echo -e $BOLD"Starting Callback Receiver"$EBOLD
+
+       __start_container cr NODOCKERARGS $CR_APP_NAME $CR_EXTERNAL_PORT "/"
+
+}
+
+###########################
+### Policy Agents functions
+###########################
+
+# Start the policy agwent
+# args: -
+# (Function for test scripts)
+start_policy_agent() {
+
+       echo -e $BOLD"Starting Policy Agent"$EBOLD
+
+       __start_container policy_agent NODOCKERARGS $POLICY_AGENT_APP_NAME $POLICY_AGENT_EXTERNAL_PORT "/status"
+
+}
+
+# All calls to the agent will be directed to the agent REST interface from now on
+# args: -
+# (Function for test scripts)
+use_agent_rest() {
+       echo -e $BOLD"Using agent REST interface"$EBOLD
+       export ADAPTER=$RESTBASE
+       echo ""
+}
+
+# All calls to the agent will be directed to the agent dmaap interface from now on
+# args: -
+# (Function for test scripts)
+use_agent_dmaap() {
+       echo -e $BOLD"Using agent DMAAP interface"$EBOLD
+       export ADAPTER=$DMAAPBASE
+       echo ""
+
+}
+
+# Turn on debug level tracing in the agent
+# args: -
+# (Function for test scripts)
+set_agent_debug() {
+       echo -e $BOLD"Setting agent debug"$EBOLD
+       curl $LOCALHOST$POLICY_AGENT_EXTERNAL_PORT/actuator/loggers/org.oransc.policyagent -X POST  -H 'Content-Type: application/json' -d '{"configuredLevel":"debug"}' &> /dev/null
+       if [ $? -ne 0 ]; then
+               __print_err "could not set debug mode" $@
+               return 1
        fi
+       return 0
+       echo ""
 }
 
-check_policy_agent_logs() {
+# Perform curl retries when making direct call to the agent for the specified http response codes
+# Speace separated list of http response codes
+# args: [<response-code>]*
+use_agent_retries() {
+       echo -e $BOLD"Do curl retries to the agent REST inteface for these response codes:$@"$EBOLD
+       AGENT_RETRY_CODES=$@
+       echo ""
+}
 
-               appname=$PA_APP_BASE
-               tmp=$(docker ps | grep $appname)
-               if ! [ -z "$tmp" ]; then  #Only check logs for running Policy Agent apps
-                       __check_policy_agent_log $appname
-               fi
+#################
+### Log functions
+#################
 
+# Check the agent logs for WARNINGs and ERRORs
+# args: -
+# (Function for test scripts)
+
+check_policy_agent_logs() {
+       __check_container_logs "Policy Agent" $POLICY_AGENT_APP_NAME $POLICY_AGENT_LOGPATH
 }
 
-__check_policy_agent_log() {
-       echo "Checking $1 log $POLICY_AGENT_LOGPATH for WARNINGs and ERRORs"
-       foundentries=$(docker exec -it $1 grep WARN /var/log/policy-agent/application.log | wc -l)
+check_control_panel_logs() {
+       __check_container_logs "Control Panel" $CONTROL_PANEL_APP_NAME $CONTROL_PANEL_LOGPATH
+}
+
+__check_container_logs() {
+       dispname=$1
+       appname=$2
+       logpath=$3
+       echo -e $BOLD"Checking $dispname container $appname log ($logpath) for WARNINGs and ERRORs"$EBOLD
+
+       #tmp=$(docker ps | grep $appname)
+       tmp=$(docker ps -q --filter name=$appname) #get the container id
+       if [ -z "$tmp" ]; then  #Only check logs for running Policy Agent apps
+               echo $dispname" is not running, no check made"
+               return
+       fi
+       foundentries="$(docker exec -it $tmp grep WARN $logpath | wc -l)"
        if [ $? -ne  0 ];then
-               echo "  Problem to search $1 log $POLICY_AGENT_LOGPATH"
+               echo "  Problem to search $appname log $logpath"
        else
                if [ $foundentries -eq 0 ]; then
-                       echo "  No WARN entries found in $1 log $POLICY_AGENT_LOGPATH"
+                       echo "  No WARN entries found in $appname log $logpath"
                else
-                       echo -e "  Found \033[1m"$foundentries"\033[0m WARN entries in $1 log $POLICY_AGENT_LOGPATH"
+                       echo -e "  Found \033[1m"$foundentries"\033[0m WARN entries in $appname log $logpath"
                fi
        fi
-       foundentries=$(docker exec -it $1 grep ERR $POLICY_AGENT_LOGPATH | wc -l)
+       foundentries="$(docker exec -it $tmp grep ERR $logpath | wc -l)"
        if [ $? -ne  0 ];then
-               echo "  Problem to search $1 log $POLICY_AGENT_LOGPATH"
+               echo "  Problem to search $appname log $logpath"
        else
                if [ $foundentries -eq 0 ]; then
-                       echo "  No ERR entries found in $1 log $POLICY_AGENT_LOGPATH"
+                       echo "  No ERR entries found in $appname log $logpath"
                else
-                       echo -e "  Found \033[1m"$foundentries"\033[0m ERR entries in $1 log $POLICY_AGENT_LOGPATH"
+                       echo -e $RED"  Found \033[1m"$foundentries"\033[0m"$RED" ERR entries in $appname log $logpath"$ERED
                fi
        fi
+       echo ""
 }
 
+# Store all container logs and other logs in the log dir for the script
+# Logs are stored with a prefix in case logs should be stored several times during a test
+# args: <logfile-prefix>
+# (Function for test scripts)
 store_logs() {
        if [ $# != 1 ]; then
-       __print_err "need one arg, <file-prefix>"
+               ((RES_CONF_FAIL++))
+       __print_err "need one arg, <file-prefix>" $@
                exit 1
        fi
-       echo "Storing all container logs and Policy Agent app log using prefix: "$1
+       echo -e $BOLD"Storing all container logs, Policy Agent app log and consul config using prefix: "$1
+
+       docker logs $CONSUL_APP_NAME > $TESTLOGS/$ATC/$1_consul.log 2>&1
+       docker logs $CBS_APP_NAME > $TESTLOGS/$ATC/$1_cbs.log 2>&1
+       docker logs $POLICY_AGENT_APP_NAME > $TESTLOGS/$ATC/$1_policy-agent.log 2>&1
+       docker logs $CONSUL_APP_NAME > $TESTLOGS/$ATC/$1_control-panel.log 2>&1
+       docker logs $MR_APP_NAME > $TESTLOGS/$ATC/$1_mr.log 2>&1
+       docker logs $CR_APP_NAME > $TESTLOGS/$ATC/$1_cr.log 2>&1
+       cp .httplog_${ATC}.txt $TESTLOGS/$ATC/$1_httplog_${ATC}.txt 2>&1
+
+       docker exec -it $SDNC_APP_NAME cat /opt/opendaylight/data/log/karaf.log > $TESTLOGS/$ATC/$1_karaf.log 2>&1
 
-       docker logs polman_consul > $TESTLOGS/$ATC/$1_consul.log 2>&1
-       docker logs polman_cbs > $TESTLOGS/$ATC/$1_cbs.log 2>&1
+       rics=$(docker ps -f "name=$RIC_SIM_PREFIX" --format "{{.Names}}")
+       for ric in $rics; do
+               docker logs $ric > $TESTLOGS/$ATC/$1_$ric.log 2>&1
+       done
+       body="$(__do_curl $LOCALHOST$CBS_EXTERNAL_PORT/service_component_all/$POLICY_AGENT_APP_NAME)"
+       echo "$body" > $TESTLOGS/$ATC/$1_consul_config.json 2>&1
+       echo ""
 }
 
+###############
+## Generic curl
+###############
+# Generic curl function, assumed all 200-codes are ok
+# args: <url>
+# returns: <returned response (without respose code)>  or "<no-response-from-server>" or "<not found, <http-code>>""
+# returns: The return code is 0 for ok and 1 for not ok
 __do_curl() {
-       res=$(curl -skw "%{http_code}" $1)
+       echo ${FUNCNAME[1]} "line: "${BASH_LINENO[1]} >> $HTTPLOG
+       curlString="curl -skw %{http_code} $1"
+       echo " CMD: $curlString" >> $HTTPLOG
+       res=$($curlString)
+       echo " RESP: $res" >> $HTTPLOG
        http_code="${res:${#res}-3}"
        if [ ${#res} -eq 3 ]; then
                echo "<no-response-from-server>"
                return 1
        else
-               if [ $http_code -lt 200 ] && [ $http_code -gt 299]; then
+               if [ $http_code -lt 200 ] || [ $http_code -gt 299 ]; then
                        echo "<not found, resp:${http_code}>"
                        return 1
                fi
@@ -392,3 +1155,204 @@ __do_curl() {
        fi
 }
 
+#######################################
+### Basic helper function for test cases
+#######################################
+
+# Test a simulator container variable value towards target value using an condition operator with an optional timeout.
+# Arg: <simulator-name> <host> <variable-name> <condition-operator> <target-value>  - This test is done
+# immediately and sets pass or fail depending on the result of comparing variable and target using the operator.
+# Arg: <simulator-name> <host> <variable-name> <condition-operator> <target-value> <timeout>  - This test waits up to the timeout
+# before setting pass or fail depending on the result of comparing variable and target using the operator.
+# If the <variable-name> has the 'json:' prefix, the the variable will be used as url and the <target-value> will be compared towards the length of the json array in the response.
+# Not to be called from test script.
+
+__var_test() {
+       checkjsonarraycount=0
+
+       if [ $# -eq 6 ]; then
+               if [[ $3 == "json:"* ]]; then
+                       checkjsonarraycount=1
+               fi
+
+               #echo -e "---- ${1} sim test criteria: \033[1m ${3} \033[0m ${4} ${5} within ${6} seconds ----"
+               echo -e $BOLD"TEST(${BASH_LINENO[1]}): ${1}, ${3} ${4} ${5} within ${6} seconds"
+               ((RES_TEST++))
+               start=$SECONDS
+               ctr=0
+               for (( ; ; )); do
+                       if [ $checkjsonarraycount -eq 0 ]; then
+                               result="$(__do_curl $2$3)"
+                               retcode=$?
+                               result=${result//[[:blank:]]/} #Strip blanks
+                       else
+                               path=${3:5}
+                               result="$(__do_curl $2$path)"
+                               retcode=$?
+                               echo "$result" > .tmp.curl.json
+                               result=$(python ../common/count_json_elements.py ".tmp.curl.json")
+                       fi
+                       duration=$((SECONDS-start))
+                       echo -ne " Result=${result} after ${duration} seconds\033[0K\r"
+                       let ctr=ctr+1
+                       if [ $retcode -ne 0 ]; then
+                               if [ $duration -gt $6 ]; then
+                                       ((RES_FAIL++))
+                                       #echo -e "----  \033[31m\033[1mFAIL\033[0m - Target ${3} ${4} ${5}  not reached in ${6} seconds, result = ${result} ----"
+                                       echo -e $RED" FAIL${ERED} - ${3} ${4} ${5} not reached in ${6} seconds, result = ${result}"
+                                       return
+                               fi
+                       elif [ $4 = "=" ] && [ "$result" -eq $5 ]; then
+                               ((RES_PASS++))
+                               echo -e " Result=${result} after ${duration} seconds\033[0K\r"
+                               echo -e $GREEN" PASS${EGREEN} - Result=${result} after ${duration} seconds"
+                               #echo -e "----  \033[32m\033[1mPASS\033[0m - Test criteria met in ${duration} seconds ----"
+                               return
+                       elif [ $4 = ">" ] && [ "$result" -gt $5 ]; then
+                               ((RES_PASS++))
+                               echo -e " Result=${result} after ${duration} seconds\033[0K\r"
+                               echo -e $GREEN" PASS${EGREEN} - Result=${result} after ${duration} seconds"
+                               #echo -e "----  \033[32m\033[1mPASS\033[0m - Test criteria met in ${duration} seconds, result = ${result}  ----"
+                               return
+                       elif [ $4 = "<" ] && [ "$result" -lt $5 ]; then
+                               ((RES_PASS++))
+                               echo -e " Result=${result} after ${duration} seconds\033[0K\r"
+                               echo -e $GREEN" PASS${EGREEN} - Result=${result} after ${duration} seconds"
+                               #echo -e "----  \033[32m\033[1mPASS\033[0m - Test criteria met in ${duration} seconds, result = ${result}  ----"
+                               return
+                       elif [ $4 = "contain_str" ] && [[ $result =~ $5 ]]; then
+                               ((RES_PASS++))
+                               echo -e " Result=${result} after ${duration} seconds\033[0K\r"
+                               echo -e $GREEN" PASS${EGREEN} - Result=${result} after ${duration} seconds"
+                               #echo -e "----  \033[32m\033[1mPASS\033[0m - Test criteria met in ${duration} seconds, result = ${result}  ----"
+                               return
+                       else
+                               if [ $duration -gt $6 ]; then
+                                       ((RES_FAIL++))
+                                       echo -e $RED" FAIL${ERED} - ${3} ${4} ${5} not reached in ${6} seconds, result = ${result}"
+                                       #echo -e "----  \033[31m\033[1mFAIL\033[0m - Target ${3} ${4} ${5}  not reached in ${6} seconds, result = ${result} ----"
+                                       return
+                               fi
+                       fi
+                       sleep 1
+               done
+       elif [ $# -eq 5 ]; then
+               if [[ $3 == "json:"* ]]; then
+                       checkjsonarraycount=1
+               fi
+
+               #echo -e "---- ${1} sim test criteria: \033[1m ${3} \033[0m ${4} ${5} ----"
+               echo -e $BOLD"TEST(${BASH_LINENO[1]}): ${1}, ${3} ${4} ${5}"$EBOLD
+               ((RES_TEST++))
+               if [ $checkjsonarraycount -eq 0 ]; then
+                       result="$(__do_curl $2$3)"
+                       retcode=$?
+                       result=${result//[[:blank:]]/} #Strip blanks
+               else
+                       path=${3:5}
+                       result="$(__do_curl $2$path)"
+                       retcode=$?
+                       echo "$result" > .tmp.curl.json
+                       result=$(python ../common/count_json_elements.py ".tmp.curl.json")
+               fi
+               if [ $retcode -ne 0 ]; then
+                       ((RES_FAIL++))
+                       #echo -e "----  \033[31m\033[1mFAIL\033[0m - Target ${3} ${4} ${5} not reached, result = ${result} ----"
+                       echo -e $RED" FAIL ${ERED}- ${3} ${4} ${5} not reached, result = ${result}"
+               elif [ $4 = "=" ] && [ "$result" -eq $5 ]; then
+                       ((RES_PASS++))
+                       echo -e $GREEN" PASS${EGREEN} - Result=${result}"
+                       #echo -e "----  \033[32m\033[1mPASS\033[0m - Test criteria met"
+               elif [ $4 = ">" ] && [ "$result" -gt $5 ]; then
+                       ((RES_PASS++))
+                       echo -e $GREEN" PASS${EGREEN} - Result=${result}"
+                       #echo -e "----  \033[32m\033[1mPASS\033[0m - Test criteria met, result = ${result} ----"
+               elif [ $4 = "<" ] && [ "$result" -lt $5 ]; then
+                       ((RES_PASS++))
+                       echo -e $GREEN" PASS${EGREEN} - Result=${result}"
+                       #echo -e "----  \033[32m\033[1mPASS\033[0m - Test criteria met, result = ${result} ----"
+               elif [ $4 = "contain_str" ] && [[ $result =~ $5 ]]; then
+                       ((RES_PASS++))
+                       echo -e $GREEN" PASS${EGREEN} - Result=${result}"
+                       #echo -e "----  \033[32m\033[1mPASS\033[0m - Test criteria met, result = ${result} ----"
+               else
+                       ((RES_FAIL++))
+                       echo -e $RED" FAIL${ERED} - ${3} ${4} ${5} not reached, result = ${result}"
+                       #echo -e "----  \033[31m\033[1mFAIL\033[0m - Target ${3} ${4} ${5} not reached, result = ${result} ----"
+               fi
+       else
+               echo "Wrong args to __var_test, needs five or six args: <simulator-name> <host> <variable-name> <condition-operator> <target-value> [ <timeout> ]"
+               echo "Got:" $@
+               exit 1
+       fi
+}
+
+
+### Generic test cases for varaible checking
+
+# Tests if a variable value in the CR is equal to a target value and and optional timeout.
+# Arg: <variable-name> <target-value> - This test set pass or fail depending on if the variable is
+# equal to the target or not.
+# Arg: <variable-name> <target-value> <timeout-in-sec>  - This test waits up to the timeout seconds
+# before setting pass or fail depending on if the variable value becomes equal to the target
+# value or not.
+# (Function for test scripts)
+cr_equal() {
+       if [ $# -eq 2 ] || [ $# -eq 3 ]; then
+               __var_test "CR" "$LOCALHOST$CR_EXTERNAL_PORT/counter/" $1 "=" $2 $3
+       else
+               ((RES_CONF_FAIL++))
+               __print_err "Wrong args to cr_equal, needs two or three args: <sim-param> <target-value> [ timeout ]" $@
+       fi
+}
+
+# Tests if a variable value in the MR stub is equal to a target value and and optional timeout.
+# Arg: <variable-name> <target-value> - This test set pass or fail depending on if the variable is
+# equal to the target or not.
+# Arg: <variable-name> <target-value> <timeout-in-sec>  - This test waits up to the timeout seconds
+# before setting pass or fail depending on if the variable value becomes equal to the target
+# value or not.
+# (Function for test scripts)
+mr_equal() {
+       if [ $# -eq 2 ] || [ $# -eq 3 ]; then
+               __var_test "MR" "$LOCALHOST$MR_EXTERNAL_PORT/counter/" $1 "=" $2 $3
+       else
+               ((RES_CONF_FAIL++))
+               __print_err "Wrong args to mr_equal, needs two or three args: <sim-param> <target-value> [ timeout ]" $@
+       fi
+}
+
+# Tests if a variable value in the MR stub is greater than a target value and and optional timeout.
+# Arg: <variable-name> <target-value> - This test set pass or fail depending on if the variable is
+# greater than the target or not.
+# Arg: <variable-name> <target-value> <timeout-in-sec>  - This test waits up to the timeout seconds
+# before setting pass or fail depending on if the variable value becomes greater than the target
+# value or not.
+# (Function for test scripts)
+mr_greater() {
+       if [ $# -eq 2 ] || [ $# -eq 3 ]; then
+               __var_test "MR" "$LOCALHOST$MR_EXTERNAL_PORT/counter/" $1 "=" $2 $3
+       else
+               ((RES_CONF_FAIL++))
+               __print_err "Wrong args to mr_greater, needs two or three args: <sim-param> <target-value> [ timeout ]" $@
+       fi
+}
+
+# Read a variable value from MR sim and send to stdout. Arg: <variable-name>
+mr_read() {
+       echo "$(__do_curl $LOCALHOST$MR_EXTERNAL_PORT/counter/$1)"
+}
+
+# Print a variable value from the MR stub.
+# arg: <variable-name>
+# (Function for test scripts)
+mr_print() {
+       if [ $# != 1 ]; then
+               ((RES_CONF_FAIL++))
+       __print_err "need one arg, <mr-param>" $@
+               exit 1
+       fi
+       echo -e $BOLD"INFO(${BASH_LINENO[0]}): mrstub, $1 = $(__do_curl $LOCALHOST$MR_EXTERNAL_PORT/counter/$1)"$EBOLD
+}
+
+
diff --git a/near-rt-ric-simulator/common/testsuite_common.sh b/near-rt-ric-simulator/common/testsuite_common.sh
new file mode 100644 (file)
index 0000000..2c5e6c3
--- /dev/null
@@ -0,0 +1,119 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+
+# Script containing all functions needed for auto testing of test suites
+
+echo "Test suite started as: ${BASH_SOURCE[$i+1]} "$1 $2
+
+
+IMAGE_TAG=""
+
+paramError=1
+if [ $# -gt 0 ]; then
+       if [ $1 == "local" ] || [ $1 == "remote" ] || [ $1 == "remote-remove" ] ; then
+               paramError=0
+       fi
+fi
+if [ $# -eq 2 ]; then
+    if [ $2 == "auto-clean" ]; then
+               paramError=0
+    fi
+fi
+if [ $paramError -ne 0 ]; then
+       echo "Expected arg: local|remote|remote-remove [ auto-clean ]"
+       exit 1
+fi
+
+# Set a description string for the test suite
+if [ -z "$TS_ONELINE_DESCR" ]; then
+       TS_ONELINE_DESCR="<no-description>"
+       echo "No test suite description found, TC_ONELINE_DESCR should be set on in the test script , using "$TS_ONELINE_DESCR
+fi
+
+TSTEST_START=$SECONDS
+
+suite_setup() {
+    ATS=$(basename "${BASH_SOURCE[$i+1]}" .sh)
+
+    echo "#################################################################################################"
+    echo "###################################      Test suite: "$ATS
+    echo "###################################      Started:    "$(date)
+    echo "#################################################################################################"
+    echo "## Description: " $TS_ONELINE_DESCR
+    echo "#################################################################################################"
+    echo ""
+    echo 0 > .tmp_tcsuite_ctr
+    echo 0 > .tmp_tcsuite_pass_ctr
+    echo 0 > .tmp_tcsuite_fail_ctr
+    rm .tmp_tcsuite_pass &> /dev/null
+    touch .tmp_tcsuite_pass
+    rm .tmp_tcsuite_fail &> /dev/null
+    touch .tmp_tcsuite_fail
+}
+
+__print_err() {
+    echo ${FUNCNAME[1]} " "$1" " ${BASH_SOURCE[$i+2]} " line" ${BASH_LINENO[$i+1]}
+}
+
+run_tc() {
+       if [ $# -eq 2 ]; then
+               ./$1 $2 $IMAGE_TAG
+       elif [ $# -eq 3 ]; then
+               ./$1 $2 $3
+       else
+               echo -e "Test case \033[31m\033[1m./"$1 $2 $3 "could not be executed.\033[0m"
+       fi
+}
+
+suite_complete() {
+    TSTEST_END=$SECONDS
+    echo ""
+    echo "#################################################################################################"
+    echo "###################################      Test suite: "$ATS
+    echo "###################################      Ended:      "$(date)
+    echo "#################################################################################################"
+    echo "## Description: " $TS_ONELINE_DESCR
+    echo "## Execution time: " $((TSTEST_END-TSTEST_START)) " seconds"
+    echo "#################################################################################################"
+    echo "###################################      RESULTS"
+    echo ""
+
+    TCSUITE_CTR=$(< .tmp_tcsuite_ctr)
+    TCSUITE_PASS_CTR=$(< .tmp_tcsuite_pass_ctr)
+    TCSUITE_FAIL_CTR=$(< .tmp_tcsuite_fail_ctr)
+
+    total=$((TCSUITE_PASS_CTR+TCSUITE_FAIL_CTR))
+    if [ $TCSUITE_CTR -eq 0 ]; then
+               echo -e "\033[1mNo test cases seem to have executed. Check the script....\033[0m"
+       elif [ $total != $TCSUITE_CTR ]; then
+        echo -e "\033[1mTotal number of test cases does not match the sum of passed and failed test cases. Check the script....\033[0m"
+    fi
+    echo "Number of test cases : " $TCSUITE_CTR
+    echo -e "Number of \033[31m\033[1mFAIL\033[0m:        " $TCSUITE_FAIL_CTR
+    echo -e "Number of \033[32m\033[1mPASS\033[0m:        " $TCSUITE_PASS_CTR
+    echo ""
+    echo "PASS test cases"
+    cat .tmp_tcsuite_pass
+    echo ""
+    echo "FAIL test cases"
+    cat .tmp_tcsuite_fail
+    echo ""
+
+    echo "###################################      Test suite completed      ##############################"
+    echo "#################################################################################################"
+}
\ No newline at end of file
diff --git a/near-rt-ric-simulator/cr/.gitignore b/near-rt-ric-simulator/cr/.gitignore
new file mode 100644 (file)
index 0000000..4512d6f
--- /dev/null
@@ -0,0 +1 @@
+.tmp.json
\ No newline at end of file
diff --git a/near-rt-ric-simulator/cr/Dockerfile b/near-rt-ric-simulator/cr/Dockerfile
new file mode 100644 (file)
index 0000000..d2e69cd
--- /dev/null
@@ -0,0 +1,28 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+FROM python:3.8-slim-buster
+
+WORKDIR /usr/src/app
+
+COPY requirements.txt requirements.txt
+
+RUN pip install -r requirements.txt
+
+COPY cr.py cr.py
+
+CMD [ "python3", "-u", "./cr.py" ]
\ No newline at end of file
diff --git a/near-rt-ric-simulator/cr/README.md b/near-rt-ric-simulator/cr/README.md
new file mode 100644 (file)
index 0000000..74205f4
--- /dev/null
@@ -0,0 +1,44 @@
+## callback receiver - a stub interface to receive callbacks ##
+
+The mrstub is intended for function tests to simulate a message router.
+The mrstub exposes the read and write urls, used by the agent, as configured in consul.
+In addition, request messages can be fed to the mrstub and the response messages can be read by polling.
+
+
+### Control interface ###
+
+The control interface can be used by any test script.
+The following REST operations are available:
+
+>Send a message to MR<br>
+This method puts a request message in the queue for the agent to pick up. The returned correlationId (auto generated by the mrstub) is used when polling for the reposone message of this particular request.<br>
+```URI and parameter, (GET): /get-event/<id>```<br><br>
+```response: message + 200 or 204```
+
+>Receive a message response for MR for the included correlation id<br>
+The method is for polling of messages, returns immediately containing the received response (if any) for the supplied correlationId.<br>
+```URI and payload, (PUT or POST): /callbacks/<id> <json array of response messages>```<br><br>
+```response: OK 200 or 500 for other errors```
+
+>Metrics - counters<br>
+There are a number of counters that can be read to monitor the message processing. Do a http GET on any of the current counters and an integer value will be returned with http response code 200.
+```/counter/received_callbacks``` - The total number of received callbacks<br>
+```/counter/fetched_callbacks``` - The total number of fetched callbacks<br>
+```/counter/current_messages``` - The current number of callback messages waiting to be fetched<br>
+
+
+### Build and start ###
+
+>Build image<br>
+```docker build -t callback-receiver .```
+
+>Start the image<br>
+```docker run -it -p 8090:8090 callback-receiver```
+
+The script ```crstub-build-start.sh``` do the above two steps in one go. This starts the callback-receiver container in stand-alone mode for basic test.<br>If the callback-receiver should be executed manually with the agent, replace docker run with this command to connect to the docker network with the correct service name (--name shall be aligned with the other components, i.e. the host named given in all callback urls).
+```docker run -it -p 8090:8090 --network nonrtric-docker-net --name callback-receiver callback-receiver```
+
+
+### Basic test ###
+
+Basic test is made with the script ```basic_test.sh``` which tests all the available urls with a subset of the possible operations. Use the script ```cr-build-start.sh``` to start the callback-receiver in a container first.
\ No newline at end of file
diff --git a/near-rt-ric-simulator/cr/basic_test.sh b/near-rt-ric-simulator/cr/basic_test.sh
new file mode 100755 (executable)
index 0000000..8be110a
--- /dev/null
@@ -0,0 +1,110 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+# Automated test script for callback receiver container
+
+# callbackreciver port
+export PORT=8090
+
+# source function to do curl and check result
+. ../common/do_curl_function.sh
+
+echo "=== CR hello world ==="
+RESULT="OK"
+do_curl GET / 200
+
+
+echo "=== Get counter - callbacks ==="
+RESULT="0"
+do_curl GET /counter/received_callbacks 200
+
+echo "=== Get counter - fetched events ==="
+RESULT="0"
+do_curl GET /counter/fetched_callbacks 200
+
+echo "=== Get counter - current events ==="
+RESULT="0"
+do_curl GET /counter/current_messages 200
+
+
+echo "=== Send a request ==="
+RESULT="*"
+#create payload
+echo "\"DATA-MSG\"" > .tmp.json
+do_curl POST '/callbacks/test' 200 .tmp.json
+
+
+echo "=== Fetch an event, wrong id==="
+RESULT="*"
+do_curl GET '/get-event/wrongid' 204
+
+
+echo "=== Get counter - callbacks ==="
+RESULT="1"
+do_curl GET /counter/received_callbacks 200
+
+echo "=== Get counter - fetched events ==="
+RESULT="0"
+do_curl GET /counter/fetched_callbacks 200
+
+echo "=== Get counter - current events ==="
+RESULT="1"
+do_curl GET /counter/current_messages 200
+
+
+echo "=== Fetch an event ==="
+RESULT="DATA-MSG"
+do_curl GET '/get-event/test' 200
+
+echo "=== Fetch an event again ==="
+RESULT="*"
+do_curl GET '/get-event/test' 204
+
+echo "=== Get counter - callbacks ==="
+RESULT="1"
+do_curl GET /counter/received_callbacks 200
+
+echo "=== Get counter - fetched events ==="
+RESULT="1"
+do_curl GET /counter/fetched_callbacks 200
+
+echo "=== Get counter - current events ==="
+RESULT="0"
+do_curl GET /counter/current_messages 200
+
+echo "=== CR reset ==="
+RESULT="OK"
+do_curl GET /reset 200
+
+echo "=== Get counter - callbacks ==="
+RESULT="0"
+do_curl GET /counter/received_callbacks 200
+
+echo "=== Get counter - fetched events ==="
+RESULT="0"
+do_curl GET /counter/fetched_callbacks 200
+
+echo "=== Get counter - current events ==="
+RESULT="0"
+do_curl GET /counter/current_messages 200
+
+
+echo "********************"
+echo "*** All tests ok ***"
+echo "********************"
diff --git a/near-rt-ric-simulator/cr/cr-build-start.sh b/near-rt-ric-simulator/cr/cr-build-start.sh
new file mode 100755 (executable)
index 0000000..1954eb7
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+#Builds the callback receiver container and starts it in interactive mode
+
+docker build -t callback-receiver .
+
+docker run -it -p 8090:8090 callback-receiver
diff --git a/near-rt-ric-simulator/cr/cr.py b/near-rt-ric-simulator/cr/cr.py
new file mode 100644 (file)
index 0000000..28e3b10
--- /dev/null
@@ -0,0 +1,158 @@
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+from flask import Flask, request
+from time import sleep
+import time
+import datetime
+import json
+from flask import Flask
+from flask import Response
+import traceback
+
+app = Flask(__name__)
+
+# list of callback messages
+msg_callbacks={}
+
+# Server info
+HOST_IP = "0.0.0.0"
+HOST_PORT = 8090
+
+# Metrics vars
+cntr_msg_callbacks=0
+cntr_msg_fetched=0
+
+# Request and response constants
+CALLBACK_URL="/callbacks/<string:id>"
+APP_READ_URL="/get-event/<string:id>"
+
+MIME_TEXT="text/plain"
+MIME_JSON="application/json"
+CAUGHT_EXCEPTION="Caught exception: "
+SERVER_ERROR="Server error :"
+
+#I'm alive function
+@app.route('/',
+    methods=['GET'])
+def index():
+    return 'OK', 200
+
+### Callback interface, for control
+
+# Fetch the oldest callback message for an id
+# URI and parameter, (GET): /get-event/<id>
+# response: message + 200 or 204
+@app.route(APP_READ_URL,
+    methods=['GET'])
+def receiveresponse(id):
+    global msg_callbacks
+    global cntr_msg_fetched
+
+    try:
+        if ((id in msg_callbacks.keys()) and (len(msg_callbacks[id]) > 0)):
+            cntr_msg_fetched+=1
+            msg=str(msg_callbacks[id][0])
+            print("Fetching msg for id: "+id+", msg="+msg)
+            del msg_callbacks[id][0]
+            return msg,200
+        print("No messages for id: "+id)
+    except Exception as e:
+        print(CAUGHT_EXCEPTION+str(e))
+
+    return "",204
+
+
+# Receive a callback message
+# URI and payload, (PUT or POST): /callbacks/<id> <json array of response messages>
+# response: OK 200 or 500 for other errors
+@app.route(CALLBACK_URL,
+    methods=['PUT','POST'])
+def events_write(id):
+    global msg_callbacks
+    global cntr_msg_callbacks
+
+    try:
+        print("Received callback for id: "+id +", content-type="+request.content_type)
+        try:
+            print("data:"+request.get_data)
+            if (request.content_type == MIME_JSON):
+                msg = request.json
+                print("Payload(json): "+str(msg))
+            elif (request.content_type == MIME_TEXT):
+                msg= request.form
+                print("Payload(text): "+str(msg))
+            else:
+                msg="\"\""
+                print("Payload(content-type="+request.content_type+"). Setting data to empty, quoted, string")
+        except:
+            msg="\"\""
+            print("Payload does not contain any json or text data, setting empty string as payload")
+
+        cntr_msg_callbacks += 1
+        if (id in msg_callbacks.keys()):
+            msg_callbacks[id].append(msg)
+        else:
+            msg_callbacks[id]=[]
+            msg_callbacks[id].append(msg)
+    except Exception as e:
+        print(CAUGHT_EXCEPTION+str(e))
+        return 'OK',500
+
+    return 'OK',200
+
+
+### Functions for metrics read out ###
+
+@app.route('/counter/received_callbacks',
+    methods=['GET'])
+def requests_submitted():
+    return Response(str(cntr_msg_callbacks), status=200, mimetype=MIME_TEXT)
+
+@app.route('/counter/fetched_callbacks',
+    methods=['GET'])
+def requests_fetched():
+    return Response(str(cntr_msg_fetched), status=200, mimetype=MIME_TEXT)
+
+@app.route('/counter/current_messages',
+    methods=['GET'])
+def current_messages():
+    return Response(str(cntr_msg_callbacks-cntr_msg_fetched), status=200, mimetype=MIME_TEXT)
+
+
+
+### Admin ###
+
+# Reset all messsages and counters
+@app.route('/reset',
+    methods=['GET', 'POST', 'PUT'])
+def reset():
+    global msg_callbacks
+    global cntr_msg_fetched
+    global cntr_msg_callbacks
+
+    msg_callbacks={}
+    cntr_msg_fetched=0
+    cntr_msg_callbacks=0
+
+    return Response('OK', status=200, mimetype=MIME_TEXT)
+
+### Main function ###
+
+if __name__ == "__main__":
+    app.run(port=HOST_PORT, host=HOST_IP)
diff --git a/near-rt-ric-simulator/cr/requirements.txt b/near-rt-ric-simulator/cr/requirements.txt
new file mode 100644 (file)
index 0000000..1dabaa8
--- /dev/null
@@ -0,0 +1,3 @@
+Flask==1.1.1
+
+
diff --git a/near-rt-ric-simulator/mrstub/.gitignore b/near-rt-ric-simulator/mrstub/.gitignore
new file mode 100644 (file)
index 0000000..4512d6f
--- /dev/null
@@ -0,0 +1 @@
+.tmp.json
\ No newline at end of file
diff --git a/near-rt-ric-simulator/mrstub/Dockerfile b/near-rt-ric-simulator/mrstub/Dockerfile
new file mode 100644 (file)
index 0000000..f1d16b7
--- /dev/null
@@ -0,0 +1,28 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+FROM python:3.7
+
+WORKDIR /usr/src/app
+
+COPY requirements.txt requirements.txt
+
+RUN pip install -r requirements.txt
+
+COPY mr.py mr.py
+
+CMD [ "python3", "-u", "./mr.py" ]
\ No newline at end of file
diff --git a/near-rt-ric-simulator/mrstub/README.md b/near-rt-ric-simulator/mrstub/README.md
new file mode 100644 (file)
index 0000000..6a69930
--- /dev/null
@@ -0,0 +1,47 @@
+## mrstub - stub interface to interact with the policy agent over Dmaap ##
+
+The mrstub is intended for function tests to simulate a message router.
+The mrstub exposes the read and write urls, used by the agent, as configured in consul.
+In addition, request messages can be fed to the mrstub and the response messages can be read by polling.
+
+
+### Control interface ###
+
+The control interface can be used by any test script.
+The following REST operations are available:
+
+>Send a message to MR<br>
+This method puts a request message in the queue for the agent to pick up. The returned correlationId (auto generated by the mrstub) is used when polling for the reposone message of this particular request.<br>
+```URI and parameters (GET): /send-request?operation=<GET|PUT|POST|DELETE>&url=<url>```<br><br>
+```response: <correlation-id> (http 200) or 400 for parameter error or 500 for other errors```
+
+>Receive a message response for MR for the included correlation id<br>
+The method is for polling of messages, returns immediately containing the received response (if any) for the supplied correlationId.<br>
+```URI and parameter, (GET): /receive-response?correlationId=<correlationid>```<br><br>
+```response: <json-array of 1 response> 200 or empty 204 or other errors 500```
+
+>Metrics - counters<br>
+There are a number of counters that can be read to monitor the message processing. Do a http GET on any of the current counters and an integer value will be returned with http response code 200.
+```/counter/requests_submitted``` - The total number of requests sent from the application<br>
+```/counter/requests_fetched``` - The total number of requests picked up by the agent<br>
+```/counter/responses_submitted``` - The total number of responses written by the agent<br>
+```/counter/responses_fetched``` - The total number of responses picked up by the application<br>
+```/counter/current_requests``` - The current number of requests waiting to be picked up by the agent<br>
+```/counter/current_responses``` - The current number of responses waiting to be picked up by the application<br>
+
+
+### Build and start ###
+
+>Build image<br>
+```docker build -t mrstub .```
+
+>Start the image<br>
+```docker run -it -p 3905:3905 mrstub```
+
+The script ```mrstub-build-start.sh``` do the above two steps in one go. This starts the stub container in stand-alone mode for basic test.<br>If the mrstub should be executed manually with the agent, replace docker run with this command to connect to the docker network with the correct service name (--name shall be the same as configured in consul for the read and write streams).
+```docker run -it -p 3905:3905 --network nonrtric-docker-net --name message-router mrstub```
+
+
+### Basic test ###
+
+Basic test is made with the script ```basic_test.sh``` which tests all the available urls with a subset of the possible operations. Use the script ```mrstub-build-start.sh``` to start the mrstub in a container first.
\ No newline at end of file
diff --git a/near-rt-ric-simulator/mrstub/basic_test.sh b/near-rt-ric-simulator/mrstub/basic_test.sh
new file mode 100755 (executable)
index 0000000..13ea3a6
--- /dev/null
@@ -0,0 +1,93 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+# Automated test script for mrstub container
+
+# mr-stub port
+export PORT=3905
+
+# source function to do curl and check result
+. ../common/do_curl_function.sh
+
+echo "=== Stub hello world ==="
+RESULT="OK"
+do_curl GET / 200
+
+echo "=== Stub reset ==="
+RESULT="OK"
+do_curl GET /reset 200
+
+## Test with json response
+
+echo "=== Send a request ==="
+RESULT="*"
+#create payload
+echo "{\"data\": \"data-value\"}" > .tmp.json
+
+do_curl POST '/send-request?operation=PUT&url=/test' 200 .tmp.json
+#Save id for later
+CORRID=$body
+
+echo "=== Fetch a response, shall be empty ==="
+RESULT=""
+do_curl GET '/receive-response?correlationid='$CORRID 204
+
+echo "=== Fetch a request ==="
+RESULT="json:[{\"apiVersion\":\"1.0\",\"operation\":\"PUT\",\"correlationId\":\""$CORRID"\",\"originatorId\": \"849e6c6b420\",\"payload\":{\"data\": \"data-value\"},\"requestId\":\"23343221\", \"target\":\"policy-agent\", \"timestamp\":\"????\", \"type\":\"request\",\"url\":\"/test\"}]"
+do_curl GET '/events/A1-POLICY-AGENT-READ/users/policy-agent' 200
+
+echo "=== Send a json response ==="
+# Create minimal accepted response message
+echo "[{\"correlationId\": \""$CORRID"\", \"message\": {\"test\":\"testresponse\"}, \"status\": \"200\"}]" > .tmp.json
+RESULT="OK"
+do_curl POST /events/A1-POLICY-AGENT-WRITE 200 .tmp.json
+
+echo "=== Fetch a response ==="
+RESULT="{\"test\": \"testresponse\"}200"
+do_curl GET '/receive-response?correlationid='$CORRID 200
+
+### Test with plain text response
+
+echo "=== Send a request ==="
+RESULT="*"
+do_curl POST '/send-request?operation=GET&url=/test2' 200
+#Save id for later
+CORRID=$body
+
+echo "=== Fetch a response, shall be empty ==="
+RESULT=""
+do_curl GET '/receive-response?correlationid='$CORRID 204
+
+echo "=== Fetch a request ==="
+RESULT="json:[{\"apiVersion\":\"1.0\",\"operation\":\"GET\",\"correlationId\":\""$CORRID"\",\"originatorId\": \"849e6c6b420\",\"payload\":{},\"requestId\":\"23343221\", \"target\":\"policy-agent\", \"timestamp\":\"????\", \"type\":\"request\",\"url\":\"/test2\"}]"
+do_curl GET '/events/A1-POLICY-AGENT-READ/users/policy-agent' 200
+
+echo "=== Send a json response ==="
+# Create minimal accepted response message
+echo "[{\"correlationId\": \""$CORRID"\", \"message\": \"test2-response\", \"status\": \"200\"}]" > .tmp.json
+RESULT="OK"
+do_curl POST /events/A1-POLICY-AGENT-WRITE 200 .tmp.json
+
+echo "=== Fetch a response ==="
+RESULT="test2-response200"
+do_curl GET '/receive-response?correlationid='$CORRID 200
+
+echo "********************"
+echo "*** All tests ok ***"
+echo "********************"
diff --git a/near-rt-ric-simulator/mrstub/mr.py b/near-rt-ric-simulator/mrstub/mr.py
new file mode 100644 (file)
index 0000000..45f8cfe
--- /dev/null
@@ -0,0 +1,265 @@
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+from flask import Flask, request
+from time import sleep
+import time
+import datetime
+import json
+from flask import Flask
+from flask import Response
+import traceback
+
+app = Flask(__name__)
+
+# list of messages to/from Dmaap
+msg_requests={}
+msg_responses={}
+
+# Server info
+HOST_IP = "0.0.0.0"
+HOST_PORT = 3905
+
+# Metrics vars
+cntr_msg_requests_submitted=0
+cntr_msg_requests_fetched=0
+cntr_msg_responses_submitted=0
+cntr_msg_responses_fetched=0
+
+# Request and response constants
+AGENT_WRITE_URL="/events/A1-POLICY-AGENT-WRITE"
+AGENT_READ_URL="/events/A1-POLICY-AGENT-READ/users/policy-agent"
+APP_WRITE_URL="/send-request"
+APP_READ_URL="/receive-response"
+MIME_TEXT="text/plain"
+MIME_JSON="application/json"
+CAUGHT_EXCEPTION="Caught exception: "
+SERVER_ERROR="Server error :"
+
+#I'm alive function
+@app.route('/',
+    methods=['GET'])
+def index():
+    return 'OK', 200
+
+
+# Helper function to create a Dmaap request message
+# args : <GET|PUT|DELETE> <correlation-id> <json-string-payload - may be None> <url>
+# response: json formatted string of a complete Dmaap message
+def create_message(operation, correlation_id, payload, url):
+    if (payload is None):
+        payload="{}"
+    time_stamp=datetime.datetime.utcnow()
+    msg = '{\"apiVersion\":\"1.0\",\"operation\":\"'+operation+'\",\"correlationId\":\"'+correlation_id+'\",\"originatorId\": \"849e6c6b420\",'
+    msg = msg + '\"payload\":'+payload+',\"requestId\":\"23343221\", \"target\":\"policy-agent\", \"timestamp\":\"'+str(time_stamp)+'\", \"type\":\"request\",\"url\":\"'+url+'\"}'
+    return msg
+
+
+### MR-stub interface, for MR control
+
+# Send a message to MR
+# URI and parameters (GET): /send-request?operation=<GET|PUT|POST|DELETE>&url=<url>
+# response: <correlation-id> (http 200) o4 400 for parameter error or 500 for other errors
+@app.route(APP_WRITE_URL,
+    methods=['PUT','POST'])
+def sendrequest():
+    global msg_requests
+    global cntr_msg_requests_submitted
+
+    try:
+
+        oper=request.args.get('operation')
+        if (oper is None):
+            print(APP_WRITE_URL+" parameter 'operation' missing")
+            return Response('Parameter operation missing in request', status=400, mimetype=MIME_TEXT)
+
+        url=request.args.get('url')
+        if (url is None):
+            print(APP_WRITE_URL+" parameter 'url' missing")
+            return Response('Parameter url missing in request', status=400, mimetype=MIME_TEXT)
+
+        if (oper != "GET" and oper != "PUT" and oper != "POST" and oper != "DELETE"):
+            print(APP_WRITE_URL+" parameter 'operation' need to be: DEL|PUT|POST|DELETE")
+            return Response('Parameter operation does not contain DEL|PUT|POST|DELETE in request', status=400, mimetype=MIME_TEXT)
+
+        print(APP_WRITE_URL+" operation="+oper+" url="+url)
+        correlation_id=str(time.time_ns())
+        payload=None
+        if (oper == "PUT") and (request.json is not None):
+            payload=json.dumps(request.json)
+
+        msg=create_message(oper, correlation_id, payload, url)
+        print(msg)
+        print(APP_WRITE_URL+" MSG(correlationid = "+correlation_id+"): " + json.dumps(json.loads(msg), indent=2))
+        msg_requests[correlation_id]=msg
+        cntr_msg_requests_submitted += 1
+        return Response(correlation_id, status=200, mimetype=MIME_TEXT)
+    except Exception as e:
+        print(APP_WRITE_URL+"-"+CAUGHT_EXCEPTION+" "+str(e) + " "+traceback.format_exc())
+        return Response(SERVER_ERROR+" "+str(e), status=500, mimetype=MIME_TEXT)
+
+# Receive a message response for MR for the included correlation id
+# URI and parameter, (GET): /receive-response?correlationid=<correlation-id>
+# response: <json-array of 1 response> 200 or empty 204 or other errors 500
+@app.route(APP_READ_URL,
+    methods=['GET'])
+def receiveresponse():
+    global msg_responses
+    global cntr_msg_responses_fetched
+
+    try:
+        id=request.args.get('correlationid')
+        if (id is None):
+            print(APP_READ_URL+" parameter 'correclationid' missing")
+            return Response('Parameter correlationid missing in json', status=500, mimetype=MIME_TEXT)
+
+        if (id in msg_responses):
+            answer=msg_responses[id]
+            del msg_responses[id]
+            print(APP_READ_URL+" response (correlationid="+id+"): " + answer)
+            cntr_msg_responses_fetched += 1
+            return Response(answer, status=200, mimetype=MIME_JSON)
+
+        print(APP_READ_URL+" - no messages (correlationid="+id+"): ")
+        return Response('', status=204, mimetype=MIME_JSON)
+    except Exception as e:
+        print(APP_READ_URL+"-"+CAUGHT_EXCEPTION+" "+str(e) + " "+traceback.format_exc())
+        return Response(SERVER_ERROR+" "+str(e), status=500, mimetype=MIME_TEXT)
+
+### Dmaap interface ###
+
+# Read messages stream. URI according to agent configuration.
+# URI, (GET): /events/A1-POLICY-AGENT-READ/users/policy-agent
+# response: 200 <json array of request messages>, or 500 for other errors
+@app.route(AGENT_READ_URL,
+    methods=['GET'])
+def events_read():
+    global msg_requests
+    global cntr_msg_requests_fetched
+    try:
+        msgs=''
+        for item in msg_requests:
+            if (len(msgs)>1):
+                msgs=msgs+','
+            msgs=msgs+msg_requests[item]
+            cntr_msg_requests_fetched += 1
+
+        msg_requests={}
+        msgs='['+msgs+']'
+        print(AGENT_READ_URL+" MSGs: "+json.dumps(json.loads(msgs), indent=2))
+        return Response(msgs, status=200, mimetype=MIME_JSON)
+    except Exception as e:
+        print(AGENT_READ_URL+"-"+CAUGHT_EXCEPTION+" "+str(e) + " "+traceback.format_exc())
+        return Response(SERVER_ERROR+" "+str(e), status=500, mimetype=MIME_TEXT)
+
+# Write messages stream. URI according to agent configuration.
+# URI and payload, (PUT or POST): /events/A1-POLICY-AGENT-WRITE <json array of response messages>
+# response: OK 200 or 400 for missing json parameters, 500 for other errors
+@app.route(AGENT_WRITE_URL,
+    methods=['PUT','POST'])
+def events_write():
+    global msg_responses
+    global cntr_msg_responses_submitted
+
+    try:
+        answer=request.json
+        print(AGENT_WRITE_URL+ " json=" + json.dumps(answer, indent=2))
+        for item in answer:
+            id=item['correlationId']
+            if (id is None):
+                print(AGENT_WRITE_URL+" parameter 'correlatonid' missing")
+                return Response('Parameter <correlationid> missing in json', status=400, mimetype=MIME_TEXT)
+            msg=item['message']
+            if (msg is None):
+                print(AGENT_WRITE_URL+" parameter 'msgs' missing")
+                return Response('Parameter >message> missing in json', status=400, mimetype=MIME_TEXT)
+            status=item['status']
+            if (status is None):
+                print(AGENT_WRITE_URL+" parameter 'status' missing")
+                return Response('Parameter <status> missing in json', status=400, mimetype=MIME_TEXT)
+            if isinstance(msg, list) or isinstance(msg, dict):
+                msg_str=json.dumps(msg)+status[0:3]
+            else:
+                msg_str=msg+status[0:3]
+            msg_responses[id]=msg_str
+            cntr_msg_responses_submitted += 1
+            print(AGENT_WRITE_URL+ " msg+status (correlationid="+id+") :" + str(msg_str))
+    except Exception as e:
+        print(AGENT_WRITE_URL+"-"+CAUGHT_EXCEPTION+" "+str(e) + " "+traceback.format_exc())
+        return Response(SERVER_ERROR+" "+str(e), status=500, mimetype=MIME_TEXT)
+
+    return Response('OK', status=200, mimetype=MIME_TEXT)
+
+
+### Functions for metrics read out ###
+
+@app.route('/counter/requests_submitted',
+    methods=['GET'])
+def requests_submitted():
+    return Response(str(cntr_msg_requests_submitted), status=200, mimetype=MIME_TEXT)
+
+@app.route('/counter/requests_fetched',
+    methods=['GET'])
+def requests_fetched():
+    return Response(str(cntr_msg_requests_fetched), status=200, mimetype=MIME_TEXT)
+
+@app.route('/counter/responses_submitted',
+    methods=['GET'])
+def responses_submitted():
+    return Response(str(cntr_msg_responses_submitted), status=200, mimetype=MIME_TEXT)
+
+@app.route('/counter/responses_fetched',
+    methods=['GET'])
+def responses_fetched():
+    return Response(str(cntr_msg_responses_fetched), status=200, mimetype=MIME_TEXT)
+
+@app.route('/counter/current_requests',
+    methods=['GET'])
+def current_requests():
+    return Response(str(len(msg_requests)), status=200, mimetype=MIME_TEXT)
+
+@app.route('/counter/current_responses',
+    methods=['GET'])
+def current_responses():
+    return Response(str(len(msg_responses)), status=200, mimetype=MIME_TEXT)
+
+### Admin ###
+
+# Reset all messsages and counters
+@app.route('/reset',
+    methods=['GET', 'POST', 'PUT'])
+def reset():
+    global cntr_msg_requests_submitted
+    global cntr_msg_requests_fetched
+    global cntr_msg_responses_submitted
+    global cntr_msg_responses_fetched
+    global msg_requests
+    global msg_responses
+
+    cntr_msg_requests_submitted=0
+    cntr_msg_requests_fetched=0
+    cntr_msg_responses_submitted=0
+    cntr_msg_responses_fetched=0
+    msg_requests={}
+    msg_responses={}
+    return Response('OK', status=200, mimetype=MIME_TEXT)
+
+### Main function ###
+
+if __name__ == "__main__":
+    app.run(port=HOST_PORT, host=HOST_IP)
diff --git a/near-rt-ric-simulator/mrstub/mrstub-build-start.sh b/near-rt-ric-simulator/mrstub/mrstub-build-start.sh
new file mode 100755 (executable)
index 0000000..1a463dc
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+#Builds the mrstub container and starts it in interactive mode
+
+docker build -t mrstub .
+
+docker run -it -p 3905:3905 mrstub
diff --git a/near-rt-ric-simulator/mrstub/requirements.txt b/near-rt-ric-simulator/mrstub/requirements.txt
new file mode 100644 (file)
index 0000000..1dabaa8
--- /dev/null
@@ -0,0 +1,3 @@
+Flask==1.1.1
+
+
diff --git a/near-rt-ric-simulator/simulator-group/.gitignore b/near-rt-ric-simulator/simulator-group/.gitignore
new file mode 100644 (file)
index 0000000..25c8fdb
--- /dev/null
@@ -0,0 +1,2 @@
+node_modules
+package-lock.json
\ No newline at end of file
diff --git a/near-rt-ric-simulator/simulator-group/consul_cbs/config.json b/near-rt-ric-simulator/simulator-group/consul_cbs/config.json
deleted file mode 100644 (file)
index 52acc38..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-{
-    "ric": [
-        {
-            "name": "ric_ric-simulator_3",
-            "baseUrl": "http://ric_ric-simulator_3:8085/",
-            "managedElementIds": [
-                "kista_ric_ric-simulator_3",
-                "stockholm_ric_ric-simulator_3"
-            ]
-        },
-        {
-            "name": "ric_ric-simulator_2",
-            "baseUrl": "http://ric_ric-simulator_2:8085/",
-            "managedElementIds": [
-                "kista_ric_ric-simulator_2",
-                "stockholm_ric_ric-simulator_2"
-            ]
-        },
-        {
-            "name": "ric_ric-simulator_1",
-            "baseUrl": "http://ric_ric-simulator_1:8085/",
-            "managedElementIds": [
-                "kista_ric_ric-simulator_1",
-                "stockholm_ric_ric-simulator_1"
-            ]
-        }
-    ],
-    "streams_publishes": {
-        "dmaap_publisher": {
-            "type": "message_router",
-            "dmaap_info": {
-                "topic_url": "http://message-router:3905/events/A1-POLICY-AGENT-WRITE"
-            }
-        }
-    },
-    "streams_subscribes": {
-        "dmaap_subscriber": {
-            "type": "message_router",
-            "dmaap_info": {
-                "topic_url": "http://message-router:3905/events/A1-POLICY-AGENT-READ/users/policy-agent"
-            }
-        }
-    }
-}
\ No newline at end of file
index d36ae56..004fb1d 100644 (file)
@@ -1,3 +1,20 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
 #server = true
 #bootstrap = true
 #client_addr = "0.0.0.0"
index 63be3d4..ff0bd31 100644 (file)
@@ -1,3 +1,20 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
 service {
   # Name for CBS in consul, env var CONFIG_BINDING_SERVICE
   # should be passed to Policy Agent app with this value
diff --git a/near-rt-ric-simulator/simulator-group/consul_cbs/docker-compose-template.yml b/near-rt-ric-simulator/simulator-group/consul_cbs/docker-compose-template.yml
deleted file mode 100644 (file)
index c2d07de..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-version: '3'
-
-networks:
-  nonrtric-docker-net:
-    external:
-      name: nonrtric-docker-net
-
-services:
-
-  consul-server:
-    networks:
-      - nonrtric-docker-net
-    container_name: polman_consul
-    image: docker.io/consul:1.4.4
-    ports:
-      - "8500:8500"
-    volumes:
-      - ./consul/:/consul/config
-
-  config-binding-service:
-    networks:
-      - nonrtric-docker-net
-    container_name: polman_cbs
-    image: nexus3.onap.org:10001/onap/org.onap.dcaegen2.platform.configbinding.app-app:2.3.0
-    ports:
-      - "10000:10000"
-    environment:
-      - CONSUL_HOST=consul-server
-    depends_on:
-      - consul-server
-
diff --git a/near-rt-ric-simulator/simulator-group/consul_cbs/docker-compose.yml b/near-rt-ric-simulator/simulator-group/consul_cbs/docker-compose.yml
new file mode 100644 (file)
index 0000000..15d3de1
--- /dev/null
@@ -0,0 +1,48 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+version: '3'
+
+networks:
+  default:
+    external:
+      name: ${DOCKER_SIM_NWNAME}
+
+services:
+
+  consul-server:
+    networks:
+      - default
+    container_name: ${CONSUL_APP_NAME}
+    image: ${CONSUL_IMAGE}
+    ports:
+      - ${CONSUL_EXTERNAL_PORT}:${CONSUL_INTERNAL_PORT}
+    volumes:
+      - ./consul/:/consul/config
+
+  config-binding-service:
+    networks:
+      - default
+    container_name: ${CBS_APP_NAME}
+    image: ${CBS_IMAGE}
+    ports:
+      - ${CBS_EXTERNAL_PORT}:${CBS_INTERNAL_PORT}
+    environment:
+      - CONSUL_HOST=${CONSUL_HOST}
+    depends_on:
+      - ${CONSUL_HOST}
+
index ed4f9e6..b0399f2 100755 (executable)
@@ -1,5 +1,22 @@
 #!/bin/bash
 
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
 DOCKER_SIM_NWNAME="nonrtric-docker-net"
 echo "Creating docker network $DOCKER_SIM_NWNAME, if needed"
 docker network ls| grep $DOCKER_SIM_NWNAME > /dev/null || docker network create $DOCKER_SIM_NWNAME
diff --git a/near-rt-ric-simulator/simulator-group/control_panel/docker-compose.yml b/near-rt-ric-simulator/simulator-group/control_panel/docker-compose.yml
new file mode 100644 (file)
index 0000000..4e86f3c
--- /dev/null
@@ -0,0 +1,32 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+version: '3.0'
+networks:
+  default:
+    external:
+      name: nonrtric-docker-net
+services:
+  control-panel:
+    image: ${CONTROL_PANEL_IMAGE}
+    container_name: ${CONTROL_PANEL_APP_NAME}
+    networks:
+      - default
+    ports:
+    - ${CONTROL_PANEL_EXTERNAL_PORT}:${CONTROL_PANEL_INTERNAL_PORT}
+
+
+
diff --git a/near-rt-ric-simulator/simulator-group/cr/docker-compose.yml b/near-rt-ric-simulator/simulator-group/cr/docker-compose.yml
new file mode 100644 (file)
index 0000000..77a958f
--- /dev/null
@@ -0,0 +1,30 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+version: '3.0'
+networks:
+  default:
+    external:
+      name: ${DOCKER_SIM_NWNAME}
+services:
+  callback-receiver:
+    networks:
+      - default
+    container_name: ${CR_APP_NAME}
+    image: ${CR_IMAGE}
+    ports:
+      - ${CR_EXTERNAL_PORT}:${CR_INTERNAL_PORT}
diff --git a/near-rt-ric-simulator/simulator-group/dashboard/docker-compose.yml b/near-rt-ric-simulator/simulator-group/dashboard/docker-compose.yml
deleted file mode 100644 (file)
index ef4ecd3..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-networks:
-  nonrtric-docker-net:
-    external:
-      name: nonrtric-docker-net
-services:
-  dashboard:
-    image: nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-dashboard:1.0.1
-
-    networks:
-      nonrtric-docker-net: null
-    ports:
-    - 8080:8080
-version: '3.0'
-
-
diff --git a/near-rt-ric-simulator/simulator-group/mr/docker-compose.yml b/near-rt-ric-simulator/simulator-group/mr/docker-compose.yml
new file mode 100644 (file)
index 0000000..887b216
--- /dev/null
@@ -0,0 +1,30 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+version: '3.0'
+networks:
+  default:
+    external:
+      name: ${DOCKER_SIM_NWNAME}
+services:
+  message-router:
+    networks:
+      - default
+    container_name: ${MR_APP_NAME}
+    image: ${MRSTUB_IMAGE}
+    ports:
+      - ${MR_EXTERNAL_PORT}:${MR_INTERNAL_PORT}
diff --git a/near-rt-ric-simulator/simulator-group/policy_agent/docker-compose.yml b/near-rt-ric-simulator/simulator-group/policy_agent/docker-compose.yml
new file mode 100644 (file)
index 0000000..f349249
--- /dev/null
@@ -0,0 +1,35 @@
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+version: '3.0'
+networks:
+  default:
+    external:
+      name: ${DOCKER_SIM_NWNAME}
+services:
+  policy-agent:
+    image: ${POLICY_AGENT_IMAGE}
+    container_name: ${POLICY_AGENT_APP_NAME}
+    networks:
+      - default
+    ports:
+    - ${POLICY_AGENT_EXTERNAL_PORT}:${POLICY_AGENT_INTERNAL_PORT}
+    environment:
+      - CONSUL_HOST=${CONSUL_HOST}
+      - CONSUL_PORT=${CONSUL_INTERNAL_PORT}
+      - CONFIG_BINDING_SERVICE=${CONFIG_BINDING_SERVICE}
+      - HOSTNAME=${POLICY_AGENT_APP_NAME}
+
+
diff --git a/near-rt-ric-simulator/simulator-group/ric/.gitignore b/near-rt-ric-simulator/simulator-group/ric/.gitignore
new file mode 100644 (file)
index 0000000..2eea525
--- /dev/null
@@ -0,0 +1 @@
+.env
\ No newline at end of file
index 1e40416..fcf3034 100644 (file)
@@ -1,8 +1,25 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
 import json
 import subprocess
 import os
 
-print("Clean old ric configurations in Consul config file")
+print(" Clean old ric configurations in Consul config file")
 
 p = os.path.abspath('..')
 consul_config = p + '/consul_cbs' + '/config.json'
@@ -19,6 +36,6 @@ with open(consul_config) as json_file:
 
 
 write_json(clean)
-print("Clean old ric configurations from Consul config file, done")
+print(" Clean old ric configurations from Consul config file, done")
 
 
index e45e0e4..17ef5aa 100644 (file)
@@ -1,12 +1,50 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+version: '3.0'
+
+# Compose file to bring up 3 groups of ric simulator containers with variable interface and count
+
 networks:
-  nonrtric-docker-net:
+  default:
     external:
-      name: nonrtric-docker-net
+      name: ${DOCKER_SIM_NWNAME}
 services:
-  ric-simulator:
-    image: ric-simulator:latest
+  g1:
+    image: ${RIC_SIM_IMAGE}
     networks:
-      nonrtric-docker-net: null
+      - default
     ports:
-    - 8085/tcp
-version: '3.0'
\ No newline at end of file
+      - ${RIC_SIM_INTERNAL_PORT}/tcp
+    environment:
+      - A1_VERSION=${G1_A1_VERSION}
+  g2:
+    image: ${RIC_SIM_IMAGE}
+    networks:
+      - default
+    ports:
+      - ${RIC_SIM_INTERNAL_PORT}/tcp
+    environment:
+      - A1_VERSION=${G2_A1_VERSION}
+  g3:
+    image: ${RIC_SIM_IMAGE}
+    networks:
+      - default
+    ports:
+      - ${RIC_SIM_INTERNAL_PORT}/tcp
+    environment:
+      - A1_VERSION=${G3_A1_VERSION}
\ No newline at end of file
index 5cb482b..fcb01e9 100644 (file)
@@ -1,8 +1,25 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
 import json
 import subprocess
 import os
 
-print("Update fresh ric configuration in Consul configuration file")
+print(" Update fresh ric configuration in Consul configuration file")
 
 p = os.path.abspath('..')
 consul_config = p + '/consul_cbs' + '/config.json'
@@ -40,4 +57,4 @@ with open(consul_config) as json_file:
 
 
 write_json(data)
-print("Update Consul config file with fresh ric configuration,  done")
+print(" Update Consul config file with fresh ric configuration,  done")
index c5007c8..85d88cd 100644 (file)
@@ -18,12 +18,12 @@ version: '2.1'
 networks:
   default:
     driver: bridge
-    name: nonrtric-docker-net
+    name: ${DOCKER_SIM_NWNAME}
 
 services:
   db:
-    image: mysql/mysql-server:5.6
-    container_name: sdnc_db_container
+    image: ${SDNC_DB_IMAGE}
+    container_name: ${SDNC_DB_APP_NAME}
     networks:
       - default
     ports:
@@ -38,15 +38,15 @@ services:
         max-file: "5"
 
   a1-controller:
-    image: nexus3.o-ran-sc.org:10002/o-ran-sc/nonrtric-a1-controller:1.7.4
+    image: ${SDNC_A1_CONTROLLER_IMAGE}
     depends_on :
       - db
-    container_name: a1-controller-container
+    container_name: ${SDNC_APP_NAME}
     networks:
       - default
     entrypoint: ["/opt/onap/sdnc/bin/startODL.sh"]
     ports:
-      - "8282:8181"
+      - ${SDNC_EXTERNAL_PORT}:${SDNC_INTERNAL_PORT}
     links:
       - db:dbhost
       - db:sdnctldb01
diff --git a/near-rt-ric-simulator/simulator-group/sim-monitor-start.sh b/near-rt-ric-simulator/simulator-group/sim-monitor-start.sh
new file mode 100755 (executable)
index 0000000..14316ca
--- /dev/null
@@ -0,0 +1,25 @@
+#/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+
+#Script to install dependencies and start the sim-monitor
+
+npm install express
+npm install json
+node sim-monitor
+
diff --git a/near-rt-ric-simulator/simulator-group/sim-monitor.js b/near-rt-ric-simulator/simulator-group/sim-monitor.js
new file mode 100644 (file)
index 0000000..da71a9e
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 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.
+#  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=================================================
+#
+*/
+
+// Sim mon server - query the agent and the simulators for counters and other data
+// Presents a web page on localhost:9999/mon
+
+var LOCALHOST="http://127.0.0.1:"
+var MRSTUB_PORT="3905"
+var AGENT_PORT="8081"
+var CR_PORT="8090"
+var http = require('http');
+
+var express = require('express');
+var app = express();
+var fieldSize=32;
+
+
+
+//I am alive
+app.get("/",function(req, res){
+       res.send("ok");
+})
+
+//Get parameter valuue from other server
+function getSimCtr(url, index, cb) {
+    var data = '';
+       http.get(url, (resp) => {
+               // A chunk of data has been recieved.
+               resp.on('data', (chunk) => {
+               data += chunk;
+               });
+
+               // The whole response has been received.
+               resp.on('end', () => {
+            var code=resp.statusCode
+            if (code > 199 && code < 300) {
+                cb(data, index);
+            } else {
+                cb("not found", index);
+            }
+               });
+
+       }).on("error", (err) => {
+               console.log("Error: " + err.message);
+               cb("no response", index);
+       });
+};
+
+
+//Format a comma separated list of data to a html-safe string with fixed fieldsizes
+function formatDataRow(commaList) {
+       var str = "";
+       var tmp=commaList.split(',');
+    for(var i=0;i<tmp.length;i++) {
+        var data=tmp[i];
+        var len = fieldSize-data.length;
+        while(len>0) {
+            data = data+"&nbsp;";
+            len--;
+        }
+        str=str+data+"&nbsp;&nbsp;&nbsp;";
+     }
+       return str;
+}
+
+//Format a comma separated list of ids to a html-safe string with fixed fieldsizes
+function formatIdRow(commaList) {
+       var str = "";
+       var tmp=commaList.split(',');
+    for(var i=0;i<tmp.length;i++) {
+       tmp[i] = tmp[i].trim();
+        var data="&lt"+tmp[i]+"&gt";
+        var len = fieldSize+4-data.length;
+        while(len>0) {
+            data = data+"&nbsp;";
+            len--;
+        }
+        str=str+data+"&nbsp;&nbsp;&nbsp;";
+    }
+       return str;
+}
+
+//Format a list of ids to a html-safe string in compact format
+function formatIdRowCompact(commaList) {
+    if (commaList == undefined) {
+        commaList= "";
+    }
+       var str = "";
+       var tmp=commaList.split(',');
+    for(var i=0;i<tmp.length;i++) {
+       tmp[i] = tmp[i].trim();
+        var data="&lt"+tmp[i]+"&gt";
+        str=str+data+"&nbsp;";
+    }
+       return str;
+}
+
+//Pad a string upto a certain size using a pad string
+function padding(val, fieldSize, pad) {
+       var s=""+val;
+       for(var i=s.length;i<fieldSize;i++) {
+               s=s+pad
+       }
+       return s;
+}
+
+//Status variables, for parameters values fetched from other simulators
+var mr1="", mr2="", mr3="", mr4="", mr5="", mr6="";
+
+//Status variables for agent
+var ag1=""
+var ag2=""
+var ag3=""
+var ag4=""
+
+//Status variables for callback receiver
+var cr1=""
+var cr2=""
+var cr3=""
+
+
+//Container names and ports of the ric simulator
+var simnames=[]
+var simports=[]
+
+//Status variables for each ric simulator
+var simvar1=[]
+var simvar2=[]
+var simvar3=[]
+var simvar4=[]
+
+//Counts the number of get request for the html page
+var getCtr=0
+
+var refreshInterval=2000
+
+function fetchAllMetrics() {
+    setTimeout(() => {
+
+        console.log("Fetching all metics data")
+        if (refreshInterval < 20000) {
+            refreshInterval+=100
+        }
+        if (getCtr%3 == 0) {
+            //Extract the port numbers from the running simulators, for every 3 calls
+            const { exec } = require('child_process');
+            exec('docker ps --filter "name=ricsim" --format "{{.Names}} {{.Ports}}" | sed s/0.0.0.0:// | cut -d \'>\' -f1 | sed \'s/[[-]]*$//\'', (err, stdout, stderr) => {
+
+                var simulators = ""
+                simulators=`${stdout}`.replace(/(\r\n|\n|\r)/gm," ");
+                simulators=simulators.trim();
+                var sims=simulators.split(" ")
+                simnames=[]
+                simports=[]
+                for(i=0;i<sims.length;i=i+2) {
+                    simnames[i/2]=sims[i]
+                    simports[i/2]=sims[i+1]
+                }
+            });
+        }
+        getCtr=getCtr+1
+
+        //Get metric values from the simulators
+        for(var index=0;index<simnames.length;index++) {
+            getSimCtr(LOCALHOST+simports[index]+"/counter/num_instances", index, function(data, index) {
+                simvar1[index] = data;
+            });
+            getSimCtr(LOCALHOST+simports[index]+"/counter/num_types", index, function(data,index) {
+                simvar2[index] = data;
+            });
+            getSimCtr(LOCALHOST+simports[index]+"/policytypes", index, function(data,index) {
+                data=data.replace(/\[/g,'');
+                data=data.replace(/\]/g,'');
+                data=data.replace(/ /g,'');
+                data=data.replace(/\"/g,'');
+                simvar3[index] = data;
+            });
+            getSimCtr(LOCALHOST+simports[index]+"/counter/interface", index, function(data,index) {
+                simvar4[index] = data;
+            });
+        }
+
+        //MR - get metrics values from the MR stub
+        getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/requests_submitted", 0, function(data, index) {
+            mr1 = data;
+        });
+        getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/requests_fetched", 0, function(data, index) {
+            mr2 = data;
+        });
+        getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/current_requests", 0, function(data, index) {
+            mr3 = data;
+        });
+        getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/responses_submitted", 0, function(data, index) {
+            mr4 = data;
+        });
+        getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/responses_fetched", 0, function(data, index) {
+            mr5 = data;
+        });
+        getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/current_responses", 0, function(data, index) {
+            mr6 = data;
+        });
+
+        //CR - get metrics values from the callbackreceiver
+        getSimCtr(LOCALHOST+CR_PORT+"/counter/received_callbacks", 0, function(data, index) {
+            cr1 = data;
+        });
+        getSimCtr(LOCALHOST+CR_PORT+"/counter/fetched_callbacks", 0, function(data, index) {
+            cr2 = data;
+        });
+        getSimCtr(LOCALHOST+CR_PORT+"/counter/current_messages", 0, function(data, index) {
+            cr3 = data;
+        });
+
+        //Agent - get metrics from the agent
+        getSimCtr(LOCALHOST+AGENT_PORT+"/status", 0, function(data, index) {
+            ag1 = data;
+        });
+        getSimCtr(LOCALHOST+AGENT_PORT+"/services", 0, function(data, index) {
+            ag2="";
+            try {
+                var jd=JSON.parse(data);
+                for(var key in jd) {
+                    if (ag2.length > 1) {
+                        ag2=ag2+", "
+                    }
+                    ag2=ag2+(jd[key]["serviceName"]).trim()
+                }
+            }
+            catch (err) {
+                ag2=data
+            }
+        });
+        getSimCtr(LOCALHOST+AGENT_PORT+"/policy_types", 0, function(data, index) {
+            ag3="";
+            try {
+                var jd=JSON.parse(data);
+                for(var key in jd) {
+                    if (ag3.length > 0) {
+                        ag3=ag3+", "
+                    }
+                    ag3=ag3+jd[key].trim()
+                }
+            }
+            catch (err) {
+                ag3=""
+            }
+        });
+        getSimCtr(LOCALHOST+AGENT_PORT+"/policy_ids", 0, function(data, index) {
+            ag4=""
+            try {
+                var jd=JSON.parse(data);
+                ag4=""+jd.length
+            }
+            catch (err) {
+                ag4=""
+            }
+        });
+
+
+
+        fetchAllMetrics();
+    }, refreshInterval)
+}
+
+fetchAllMetrics();
+
+setInterval(() => {
+    console.log("Setting interval "+refreshInterval+"ms")
+}, refreshInterval)
+
+app.get("/mon",function(req, res){
+
+
+    refreshInterval=2000
+
+  //Build web page
+       var htmlStr = "<!DOCTYPE html>" +
+          "<html>" +
+          "<head>" +
+            "<meta http-equiv=\"refresh\" content=\"2\">"+  //2 sec auto refresh
+            "<title>Policy Agent and simulator monitor</title>"+
+            "</head>" +
+            "<body>" +
+            "<h3>Policy agent</h3>" +
+            "<font face=\"monospace\">" +
+            "Status:..............................." + formatDataRow(ag1) + "<br>" +
+            "Services:............................." + formatIdRowCompact(ag2) + "<br>" +
+            "Types:................................" + formatIdRowCompact(ag3) + "<br>" +
+            "Number of instances:.................." + formatDataRow(ag4) + "<br>" +
+            "</font>" +
+            "<h3>MR Stub interface</h3>" +
+            "<font face=\"monospace\">"+
+            "Submitted requests:............................" + formatDataRow(mr1) + "<br>" +
+            "Fetched requests:.............................." + formatDataRow(mr2) + "<br>" +
+            "Current requests waiting:......................" + formatDataRow(mr3) + "<br>" +
+            "Submitted responses:..........................." + formatDataRow(mr4) + "<br>" +
+            "Fetched responses.............................." + formatDataRow(mr5) + "<br>" +
+            "Current responses waiting......................" + formatDataRow(mr6) + "<br>" +
+            "</font>"+
+            "<h3>Callback receiver</h3>" +
+            "<font face=\"monospace\">" +
+            "Callbacks received:..................." + formatDataRow(cr1) + "<br>" +
+            "Callbacks fetched:...................." + formatDataRow(cr2) + "<br>" +
+            "Number of waiting callback messages:.." + formatDataRow(cr3) + "<br>" +
+            "</font>" +
+            "<h3>Near-RT RIC Simulators</h3>" +
+            "<font face=\"monospace\">"
+
+            htmlStr=htmlStr+padding("Near-RT RIC Simulator name", 35,"&nbsp;")
+            htmlStr=htmlStr+padding("Types", 10,"&nbsp;")
+            htmlStr=htmlStr+padding("Instances", 10,"&nbsp;")
+            htmlStr=htmlStr+"<br>"+padding("",55,"=")+"<br>"
+
+            for(var simIndex=0;simIndex<simnames.length;simIndex++) {
+                htmlStr=htmlStr+padding(simnames[simIndex]+ " ("+simports[simIndex]+")",35,"&nbsp;");
+                htmlStr=htmlStr+padding(simvar2[simIndex],10,"&nbsp;")
+                htmlStr=htmlStr+padding(simvar1[simIndex],10,"&nbsp;")
+                htmlStr=htmlStr+"<br>";
+            }
+
+            htmlStr=htmlStr+"<br>";
+            htmlStr=htmlStr+padding("Near-RT RIC Simulator name", 35,"&nbsp;")
+            htmlStr=htmlStr+padding("Version", 20,"&nbsp;")
+            htmlStr=htmlStr+padding("Type-IDs", 10,"&nbsp;")+"<br>"
+            htmlStr=htmlStr+padding("",65,"=")+"<br>"
+            for(simIndex=0;simIndex<simnames.length;simIndex++) {
+                htmlStr=htmlStr+padding(simnames[simIndex]+ " ("+simports[simIndex]+")",35,"&nbsp;");
+                htmlStr=htmlStr+padding(simvar4[simIndex],20,"&nbsp;")
+                htmlStr=htmlStr+padding(formatIdRowCompact(simvar3[simIndex]),10,"&nbsp;")
+                htmlStr=htmlStr+"<br>";
+            }
+
+            htmlStr=htmlStr+
+           "</body>" +
+          "</html>";
+       res.send(htmlStr);
+})
+
+var httpServer = http.createServer(app);
+var httpPort=9999;
+httpServer.listen(httpPort);
+console.log("Simulator monitor listening (http) at "+httpPort);
+console.log("Open the web page on localhost:9999/mon to view the statistics page.")
\ No newline at end of file
diff --git a/near-rt-ric-simulator/simulator-group/simulators-start.sh b/near-rt-ric-simulator/simulator-group/simulators-start.sh
deleted file mode 100755 (executable)
index adcf621..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env bash
-
-DOCKER_SIM_NWNAME="nonrtric-docker-net"
-echo "Creating docker network $DOCKER_SIM_NWNAME, if needed"
-docker network ls| grep $DOCKER_SIM_NWNAME > /dev/null || docker network create $DOCKER_SIM_NWNAME
-docker-compose -f consul_cbs/docker-compose-template.yml config > docker-compose.yml
-
-docker-compose up -d
\ No newline at end of file