From 0aed8d1f322c36c4fc71b1be45bf9ee45870ab88 Mon Sep 17 00:00:00 2001 From: Stavros Charismiadis Date: Fri, 30 Jan 2026 10:51:19 +0200 Subject: [PATCH 1/3] use docker compose to deploy --- .gitignore | 1 + README.md | 15 +++++--- Dockerfile => app/Dockerfile | 0 app_template.py => app/app_template.py | 30 +++++++++++++--- .../invoker_sdk_config_template.json | 0 .../requirements_template.txt | 0 clean_files.sh | 3 -- docker-compose.yml | 13 +++++++ logs_invoker.sh | 33 +++++++++++++++++ start_invoker.sh | 27 +++++++------- stop_invoker.sh | 35 +++++++++++++++++++ 11 files changed, 130 insertions(+), 27 deletions(-) rename Dockerfile => app/Dockerfile (100%) rename app_template.py => app/app_template.py (75%) rename invoker_sdk_config_template.json => app/invoker_sdk_config_template.json (100%) rename requirements_template.txt => app/requirements_template.txt (100%) delete mode 100755 clean_files.sh create mode 100644 docker-compose.yml create mode 100755 logs_invoker.sh create mode 100755 stop_invoker.sh diff --git a/.gitignore b/.gitignore index 9e10135..89f7732 100644 --- a/.gitignore +++ b/.gitignore @@ -17,5 +17,6 @@ app.py invoker_sdk_config.json requirements.txt discoverer.pkl +invoker.pkl invoker_info/ logs/ \ No newline at end of file diff --git a/README.md b/README.md index fe6008d..9996610 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ A Postman collection is also provided, which can be imported directly to the Pos ## Getting started To start the service, follow the steps below +Inside the "app" folder ... 1. Copy requirements_template.txt to requirements.txt ``` @@ -51,11 +52,17 @@ To start the service, follow the steps below 6. To deploy the service, run the following commands in an Ubuntu or MacOS terminal. To stop the invoker just press Ctrl+C or Command+C ``` chmod +x start_invoker.sh - ./start_invoker.sh -u [-n ]" + ./start_invoker.sh -u ``` -7. To remove the files of the invoker instance (invoker_info, logs and pkl file), execute the following commands. +7. To see the logs, execute the following commands. ``` - chmod +x clean_files.sh - ./clean_files.sh + chmod +x logs_invoker.sh + ./logs_invoker.sh -u +``` + +8. To stop the invoker service and remove the files of the invoker instance (invoker_info, logs and pkl file), execute the following commands. +``` + chmod +x stop_invoker.sh + ./stop_invoker.sh -u ``` \ No newline at end of file diff --git a/Dockerfile b/app/Dockerfile similarity index 100% rename from Dockerfile rename to app/Dockerfile diff --git a/app_template.py b/app/app_template.py similarity index 75% rename from app_template.py rename to app/app_template.py index 0a6c407..6e24b17 100644 --- a/app_template.py +++ b/app/app_template.py @@ -36,6 +36,7 @@ def onboard(): def discover(): response_message = "Discover" ### Create the connection with CAPIF as an onboarded invoker + # service_discoverer = ... ### Discover APIs according to the filters @@ -60,11 +61,11 @@ def access_service(): # resource_name = request_data['resource_name'] # method = request_data['method'] - ### Uncomment, fill the ... with a preferred variable name and fetch the discoverer object + ### Uncomment to fetch the discoverer object # if not os.path.exists(OBJ_FILE): # return "No session found.", 404 # with open(OBJ_FILE, 'rb') as f: - # ... = pickle.load(f) + # service_discoverer = pickle.load(f) ### Fetch the necessary information of the targeted API and add to a url parameter # service_path = ... @@ -72,10 +73,11 @@ def access_service(): # service_interface = # url = ... - ### Get API token for the discovered API and add it to a header - # jwt_token = ... + ### Get API token for the discovered API + + ### Uncomment to add token to a header # headers = { - # 'Authorization': 'Bearer {}'.format(jwt_token) + # 'Authorization': 'Bearer {}'.format(...) # } ### Uncomment to make the request and return response text @@ -84,6 +86,24 @@ def access_service(): return response_message +@app.get("/offboard") +def offboard(): + response_message = "Offboard" + + ### Uncomment to fetch the invoker object + # if not os.path.exists(OBJ_FILE): + # return "No session found.", 404 + # with open(OBJ_FILE_INV, 'rb') as f: + # invoker = pickle.load(f) + + ### Offboard invoker + + ### Uncomment to check if invoker was successfully offboarded + # if not os.path.exists("./invoker_info/{}".format(user_name)): + # response_message = "Invoker offboarded successfully" + + return response_message + if __name__ == "__main__": port = int(os.getenv("PORT", 8001)) app.run(host='0.0.0.0', port=port, debug=True) \ No newline at end of file diff --git a/invoker_sdk_config_template.json b/app/invoker_sdk_config_template.json similarity index 100% rename from invoker_sdk_config_template.json rename to app/invoker_sdk_config_template.json diff --git a/requirements_template.txt b/app/requirements_template.txt similarity index 100% rename from requirements_template.txt rename to app/requirements_template.txt diff --git a/clean_files.sh b/clean_files.sh deleted file mode 100755 index 49030dd..0000000 --- a/clean_files.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -sudo rm -R invoker_info logs discoverer.pkl \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e6cf410 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +name: invoker +services: + application: + image: invoker-service + build: + context: ./app + restart: unless-stopped + ports: + - 8001:8001 + environment: + - USER_NAME=${USER_NAME} + volumes: + - ./app:/app diff --git a/logs_invoker.sh b/logs_invoker.sh new file mode 100755 index 0000000..ccfc6c8 --- /dev/null +++ b/logs_invoker.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +help() { + echo "Usage: $1 " + echo " -u : Provide the username given by the organizers" + echo " -h : show this help" + exit 1 +} + +# Read params +while getopts "u:" opt; do + case $opt in + u) + USER_NAME="$OPTARG" + ;; + \?) + echo "Invalid option" + exit 1 + ;; + esac +done + +# Mandatory Check +# -z checks if the string is empty +if [[ -z "$USER_NAME" ]]; then + echo "Error: The -u [user_name] argument is mandatory." + echo "Usage: $0 -u " + exit 1 +fi + +echo "Logs of invoker service for user: $USER_NAME" + +USER_NAME=$USER_NAME docker compose logs -f \ No newline at end of file diff --git a/start_invoker.sh b/start_invoker.sh index b6c33e1..8500219 100755 --- a/start_invoker.sh +++ b/start_invoker.sh @@ -1,22 +1,17 @@ #!/bin/bash USER_NAME="" -ADD_HOST_FLAG="" help() { echo "Usage: $1 " - echo " -n : Setup host record inside container for the CCF (used when CAPIF is deployed locally)" echo " -u : Provide the username given by the organizers" echo " -h : show this help" exit 1 } # Read params -while getopts "n:u:" opt; do +while getopts "u:" opt; do case $opt in - n) - ADD_HOST_FLAG="--add-host $OPTARG" - ;; u) USER_NAME="$OPTARG" ;; @@ -31,18 +26,20 @@ done # -z checks if the string is empty if [[ -z "$USER_NAME" ]]; then echo "Error: The -u [user_name] argument is mandatory." - echo "Usage: $0 -u [-n ]" + echo "Usage: $0 -u " exit 1 fi echo "Create invoker service for user: $USER_NAME" -docker build -t invoker-service . +USER_NAME=$USER_NAME docker compose up --detach --build --force-recreate -docker run -it --rm \ - -p 8001:8001 \ - -e USER_NAME=$USER_NAME \ - -v "$(pwd):/app" \ - --name invoker \ - $ADD_HOST_FLAG \ - invoker-service +#docker build -t invoker-service . +# +#docker run -it --rm \ +# -p 8001:8001 \ +# -e USER_NAME=$USER_NAME \ +# -v "$(pwd):/app" \ +# --name invoker \ +# $ADD_HOST_FLAG \ +# invoker-service diff --git a/stop_invoker.sh b/stop_invoker.sh new file mode 100755 index 0000000..d963742 --- /dev/null +++ b/stop_invoker.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +help() { + echo "Usage: $1 " + echo " -u : Provide the username given by the organizers" + echo " -h : show this help" + exit 1 +} + +# Read params +while getopts "u:" opt; do + case $opt in + u) + USER_NAME="$OPTARG" + ;; + \?) + echo "Invalid option" + exit 1 + ;; + esac +done + +# Mandatory Check +# -z checks if the string is empty +if [[ -z "$USER_NAME" ]]; then + echo "Error: The -u [user_name] argument is mandatory." + echo "Usage: $0 -u " + exit 1 +fi + +echo "Stop invoker service for user: $USER_NAME" + +USER_NAME=$USER_NAME docker compose down + +sudo rm -R ./app/invoker_info ./app/logs ./app/discoverer.pkl \ No newline at end of file -- GitLab From f229e202b7cd3c72953686aea6421a4daeae6a86 Mon Sep 17 00:00:00 2001 From: Stavros Charismiadis Date: Fri, 30 Jan 2026 13:31:53 +0200 Subject: [PATCH 2/3] Add all the tutorial code in the template --- app/app_template.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/app/app_template.py b/app/app_template.py index 6e24b17..c86b6e1 100644 --- a/app/app_template.py +++ b/app/app_template.py @@ -3,7 +3,8 @@ import json import pickle import requests from flask import Flask, jsonify, request -# import OpenCAPIF SDK +### Import OpenCAPIF SDK package +# import opencapif_sdk app = Flask(__name__) OBJ_FILE = "discoverer.pkl" @@ -16,18 +17,21 @@ user_name = os.getenv("USER_NAME", "test") def onboard(): response_message = "Onboard" ### Create the connection with CAPIF and set the invoker's config file + # invoker = opencapif_sdk.capif_invoker_connector(config_file="invoker_sdk_config.json") ### Onboard the invoker + # invoker.onboard_invoker() - ### Uncomment to print the Invoker ID + ### Uncomment to get the Invoker ID # with open("./invoker_info/{0}/capif_api_security_context_details-{0}.json".format(user_name), "rb") as f: # d = json.load(f) + # invoker_id = d['api_invoker_id'] - ### Uncomment, fill the ... with the object and store invoker object + ### Uncomment to store invoker object # with open(OBJ_FILE_INV, 'wb') as f: # pickle.dump(invoker, f) - # response_message = "Invoker onboarded with ID: {}".format(d['api_invoker_id']) + # response_message = "Invoker onboarded with ID: {}".format(d['invoker_id']) return response_message @@ -36,13 +40,14 @@ def onboard(): def discover(): response_message = "Discover" ### Create the connection with CAPIF as an onboarded invoker - # service_discoverer = ... + # service_discoverer = opencapif_sdk.service_discoverer(config_file="invoker_sdk_config.json") ### Discover APIs according to the filters + # service_discoverer.discover() - ### Uncomment, fill the ... with the object and store discoverer object + ### Uncomment to store discoverer object # with open(OBJ_FILE, 'wb') as f: - # pickle.dump( ... , f) + # pickle.dump( service_discoverer , f) ### Uncomment to read and return the discovered API # with open("./invoker_info/{0}/capif_api_security_context_details-{0}.json".format(user_name), "rb") as f: @@ -68,16 +73,18 @@ def access_service(): # service_discoverer = pickle.load(f) ### Fetch the necessary information of the targeted API and add to a url parameter - # service_path = ... - # api_details = ... - # service_interface = - # url = ... + # service_path = service_discoverer.retrieve_specific_resource_name(api_name, resource_name).split("/")[-1] + # api_details = service_discoverer.retrieve_api_description_by_name(api_name) + # service_interface = api_details["aefProfiles"][0]['interfaceDescriptions'][0] + # url = "http://{}:{}/{}".format(service_interface['ipv4Addr'], service_interface['port'], service_path) ### Get API token for the discovered API + # service_discoverer.get_tokens() + # jwt_token = service_discoverer.token ### Uncomment to add token to a header # headers = { - # 'Authorization': 'Bearer {}'.format(...) + # 'Authorization': 'Bearer {}'.format(jwt_token) # } ### Uncomment to make the request and return response text @@ -97,6 +104,7 @@ def offboard(): # invoker = pickle.load(f) ### Offboard invoker + # invoker.offboard_invoker() ### Uncomment to check if invoker was successfully offboarded # if not os.path.exists("./invoker_info/{}".format(user_name)): -- GitLab From 7be2274ec5a09ce9d41bddb2b5282407533c0e90 Mon Sep 17 00:00:00 2001 From: Stavros Charismiadis Date: Fri, 30 Jan 2026 14:16:40 +0200 Subject: [PATCH 3/3] minor fixes --- README.md | 7 +++---- app/app_template.py | 2 +- stop_invoker.sh | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9996610..c8cc4be 100644 --- a/README.md +++ b/README.md @@ -26,21 +26,20 @@ A Postman collection is also provided, which can be imported directly to the Pos ## Getting started To start the service, follow the steps below -Inside the "app" folder ... 1. Copy requirements_template.txt to requirements.txt ``` - cp requirements_template.txt requirements.txt + cp ./app/requirements_template.txt ./app/requirements.txt ``` 2. Copy app_template.py to app.py ``` - cp app_template.py app.py + cp ./app/app_template.py ./app/app.py ``` 3. Copy invoker_sdk_config_template.json to invoker_sdk_config.json ``` - cp invoker_sdk_config_template.json invoker_sdk_config.json + cp ./app/invoker_sdk_config_template.json ./app/invoker_sdk_config.json ``` 4. Add opencapif_sdk in requirements.txt diff --git a/app/app_template.py b/app/app_template.py index c86b6e1..87cb0a8 100644 --- a/app/app_template.py +++ b/app/app_template.py @@ -31,7 +31,7 @@ def onboard(): # with open(OBJ_FILE_INV, 'wb') as f: # pickle.dump(invoker, f) - # response_message = "Invoker onboarded with ID: {}".format(d['invoker_id']) + # response_message = "Invoker onboarded with ID: {}".format(invoker_id) return response_message diff --git a/stop_invoker.sh b/stop_invoker.sh index d963742..ccf5406 100755 --- a/stop_invoker.sh +++ b/stop_invoker.sh @@ -32,4 +32,4 @@ echo "Stop invoker service for user: $USER_NAME" USER_NAME=$USER_NAME docker compose down -sudo rm -R ./app/invoker_info ./app/logs ./app/discoverer.pkl \ No newline at end of file +sudo rm -R ./app/invoker_info ./app/logs ./app/discoverer.pkl ./app/invoker.pkl \ No newline at end of file -- GitLab