From aa2a3c646f4f5600d43c5d2cb70b449d9be76912 Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Wed, 15 May 2024 15:28:28 +0300 Subject: [PATCH 01/15] Move Register service to Gunicorn production server --- services/register/register_prepare.sh | 6 ++++-- .../register_service/{__main__.py => app.py} | 19 ++++++------------- services/register/register_service/config.py | 2 +- .../controllers/register_controller.py | 4 ++-- .../core/register_operations.py | 4 ++-- services/register/register_service/wsgi.py | 4 ++++ services/register/requirements.txt | 2 ++ 7 files changed, 21 insertions(+), 20 deletions(-) rename services/register/register_service/{__main__.py => app.py} (79%) create mode 100644 services/register/register_service/wsgi.py diff --git a/services/register/register_prepare.sh b/services/register/register_prepare.sh index 4a49b87..2ae8def 100644 --- a/services/register/register_prepare.sh +++ b/services/register/register_prepare.sh @@ -40,5 +40,7 @@ __EOF__ openssl x509 -req -in /usr/src/app/register_service/certs/register.csr -CA /usr/src/app/register_service/certs/registerCA.crt -CAkey /usr/src/app/register_service/certs/registerCA.key -CAcreateserial -out /usr/src/app/register_service/certs/register_cert.crt -days 365 -sha256 -cd /usr/src/app/ -python3 -m register_service \ No newline at end of file +gunicorn --certfile=/usr/src/app/register_service/certs/register_cert.crt \ + --keyfile=/usr/src/app/register_service/certs/register_key.key \ + --bind 0.0.0.0:8080 \ + --chdir /usr/src/app/register_service wsgi:app \ No newline at end of file diff --git a/services/register/register_service/__main__.py b/services/register/register_service/app.py similarity index 79% rename from services/register/register_service/__main__.py rename to services/register/register_service/app.py index 12f6ffd..c92f175 100644 --- a/services/register/register_service/__main__.py +++ b/services/register/register_service/app.py @@ -1,13 +1,13 @@ import os from flask import Flask -from .controllers.register_controller import register_routes +from controllers.register_controller import register_routes from flask_jwt_extended import JWTManager from OpenSSL.crypto import PKey, TYPE_RSA, X509Req, dump_certificate_request, FILETYPE_PEM, dump_privatekey import requests import json import jwt -from .config import Config +from config import Config app = Flask(__name__) @@ -32,7 +32,7 @@ csr_request = dump_certificate_request(FILETYPE_PEM, req) private_key = dump_privatekey(FILETYPE_PEM, key) # Save superadmin private key -key_file = open("register_service/certs/superadmin.key", 'wb+') +key_file = open("certs/superadmin.key", 'wb+') key_file.write(bytes(private_key)) key_file.close() @@ -50,7 +50,7 @@ response = requests.request("POST", url, headers=headers, data=data, verify = Fa superadmin_cert = json.loads(response.text)['data']['certificate'] # Save the superadmin certificate -cert_file = open("register_service/certs/superadmin.crt", 'wb') +cert_file = open("certs/superadmin.crt", 'wb') cert_file.write(bytes(superadmin_cert, 'utf-8')) cert_file.close() @@ -62,7 +62,7 @@ headers = { response = requests.request("GET", url, headers=headers, verify = False) ca_root = json.loads(response.text)['data']['data']['ca'] -cert_file = open("register_service/certs/ca_root.crt", 'wb') +cert_file = open("certs/ca_root.crt", 'wb') cert_file.write(bytes(ca_root, 'utf-8')) cert_file.close() @@ -78,11 +78,4 @@ app.config['JWT_ALGORITHM'] = 'RS256' app.config['JWT_PRIVATE_KEY'] = key_data app.config['REGISTRE_SECRET_KEY'] = config["register"]["register_uuid"] -app.register_blueprint(register_routes) - -#---------------------------------------- -# launch -#---------------------------------------- - -if __name__ == "__main__": - app.run(debug=True, host = '0.0.0.0', port=8080, ssl_context= ("/usr/src/app/register_service/certs/register_cert.crt", "/usr/src/app/register_service/certs/register_key.key")) +app.register_blueprint(register_routes) \ No newline at end of file diff --git a/services/register/register_service/config.py b/services/register/register_service/config.py index d04bd1a..97ab831 100644 --- a/services/register/register_service/config.py +++ b/services/register/register_service/config.py @@ -5,7 +5,7 @@ import os class Config: def __init__(self): self.cached = 0 - self.file="./config.yaml" + self.file="../config.yaml" self.my_config = {} stamp = os.stat(self.file).st_mtime diff --git a/services/register/register_service/controllers/register_controller.py b/services/register/register_service/controllers/register_controller.py index 14877f8..fe51f4f 100644 --- a/services/register/register_service/controllers/register_controller.py +++ b/services/register/register_service/controllers/register_controller.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 from flask import current_app, Flask, jsonify, request, Blueprint -from ..core.register_operations import RegisterOperations -from ..config import Config +from register_service.core.register_operations import RegisterOperations +from register_service.config import Config from functools import wraps from datetime import datetime, timedelta diff --git a/services/register/register_service/core/register_operations.py b/services/register/register_service/core/register_operations.py index a8fee91..3771dfc 100644 --- a/services/register/register_service/core/register_operations.py +++ b/services/register/register_service/core/register_operations.py @@ -37,11 +37,11 @@ class RegisterOperations: exist_user = mycol.find_one({"username": username}) if exist_user is None: - return jsonify("Not exister user with this credentials"), 400 + return jsonify("Not existing user with this credentials"), 400 access_token = create_access_token(identity=(username + " " + exist_user["uuid"])) - cert_file = open("register_service/certs/ca_root.crt", 'rb') + cert_file = open("certs/ca_root.crt", 'rb') ca_root = cert_file.read() cert_file.close() diff --git a/services/register/register_service/wsgi.py b/services/register/register_service/wsgi.py new file mode 100644 index 0000000..6026b0f --- /dev/null +++ b/services/register/register_service/wsgi.py @@ -0,0 +1,4 @@ +from app import app + +if __name__ == "__main__": + app.run() diff --git a/services/register/requirements.txt b/services/register/requirements.txt index c5446a6..8da8ad4 100644 --- a/services/register/requirements.txt +++ b/services/register/requirements.txt @@ -2,6 +2,8 @@ python_dateutil >= 2.6.0 setuptools >= 21.0.0 Flask >= 2.0.3 pymongo == 4.0.1 +gunicorn==22.0.0 +packaging==24.0 flask_jwt_extended pyopenssl pyyaml -- GitLab From b4c3c202443d1299827735681740764fe7f1336c Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Thu, 16 May 2024 15:12:02 +0300 Subject: [PATCH 02/15] Fix register issue and deploy Onboard_Provider service in production server --- .../{__main__.py => app.py} | 41 ++++++++++--------- .../api_provider_management/config.py | 2 +- .../controllers/default_controller.py | 12 +++--- ...i_provider_enrolment_details_controller.py | 9 ++-- .../core/provider_enrolment_details_api.py | 5 ++- .../api_provider_management/encoder.py | 3 +- .../api_provider_management/util.py | 2 +- .../api_provider_management/wsgi.py | 4 ++ .../prepare_provider.sh | 4 +- .../requirements.txt | 3 +- .../controllers/register_controller.py | 6 ++- .../core/register_operations.py | 4 +- services/register/register_service/db/db.py | 2 +- 13 files changed, 54 insertions(+), 43 deletions(-) rename services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/{__main__.py => app.py} (82%) create mode 100644 services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/wsgi.py diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/__main__.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/app.py similarity index 82% rename from services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/__main__.py rename to services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/app.py index f52d69c..4caa391 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/__main__.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/app.py @@ -3,10 +3,10 @@ import connexion import logging -from api_provider_management import encoder +import encoder from flask_jwt_extended import JWTManager from logging.handlers import RotatingFileHandler -from .config import Config +from config import Config import os import sys from fluent import sender @@ -106,31 +106,32 @@ def verbose_formatter(): datefmt='%d/%m/%Y %H:%M:%S' ) -def main(): +# def main(): - with open("/usr/src/app/api_provider_management/pubkey.pem", "rb") as pub_file: - pub_data = pub_file.read() - app = connexion.App(__name__, specification_dir='./openapi/') - app.app.json_encoder = encoder.JSONEncoder - app.add_api('openapi.yaml', - arguments={'title': 'CAPIF_API_Provider_Management_API'}, - pythonic_params=True) +with open("/usr/src/app/api_provider_management/pubkey.pem", "rb") as pub_file: + pub_data = pub_file.read() - config = Config() - configure_logging(app.app) +app = connexion.App(__name__, specification_dir='./openapi/') +app.app.json_encoder = encoder.JSONEncoder +app.add_api('openapi.yaml', + arguments={'title': 'CAPIF_API_Provider_Management_API'}, + pythonic_params=True) - if eval(os.environ.get("MONITORING").lower().capitalize()): - configure_monitoring(app.app, config.get_config()) +config = Config() +configure_logging(app.app) - app.app.config['JWT_ALGORITHM'] = 'RS256' - app.app.config['JWT_PUBLIC_KEY'] = pub_data +if eval(os.environ.get("MONITORING").lower().capitalize()): + configure_monitoring(app.app, config.get_config()) - JWTManager(app.app) +app.app.config['JWT_ALGORITHM'] = 'RS256' +app.app.config['JWT_PUBLIC_KEY'] = pub_data +JWTManager(app.app) - app.run(port=8080, debug=True) +# app.run(port=8080, debug=True) -if __name__ == '__main__': - main() + +# if __name__ == '__main__': +# main() diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/config.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/config.py index 377b14f..bed212a 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/config.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/config.py @@ -5,7 +5,7 @@ import os class Config: def __init__(self): self.cached = 0 - self.file="./config.yaml" + self.file="../config.yaml" self.my_config = {} stamp = os.stat(self.file).st_mtime if stamp != self.cached: diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/default_controller.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/default_controller.py index f5bcf16..50745b8 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/default_controller.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/default_controller.py @@ -3,17 +3,19 @@ import six import json from flask import Response, request, current_app + from ..core.provider_enrolment_details_api import ProviderManagementOperations -from ..encoder import JSONEncoder -from api_provider_management.models.api_provider_enrolment_details import APIProviderEnrolmentDetails # noqa: E501 -from api_provider_management.models.problem_details import ProblemDetails # noqa: E501 -from api_provider_management import util +from ..models.api_provider_enrolment_details import APIProviderEnrolmentDetails # noqa: E501 +from ..models.problem_details import ProblemDetails # noqa: E501 +from .. import util +from ..core.validate_user import ControlAccess + from cryptography import x509 from cryptography.hazmat.backends import default_backend from flask_jwt_extended import jwt_required, get_jwt_identity from cryptography import x509 from functools import wraps -from ..core.validate_user import ControlAccess + import sys diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/individual_api_provider_enrolment_details_controller.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/individual_api_provider_enrolment_details_controller.py index dde822b..50ccf0e 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/individual_api_provider_enrolment_details_controller.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/individual_api_provider_enrolment_details_controller.py @@ -6,10 +6,11 @@ import json from flask import Response, request, current_app from ..core.provider_enrolment_details_api import ProviderManagementOperations from ..encoder import JSONEncoder -from api_provider_management.models.api_provider_enrolment_details import APIProviderEnrolmentDetails # noqa: E501 -from api_provider_management.models.api_provider_enrolment_details_patch import APIProviderEnrolmentDetailsPatch # noqa: E501 -from api_provider_management.models.problem_details import ProblemDetails # noqa: E501 -from api_provider_management import util +from ..models.api_provider_enrolment_details import APIProviderEnrolmentDetails # noqa: E501 +from ..models.api_provider_enrolment_details_patch import APIProviderEnrolmentDetailsPatch # noqa: E501 +from ..models.problem_details import ProblemDetails # noqa: E501 +from .. import util + from cryptography.hazmat.backends import default_backend from cryptography import x509 diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py index 6ba9043..c58f629 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py @@ -45,7 +45,7 @@ class ProviderManagementOperations(Resource): api_provider_enrolment_details.api_prov_dom_id = secrets.token_hex(15) - current_app.logger.debug("Geretaing certs to api prov funcs") + current_app.logger.debug("Generating certs to api prov funcs") for api_provider_func in api_provider_enrolment_details.api_prov_funcs: api_provider_func.api_prov_func_id = api_provider_func.api_prov_func_role + str(secrets.token_hex(15)) @@ -64,7 +64,8 @@ class ProviderManagementOperations(Resource): current_app.logger.debug("Provider inserted in database") - res = make_response(object=api_provider_enrolment_details, status=201) + res = make_response(object=dict_to_camel_case(api_provider_enrolment_details.to_dict()), status=201) + res.headers['Location'] = "/api-provider-management/v1/registrations/" + str(api_provider_enrolment_details.api_prov_dom_id) return res diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/encoder.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/encoder.py index 01531f2..3f1c01c 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/encoder.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/encoder.py @@ -1,8 +1,7 @@ from connexion.apps.flask_app import FlaskJSONEncoder import six -from api_provider_management.models.base_model_ import Model - +from models.base_model_ import Model class JSONEncoder(FlaskJSONEncoder): include_nulls = False diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/util.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/util.py index e769d28..5ff8054 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/util.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/util.py @@ -2,7 +2,7 @@ import datetime import six import typing -from api_provider_management import typing_utils +import typing_utils def clean_empty(d): if isinstance(d, dict): diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/wsgi.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/wsgi.py new file mode 100644 index 0000000..6026b0f --- /dev/null +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/wsgi.py @@ -0,0 +1,4 @@ +from app import app + +if __name__ == "__main__": + app.run() diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/prepare_provider.sh b/services/TS29222_CAPIF_API_Provider_Management_API/prepare_provider.sh index 93bf420..5ec3096 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/prepare_provider.sh +++ b/services/TS29222_CAPIF_API_Provider_Management_API/prepare_provider.sh @@ -13,7 +13,7 @@ curl -vv -k -retry 30 \ --request GET "$VAULT_ADDR/v1/secret/data/server_cert/pub" 2>/dev/null | jq -r '.data.data.pub_key' -j > /usr/src/app/api_provider_management/pubkey.pem +gunicorn --bind 0.0.0.0:8080 \ + --chdir /usr/src/app/api_provider_management wsgi:app -cd /usr/src/app/ -python3 -m api_provider_management diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/requirements.txt b/services/TS29222_CAPIF_API_Provider_Management_API/requirements.txt index d45d1e5..c93b338 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/requirements.txt +++ b/services/TS29222_CAPIF_API_Provider_Management_API/requirements.txt @@ -18,4 +18,5 @@ fluent-logger == 0.10.0 opentelemetry-api == 1.17.0 opentelemetry-sdk == 1.17.0 flask_executor == 1.0.0 - +gunicorn==22.0.0 +packaging==24.0 \ No newline at end of file diff --git a/services/register/register_service/controllers/register_controller.py b/services/register/register_service/controllers/register_controller.py index fe51f4f..58620ba 100644 --- a/services/register/register_service/controllers/register_controller.py +++ b/services/register/register_service/controllers/register_controller.py @@ -1,8 +1,10 @@ #!/usr/bin/env python3 from flask import current_app, Flask, jsonify, request, Blueprint -from register_service.core.register_operations import RegisterOperations -from register_service.config import Config + +from core.register_operations import RegisterOperations +from config import Config + from functools import wraps from datetime import datetime, timedelta diff --git a/services/register/register_service/core/register_operations.py b/services/register/register_service/core/register_operations.py index 3771dfc..53f9806 100644 --- a/services/register/register_service/core/register_operations.py +++ b/services/register/register_service/core/register_operations.py @@ -1,8 +1,8 @@ from flask import Flask, jsonify, request, Response from flask_jwt_extended import create_access_token -from ..db.db import MongoDatabse +from db.db import MongoDatabse from datetime import datetime -from ..config import Config +from config import Config import base64 import uuid diff --git a/services/register/register_service/db/db.py b/services/register/register_service/db/db.py index 0b08933..3f73712 100644 --- a/services/register/register_service/db/db.py +++ b/services/register/register_service/db/db.py @@ -2,7 +2,7 @@ import atexit import time from pymongo import MongoClient from pymongo.errors import AutoReconnect -from ..config import Config +from config import Config from bson.codec_options import CodecOptions -- GitLab From 35846b0133d1ffe44a1f7bda166fbd36fbe3b54c Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Wed, 22 May 2024 11:34:57 +0300 Subject: [PATCH 03/15] Change ProblemDetails initialization to properly be serialized --- .../core/provider_enrolment_details_api.py | 12 +++++---- .../api_provider_management/core/responses.py | 26 +++++++++++++------ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py index c58f629..67229fa 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py @@ -124,13 +124,12 @@ class ProviderManagementOperations(Resource): for api_func in api_prov_funcs: if func.api_prov_func_id == api_func["api_prov_func_id"]: if func.api_prov_func_role != api_func["api_prov_func_role"]: - return bad_request_error(detail="Bad Role in provider", cause="Different role in update reqeuest", invalid_params=[{"param":"api_prov_func_role","reason":"differente role with same id"}]) + return bad_request_error(detail="Bad Role in provider", cause="Different role in update reqeuest", invalid_params=[{"param":"api_prov_func_role","reason":"different role with same id"}]) if func.reg_info.api_prov_pub_key != api_func["reg_info"]["api_prov_pub_key"]: certificate = sign_certificate(func.reg_info.api_prov_pub_key, api_func["api_prov_func_id"]) func.reg_info.api_prov_cert = certificate self.auth_manager.update_auth_provider(certificate, func.api_prov_func_id, api_prov_dom_id, func.api_prov_func_role) - api_provider_enrolment_details = api_provider_enrolment_details.to_dict() api_provider_enrolment_details = clean_empty(api_provider_enrolment_details) @@ -139,7 +138,9 @@ class ProviderManagementOperations(Resource): result = clean_empty(result) current_app.logger.debug("Provider domain updated in database") - return make_response(object=APIProviderEnrolmentDetails().from_dict(dict_to_camel_case(result)), status=200) + provider_updated = APIProviderEnrolmentDetails().from_dict(dict_to_camel_case(result)) + # return make_response(object=APIProviderEnrolmentDetails().from_dict(dict_to_camel_case(result)), status=200) + return make_response(object=dict_to_camel_case(provider_updated.to_dict()), status=200) except Exception as e: exception = "An exception occurred in update provider" @@ -164,8 +165,9 @@ class ProviderManagementOperations(Resource): result = clean_empty(result) current_app.logger.debug("Provider domain updated in database") - - return make_response(object=APIProviderEnrolmentDetails().from_dict(dict_to_camel_case(result)), status=200) + provider_updated = APIProviderEnrolmentDetails().from_dict(dict_to_camel_case(result)) + # return make_response(object=APIProviderEnrolmentDetails().from_dict(dict_to_camel_case(result)), status=200) + return make_response(object=dict_to_camel_case(provider_updated.to_dict()), status=200) except Exception as e: exception = "An exception occurred in patch provider" diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/responses.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/responses.py index 962c4b6..6bee6ec 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/responses.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/responses.py @@ -1,31 +1,41 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder +from ..util import dict_to_camel_case from flask import Response import json mimetype = "application/json" + def make_response(object, status): res = Response(json.dumps(object, cls=JSONEncoder), status=status, mimetype=mimetype) return res + def internal_server_error(detail, cause): - prob = ProblemDetails(title="Internal Server Error", status=500, detail=detail, cause=cause) + prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Internal Server Error", status=500, detail=detail, cause=cause, invalid_params=[{"param":"","reason":""}], supported_features="fffff") + # BEFORE: prob = ProblemDetails(title="Internal Server Error", status=500, detail=detail, cause=cause) + + return Response(json.dumps(dict_to_camel_case(prob.to_dict()), cls=JSONEncoder), status=500, mimetype=mimetype) - return Response(json.dumps(prob, cls=JSONEncoder), status=500, mimetype=mimetype) def forbidden_error(detail, cause): - prob = ProblemDetails(title="Forbidden", status=403, detail=detail, cause=cause) + prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Forbidden", status=403, detail=detail, cause=cause, invalid_params=[{"param":"","reason":""}], supported_features="fffff") + # BEFORE: prob = ProblemDetails(title="Forbidden", status=403, detail=detail, cause=cause) + + return Response(json.dumps(dict_to_camel_case(prob.to_dict()), cls=JSONEncoder), status=403, mimetype=mimetype) - return Response(json.dumps(prob, cls=JSONEncoder), status=403, mimetype=mimetype) def bad_request_error(detail, cause, invalid_params): - prob = ProblemDetails(title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params) + prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params, supported_features="fffff") + # BEFORE: prob = ProblemDetails(title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params) + + return Response(json.dumps(dict_to_camel_case(prob.to_dict()), cls=JSONEncoder), status=400, mimetype=cause) - return Response(json.dumps(prob, cls=JSONEncoder), status=400, mimetype=cause) def not_found_error(detail, cause): - prob = ProblemDetails(title="Not Found", status=404, detail=detail, cause=cause) + prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Not Found", status=404, detail=detail, cause=cause, invalid_params=[{"param":"","reason":""}], supported_features="fffff") + # BEFORE: prob = ProblemDetails(title="Not Found", status=404, detail=detail, cause=cause) - return Response(json.dumps(prob, cls=JSONEncoder), status=404, mimetype=mimetype) \ No newline at end of file + return Response(json.dumps(dict_to_camel_case(prob.to_dict()), cls=JSONEncoder), status=404, mimetype=mimetype) \ No newline at end of file -- GitLab From da2838818d6bd310799e6ca6fe9086edd5e23b93 Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Wed, 22 May 2024 14:39:21 +0300 Subject: [PATCH 04/15] improve error function responses --- .../core/provider_enrolment_details_api.py | 1 - .../api_provider_management/core/responses.py | 40 ++++++++++++------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py index 67229fa..976cb32 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py @@ -134,7 +134,6 @@ class ProviderManagementOperations(Resource): api_provider_enrolment_details = clean_empty(api_provider_enrolment_details) result = mycol.find_one_and_update(result, {"$set":api_provider_enrolment_details}, projection={'_id': 0},return_document=ReturnDocument.AFTER ,upsert=False) - result = clean_empty(result) current_app.logger.debug("Provider domain updated in database") diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/responses.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/responses.py index 6bee6ec..f047297 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/responses.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/responses.py @@ -1,7 +1,7 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder -from ..util import dict_to_camel_case -from flask import Response +from ..util import dict_to_camel_case, clean_empty +from flask import Response, current_app import json mimetype = "application/json" @@ -14,28 +14,40 @@ def make_response(object, status): def internal_server_error(detail, cause): - prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Internal Server Error", status=500, detail=detail, cause=cause, invalid_params=[{"param":"","reason":""}], supported_features="fffff") - # BEFORE: prob = ProblemDetails(title="Internal Server Error", status=500, detail=detail, cause=cause) + # prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Internal Server Error", status=500, detail=detail, cause=cause, invalid_params=[{"param":"","reason":""}], supported_features="fffff") + prob = ProblemDetails(title="Internal Server Error", status=500, detail=detail, cause=cause) - return Response(json.dumps(dict_to_camel_case(prob.to_dict()), cls=JSONEncoder), status=500, mimetype=mimetype) + prob = prob.to_dict() + prob = clean_empty(prob) + + return Response(json.dumps(dict_to_camel_case(prob), cls=JSONEncoder), status=500, mimetype=mimetype) def forbidden_error(detail, cause): - prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Forbidden", status=403, detail=detail, cause=cause, invalid_params=[{"param":"","reason":""}], supported_features="fffff") - # BEFORE: prob = ProblemDetails(title="Forbidden", status=403, detail=detail, cause=cause) + prob = ProblemDetails(title="Forbidden", status=403, detail=detail, cause=cause) + + prob = prob.to_dict() + prob = clean_empty(prob) - return Response(json.dumps(dict_to_camel_case(prob.to_dict()), cls=JSONEncoder), status=403, mimetype=mimetype) + # return Response(json.dumps(dict_to_camel_case(prob.to_dict()), cls=JSONEncoder), status=403, mimetype=mimetype) + return Response(json.dumps(dict_to_camel_case(prob), cls=JSONEncoder), status=403, mimetype=mimetype) def bad_request_error(detail, cause, invalid_params): - prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params, supported_features="fffff") - # BEFORE: prob = ProblemDetails(title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params) + # prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params, supported_features="fffff") + prob = ProblemDetails(title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params) - return Response(json.dumps(dict_to_camel_case(prob.to_dict()), cls=JSONEncoder), status=400, mimetype=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + + return Response(json.dumps(dict_to_camel_case(prob), cls=JSONEncoder), status=400, mimetype=cause) def not_found_error(detail, cause): - prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Not Found", status=404, detail=detail, cause=cause, invalid_params=[{"param":"","reason":""}], supported_features="fffff") - # BEFORE: prob = ProblemDetails(title="Not Found", status=404, detail=detail, cause=cause) + # prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Not Found", status=404, detail=detail, cause=cause, invalid_params=[{"param":"","reason":""}], supported_features="fffff") + prob = ProblemDetails(title="Not Found", status=404, detail=detail, cause=cause) + + prob = prob.to_dict() + prob = clean_empty(prob) - return Response(json.dumps(dict_to_camel_case(prob.to_dict()), cls=JSONEncoder), status=404, mimetype=mimetype) \ No newline at end of file + return Response(json.dumps(dict_to_camel_case(prob), cls=JSONEncoder), status=404, mimetype=mimetype) \ No newline at end of file -- GitLab From 7abca1446ef23e22739052da7f1feb6bfaa62402 Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Mon, 10 Jun 2024 10:58:42 +0300 Subject: [PATCH 05/15] Move Publish Service from testing to production server --- .../Dockerfile | 6 ++-- .../published_apis/{__main__.py => app.py} | 22 +++++++-------- .../published_apis/config.py | 2 +- .../controllers/default_controller.py | 10 ++----- .../published_apis/core/resources.py | 2 +- .../published_apis/core/responses.py | 28 ++++++++++++++++++- .../core/serviceapidescriptions.py | 14 ++-------- .../published_apis/core/validate_user.py | 4 +++ .../published_apis/db/db.py | 2 +- .../published_apis/encoder.py | 2 +- .../published_apis/util.py | 3 +- .../published_apis/wsgi.py | 4 +++ .../requirements.txt | 2 ++ 13 files changed, 61 insertions(+), 40 deletions(-) rename services/TS29222_CAPIF_Publish_Service_API/published_apis/{__main__.py => app.py} (94%) create mode 100644 services/TS29222_CAPIF_Publish_Service_API/published_apis/wsgi.py diff --git a/services/TS29222_CAPIF_Publish_Service_API/Dockerfile b/services/TS29222_CAPIF_Publish_Service_API/Dockerfile index b2e6167..9f298a3 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/Dockerfile +++ b/services/TS29222_CAPIF_Publish_Service_API/Dockerfile @@ -12,6 +12,8 @@ COPY . /usr/src/app EXPOSE 8080 -ENTRYPOINT ["python3"] +# ENTRYPOINT ["python3"] +ENTRYPOINT ["gunicorn"] -CMD ["-m", "published_apis"] \ No newline at end of file +# CMD ["-m", "published_apis"] +CMD ["--bind", "0.0.0.0:8080", "--chdir", "/usr/src/app/published_apis", "wsgi:app"] \ No newline at end of file diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/__main__.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/app.py similarity index 94% rename from services/TS29222_CAPIF_Publish_Service_API/published_apis/__main__.py rename to services/TS29222_CAPIF_Publish_Service_API/published_apis/app.py index dfba9ef..f4cdc30 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/__main__.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/app.py @@ -3,15 +3,15 @@ import connexion import logging -from published_apis import encoder +# from published_apis import encoder +import encoder -from flask import Flask, jsonify, request from flask_jwt_extended import JWTManager, jwt_required, create_access_token -from pymongo import MongoClient -from .config import Config +# from .config import Config +from config import Config from logging.handlers import RotatingFileHandler -from .core.consumer_messager import Subscriber -from flask_executor import Executor +from core.consumer_messager import Subscriber + import os from fluent import sender from flask_executor import Executor @@ -24,10 +24,9 @@ from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.instrumentation.redis import RedisInstrumentor - - NAME = "Publish-Service" + def configure_monitoring(app, config): resource = Resource(attributes={"service.name": NAME}) @@ -86,7 +85,6 @@ def configure_monitoring(app, config): l.addHandler(FluentBitHandler()) - def configure_logging(app): del app.logger.handlers[:] loggers = [app.logger, ] @@ -114,6 +112,7 @@ def verbose_formatter(): datefmt='%d/%m/%Y %H:%M:%S' ) + app = connexion.App(__name__, specification_dir='./openapi/') app.app.json_encoder = encoder.JSONEncoder app.add_api('openapi.yaml', @@ -133,10 +132,11 @@ if eval(os.environ.get("MONITORING").lower().capitalize()): executor = Executor(app.app) subscriber = Subscriber() + @app.app.before_first_request def up_listener(): executor.submit(subscriber.listen) -if __name__ == '__main__': - app.run(debug=True, port=8080) +# if __name__ == '__main__': +# app.run(debug=True, port=8080) diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/config.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/config.py index 11e1c4f..01f9914 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/config.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/config.py @@ -5,7 +5,7 @@ import os class Config: def __init__(self): self.cached = 0 - self.file="./config.yaml" + self.file="../config.yaml" self.my_config = {} stamp = os.stat(self.file).st_mtime diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py index 8fc2b62..ab80164 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py @@ -1,20 +1,14 @@ import connexion -from published_apis.models.service_api_description import ServiceAPIDescription # noqa: E501 -from ..core import serviceapidescriptions +from ..models.service_api_description import ServiceAPIDescription # noqa: E501 from ..core.serviceapidescriptions import PublishServiceOperations from ..core.publisher import Publisher -import json from flask import Response, request, current_app -from flask_jwt_extended import jwt_required, get_jwt_identity -from flask import current_app -from ..encoder import JSONEncoder -from ..models.problem_details import ProblemDetails + from cryptography import x509 from cryptography.hazmat.backends import default_backend from ..core.validate_user import ControlAccess from functools import wraps -import pymongo service_operations = PublishServiceOperations() diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/resources.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/resources.py index 94e29ec..efbe3c2 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/resources.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/resources.py @@ -1,5 +1,5 @@ from abc import ABC, abstractmethod -from ..db.db import MongoDatabse +from db.db import MongoDatabse class Resource(ABC): diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/responses.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/responses.py index c1809ed..c61eae0 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/responses.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/responses.py @@ -1,37 +1,63 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder from flask import Response +from ..util import dict_to_camel_case, clean_empty import json -from bson import json_util + mimetype = "application/json" + def make_response(object, status): res = Response(json.dumps(object, cls=JSONEncoder), status=status, mimetype=mimetype) return res + def internal_server_error(detail, cause): prob = ProblemDetails(title="Internal Server Error", status=500, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=500, mimetype=mimetype) + def forbidden_error(detail, cause): prob = ProblemDetails(title="Forbidden", status=403, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=403, mimetype=mimetype) + def bad_request_error(detail, cause, invalid_params): prob = ProblemDetails(title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=400, mimetype=cause) + def not_found_error(detail, cause): prob = ProblemDetails(title="Not Found", status=404, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=404, mimetype=mimetype) def unauthorized_error(detail, cause): prob = ProblemDetails(title="Unauthorized", status=401, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=401, mimetype=mimetype) \ No newline at end of file diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py index 5c903d1..9dd9beb 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py @@ -1,21 +1,11 @@ -import sys - -import pymongo from pymongo import ReturnDocument import secrets from flask import current_app, Flask, Response -import json -from pymongo import response -from ..db.db import MongoDatabse -from ..encoder import JSONEncoder -from ..models.problem_details import ProblemDetails from .resources import Resource -from published_apis.models.service_api_description import ServiceAPIDescription from datetime import datetime from ..util import dict_to_camel_case, clean_empty -from .responses import bad_request_error, internal_server_error, forbidden_error, not_found_error, unauthorized_error, make_response -from bson import json_util +from .responses import internal_server_error, forbidden_error, not_found_error, unauthorized_error, make_response from .auth_manager import AuthManager @@ -109,7 +99,7 @@ class PublishServiceOperations(Resource): self.auth_manager.add_auth_service(api_id, apf_id) current_app.logger.debug("Service inserted in database") - res = make_response(object=serviceapidescription, status=201) + res = make_response(object=dict_to_camel_case(clean_empty(serviceapidescription.to_dict())), status=201) res.headers['Location'] = "http://localhost:8080/published-apis/v1/" + str(apf_id) + "/service-apis/" + str(api_id) return res diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/validate_user.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/validate_user.py index 67d434d..5eed2c9 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/validate_user.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/validate_user.py @@ -4,6 +4,7 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder from .resources import Resource from .responses import internal_server_error +from ..util import dict_to_camel_case, clean_empty class ControlAccess(Resource): @@ -18,6 +19,9 @@ class ControlAccess(Resource): if cert_entry is not None: if cert_entry["cert_signature"] != cert_signature or "services" not in cert_entry["resources"] or service_id not in cert_entry["resources"]["services"]: prob = ProblemDetails(title="Unauthorized", detail="User not authorized", cause="You are not the owner of this resource") + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) return Response(json.dumps(prob, cls=JSONEncoder), status=401, mimetype="application/json") except Exception as e: diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/db/db.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/db/db.py index 91f7b6b..114b50b 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/db/db.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/db/db.py @@ -2,7 +2,7 @@ import atexit import time from pymongo import MongoClient from pymongo.errors import AutoReconnect -from ..config import Config +from config import Config from bson.codec_options import CodecOptions import os from opentelemetry.instrumentation.pymongo import PymongoInstrumentor diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/encoder.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/encoder.py index c753f45..80bad8f 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/encoder.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/encoder.py @@ -1,7 +1,7 @@ from connexion.apps.flask_app import FlaskJSONEncoder import six -from published_apis.models.base_model_ import Model +from models.base_model_ import Model class JSONEncoder(FlaskJSONEncoder): diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/util.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/util.py index 3f53de6..c43b274 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/util.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/util.py @@ -1,8 +1,7 @@ import datetime import six -import typing -from published_apis import typing_utils +import typing_utils def clean_empty(d): diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/wsgi.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/wsgi.py new file mode 100644 index 0000000..6026b0f --- /dev/null +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/wsgi.py @@ -0,0 +1,4 @@ +from app import app + +if __name__ == "__main__": + app.run() diff --git a/services/TS29222_CAPIF_Publish_Service_API/requirements.txt b/services/TS29222_CAPIF_Publish_Service_API/requirements.txt index 0ba8fb5..cd12aa4 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/requirements.txt +++ b/services/TS29222_CAPIF_Publish_Service_API/requirements.txt @@ -19,3 +19,5 @@ flask_executor == 1.0.0 pyopenssl == 23.0.0 redis == 4.5.4 flask_executor == 1.0.0 +gunicorn==22.0.0 +packaging==24.0 -- GitLab From d140ad20bc5ae36d3784000373766f0be1fc2a1c Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Mon, 10 Jun 2024 15:00:49 +0300 Subject: [PATCH 06/15] Move Invoker Management API from testing to production server, remove unnecessary imports --- .../{__main__.py => app.py} | 21 ++++++------------- .../api_invoker_management/config.py | 2 +- .../controllers/default_controller.py | 5 +---- .../core/apiinvokerenrolmentdetails.py | 9 ++++---- .../core/auth_manager.py | 2 -- .../core/invoker_internal_ops.py | 1 - .../api_invoker_management/core/publisher.py | 2 -- .../api_invoker_management/core/resources.py | 2 +- .../api_invoker_management/core/responses.py | 17 +++++++++++++++ .../core/validate_user.py | 5 +++++ .../api_invoker_management/db/db.py | 3 +-- .../api_invoker_management/encoder.py | 2 +- .../api_invoker_management/util.py | 16 ++++++++++++-- .../api_invoker_management/wsgi.py | 4 ++++ .../prepare_invoker.sh | 6 ++++-- .../requirements.txt | 2 ++ .../api_provider_management/app.py | 1 - .../controllers/default_controller.py | 3 --- ...i_provider_enrolment_details_controller.py | 4 ---- .../core/auth_manager.py | 1 - .../core/provider_enrolment_details_api.py | 2 -- .../api_provider_management/core/publisher.py | 1 - .../api_provider_management/core/resources.py | 6 +++--- .../core/sign_certificate.py | 1 - .../core/validate_user.py | 4 ++++ .../api_provider_management/db/db.py | 3 +-- .../api_provider_management/util.py | 2 -- .../published_apis/app.py | 1 - .../published_apis/core/auth_manager.py | 2 -- .../published_apis/core/consumer_messager.py | 5 ----- .../published_apis/core/publisher.py | 1 - .../published_apis/db/db.py | 1 - services/register/register_service/app.py | 2 -- .../core/register_operations.py | 1 - services/register/register_service/db/db.py | 2 -- 35 files changed, 70 insertions(+), 72 deletions(-) rename services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/{__main__.py => app.py} (94%) create mode 100644 services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/wsgi.py diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/__main__.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/app.py similarity index 94% rename from services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/__main__.py rename to services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/app.py index 32ccc2e..5d8cc4b 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/__main__.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/app.py @@ -2,13 +2,10 @@ import connexion import logging -from api_invoker_management import encoder - -from flask import Flask, jsonify, request +import encoder from flask_jwt_extended import JWTManager, jwt_required, create_access_token -from pymongo import MongoClient -from .config import Config -from .core.consumer_messager import Subscriber +from config import Config +from core.consumer_messager import Subscriber from logging.handlers import RotatingFileHandler import os from fluent import sender @@ -23,12 +20,6 @@ from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.instrumentation.redis import RedisInstrumentor - -import sys -import uuid - - - NAME = "Invoker-Service" def configure_monitoring(app, config): @@ -146,7 +137,7 @@ subscriber = Subscriber() def create_listener_message(): executor.submit(subscriber.listen) -if __name__ == '__main__': - import logging - app.run(debug=True, port=8080) +# if __name__ == '__main__': +# import logging +# app.run(debug=True, port=8080) diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/config.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/config.py index 11e1c4f..01f9914 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/config.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/config.py @@ -5,7 +5,7 @@ import os class Config: def __init__(self): self.cached = 0 - self.file="./config.yaml" + self.file="../config.yaml" self.my_config = {} stamp = os.stat(self.file).st_mtime diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/controllers/default_controller.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/controllers/default_controller.py index 27eb1c8..9f94b19 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/controllers/default_controller.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/controllers/default_controller.py @@ -1,14 +1,11 @@ import connexion -from api_invoker_management.models.api_invoker_enrolment_details import APIInvokerEnrolmentDetails # noqa: E501 +from ..models.api_invoker_enrolment_details import APIInvokerEnrolmentDetails # noqa: E501 from ..core.apiinvokerenrolmentdetails import InvokerManagementOperations from ..core.validate_user import ControlAccess -import json from flask import Response, request, current_app from flask_jwt_extended import jwt_required, get_jwt_identity -from ..encoder import JSONEncoder -from ..models.problem_details import ProblemDetails from cryptography import x509 from cryptography.hazmat.backends import default_backend from ..core.publisher import Publisher diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py index dc186e4..7becdca 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py @@ -6,7 +6,7 @@ from .responses import bad_request_error, not_found_error, forbidden_error, inte from flask import current_app, Flask, Response import json from datetime import datetime -from ..util import dict_to_camel_case +from ..util import dict_to_camel_case, clean_empty from .auth_manager import AuthManager from .resources import Resource from ..config import Config @@ -73,7 +73,6 @@ class InvokerManagementOperations(Resource): api_invoker_id = 'INV'+str(secrets.token_hex(15)) cert = self.__sign_cert(apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key, api_invoker_id) - apiinvokerenrolmentdetail.api_invoker_id = api_invoker_id current_app.logger.debug(cert) apiinvokerenrolmentdetail.onboarding_information.api_invoker_certificate = cert['data']['certificate'] @@ -91,7 +90,7 @@ class InvokerManagementOperations(Resource): self.auth_manager.add_auth_invoker(cert['data']['certificate'], api_invoker_id) - res = make_response(object=apiinvokerenrolmentdetail, status=201) + res = make_response(object=dict_to_camel_case(clean_empty(apiinvokerenrolmentdetail.to_dict())), status=201) res.headers['Location'] = "/api-invoker-management/v1/onboardedInvokers/" + str(api_invoker_id) return res @@ -129,7 +128,9 @@ class InvokerManagementOperations(Resource): current_app.logger.debug("Invoker Resource inserted in database") - res = make_response(object=APIInvokerEnrolmentDetails().from_dict(dict_to_camel_case(result)), status=200) + invoker_updated = APIInvokerEnrolmentDetails().from_dict(dict_to_camel_case(result)) + + res = make_response(object=dict_to_camel_case(clean_empty(invoker_updated.to_dict())), status=200) return res except Exception as e: diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/auth_manager.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/auth_manager.py index cfab01e..c3736a6 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/auth_manager.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/auth_manager.py @@ -1,5 +1,3 @@ - -from flask import current_app from cryptography import x509 from cryptography.hazmat.backends import default_backend from .resources import Resource diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/invoker_internal_ops.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/invoker_internal_ops.py index a0aa138..a680d4d 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/invoker_internal_ops.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/invoker_internal_ops.py @@ -1,6 +1,5 @@ from .resources import Resource -from flask import current_app class InvokerInternalOperations(Resource): diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/publisher.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/publisher.py index 3898c4b..34fcdf4 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/publisher.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/publisher.py @@ -1,6 +1,4 @@ import redis -import sys -from flask import current_app class Publisher(): diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/resources.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/resources.py index 94e29ec..efbe3c2 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/resources.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/resources.py @@ -1,5 +1,5 @@ from abc import ABC, abstractmethod -from ..db.db import MongoDatabse +from db.db import MongoDatabse class Resource(ABC): diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/responses.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/responses.py index 962c4b6..96ace13 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/responses.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/responses.py @@ -2,6 +2,7 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder from flask import Response import json +from ..util import dict_to_camel_case, clean_empty mimetype = "application/json" @@ -13,19 +14,35 @@ def make_response(object, status): def internal_server_error(detail, cause): prob = ProblemDetails(title="Internal Server Error", status=500, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=500, mimetype=mimetype) def forbidden_error(detail, cause): prob = ProblemDetails(title="Forbidden", status=403, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=403, mimetype=mimetype) def bad_request_error(detail, cause, invalid_params): prob = ProblemDetails(title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=400, mimetype=cause) def not_found_error(detail, cause): prob = ProblemDetails(title="Not Found", status=404, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=404, mimetype=mimetype) \ No newline at end of file diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/validate_user.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/validate_user.py index 5a2a5dc..bcf0d88 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/validate_user.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/validate_user.py @@ -4,6 +4,8 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder from .resources import Resource from .responses import internal_server_error +from ..util import dict_to_camel_case, clean_empty + class ControlAccess(Resource): @@ -18,6 +20,9 @@ class ControlAccess(Resource): if cert_entry is not None: if cert_entry["cert_signature"] != cert_signature: prob = ProblemDetails(title="Unauthorized", detail="User not authorized", cause="You are not the owner of this resource") + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) return Response(json.dumps(prob, cls=JSONEncoder), status=401, mimetype="application/json") except Exception as e: diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/db/db.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/db/db.py index 5bfcd0b..bb93393 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/db/db.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/db/db.py @@ -1,8 +1,7 @@ -import atexit import time from pymongo import MongoClient from pymongo.errors import AutoReconnect -from ..config import Config +from config import Config from bson.codec_options import CodecOptions import os from opentelemetry.instrumentation.pymongo import PymongoInstrumentor diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/encoder.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/encoder.py index 04b06eb..80bad8f 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/encoder.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/encoder.py @@ -1,7 +1,7 @@ from connexion.apps.flask_app import FlaskJSONEncoder import six -from api_invoker_management.models.base_model_ import Model +from models.base_model_ import Model class JSONEncoder(FlaskJSONEncoder): diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/util.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/util.py index 6ce55d8..27ba971 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/util.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/util.py @@ -1,8 +1,20 @@ import datetime import six -import typing -from api_invoker_management import typing_utils +import typing_utils + + +def clean_empty(d): + if isinstance(d, dict): + return { + k: v + for k, v in ((k, clean_empty(v)) for k, v in d.items()) + if v + } + if isinstance(d, list): + return [v for v in map(clean_empty, d) if v] + return d + def dict_to_camel_case(my_dict): diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/wsgi.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/wsgi.py new file mode 100644 index 0000000..6026b0f --- /dev/null +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/wsgi.py @@ -0,0 +1,4 @@ +from app import app + +if __name__ == "__main__": + app.run() diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/prepare_invoker.sh b/services/TS29222_CAPIF_API_Invoker_Management_API/prepare_invoker.sh index 90ce2be..76843be 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/prepare_invoker.sh +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/prepare_invoker.sh @@ -14,5 +14,7 @@ curl -vv -k -retry 30 \ --request GET "$VAULT_ADDR/v1/secret/data/server_cert/pub" 2>/dev/null | jq -r '.data.data.pub_key' -j > /usr/src/app/api_invoker_management/pubkey.pem -cd /usr/src/app/ -python3 -m api_invoker_management \ No newline at end of file +#cd /usr/src/app/ +#python3 -m api_invoker_management +gunicorn --bind 0.0.0.0:8080 \ + --chdir /usr/src/app/api_invoker_management wsgi:app \ No newline at end of file diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/requirements.txt b/services/TS29222_CAPIF_API_Invoker_Management_API/requirements.txt index ce843e6..10f300b 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/requirements.txt +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/requirements.txt @@ -19,3 +19,5 @@ fluent-logger == 0.10.0 opentelemetry-api == 1.19.0 opentelemetry-sdk == 1.19.0 flask_executor == 1.0.0 +gunicorn==22.0.0 +packaging==24.0 \ No newline at end of file diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/app.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/app.py index 4caa391..7eefe68 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/app.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/app.py @@ -10,7 +10,6 @@ from config import Config import os import sys from fluent import sender -from flask_executor import Executor from opentelemetry.instrumentation.flask import FlaskInstrumentor from opentelemetry import trace from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/default_controller.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/default_controller.py index 50745b8..d9a190c 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/default_controller.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/default_controller.py @@ -1,7 +1,4 @@ import connexion -import six -import json - from flask import Response, request, current_app from ..core.provider_enrolment_details_api import ProviderManagementOperations diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/individual_api_provider_enrolment_details_controller.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/individual_api_provider_enrolment_details_controller.py index 50ccf0e..dee8d15 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/individual_api_provider_enrolment_details_controller.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/controllers/individual_api_provider_enrolment_details_controller.py @@ -1,8 +1,4 @@ -from email.quoprimime import body_decode import connexion -import six -import json - from flask import Response, request, current_app from ..core.provider_enrolment_details_api import ProviderManagementOperations from ..encoder import JSONEncoder diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/auth_manager.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/auth_manager.py index a4a2d24..cfa302a 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/auth_manager.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/auth_manager.py @@ -1,5 +1,4 @@ -from flask import current_app from cryptography import x509 from cryptography.hazmat.backends import default_backend from .resources import Resource diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py index 976cb32..61ab74d 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py @@ -138,7 +138,6 @@ class ProviderManagementOperations(Resource): current_app.logger.debug("Provider domain updated in database") provider_updated = APIProviderEnrolmentDetails().from_dict(dict_to_camel_case(result)) - # return make_response(object=APIProviderEnrolmentDetails().from_dict(dict_to_camel_case(result)), status=200) return make_response(object=dict_to_camel_case(provider_updated.to_dict()), status=200) except Exception as e: @@ -165,7 +164,6 @@ class ProviderManagementOperations(Resource): current_app.logger.debug("Provider domain updated in database") provider_updated = APIProviderEnrolmentDetails().from_dict(dict_to_camel_case(result)) - # return make_response(object=APIProviderEnrolmentDetails().from_dict(dict_to_camel_case(result)), status=200) return make_response(object=dict_to_camel_case(provider_updated.to_dict()), status=200) except Exception as e: diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/publisher.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/publisher.py index 38d7259..acedb7e 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/publisher.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/publisher.py @@ -1,5 +1,4 @@ import redis -import sys class Publisher(): diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/resources.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/resources.py index 86e99d4..7b8092a 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/resources.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/resources.py @@ -1,6 +1,6 @@ -from abc import ABC, abstractmethod -from ..db.db import MongoDatabse -from .publisher import Publisher +from abc import ABC +from db.db import MongoDatabse +from core.publisher import Publisher class Resource(ABC): diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/sign_certificate.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/sign_certificate.py index 6ec96cf..159947e 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/sign_certificate.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/sign_certificate.py @@ -1,6 +1,5 @@ import requests import json -import sys from ..config import Config def sign_certificate(publick_key, provider_id): diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/validate_user.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/validate_user.py index 4d101ae..4a9445d 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/validate_user.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/validate_user.py @@ -4,6 +4,7 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder from .resources import Resource from .responses import internal_server_error +from ..util import dict_to_camel_case, clean_empty class ControlAccess(Resource): @@ -18,6 +19,9 @@ class ControlAccess(Resource): if cert_entry is not None: if cert_entry["cert_signature"] != cert_signature: prob = ProblemDetails(title="Unauthorized", detail="User not authorized", cause="You are not the owner of this resource") + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) return Response(json.dumps(prob, cls=JSONEncoder), status=401, mimetype="application/json") except Exception as e: diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/db/db.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/db/db.py index bb08025..e2aba93 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/db/db.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/db/db.py @@ -1,8 +1,7 @@ -import atexit import time from pymongo import MongoClient from pymongo.errors import AutoReconnect -from ..config import Config +from config import Config from bson.codec_options import CodecOptions import os from opentelemetry.instrumentation.pymongo import PymongoInstrumentor diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/util.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/util.py index 5ff8054..6fc44d5 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/util.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/util.py @@ -1,7 +1,5 @@ import datetime - import six -import typing import typing_utils def clean_empty(d): diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/app.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/app.py index f4cdc30..d3abb2d 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/app.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/app.py @@ -7,7 +7,6 @@ import logging import encoder from flask_jwt_extended import JWTManager, jwt_required, create_access_token -# from .config import Config from config import Config from logging.handlers import RotatingFileHandler from core.consumer_messager import Subscriber diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/auth_manager.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/auth_manager.py index 6e329a4..cb2f0b9 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/auth_manager.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/auth_manager.py @@ -1,7 +1,5 @@ from flask import current_app -from cryptography import x509 -from cryptography.hazmat.backends import default_backend from .resources import Resource diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/consumer_messager.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/consumer_messager.py index 93d35e4..f0b3159 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/consumer_messager.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/consumer_messager.py @@ -1,10 +1,5 @@ # subscriber.py import redis -import time -import sys -import json -import asyncio -from threading import Thread from .internal_service_ops import InternalServiceOps from flask import current_app diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/publisher.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/publisher.py index f7b0c3c..34fcdf4 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/publisher.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/publisher.py @@ -1,5 +1,4 @@ import redis -import sys class Publisher(): diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/db/db.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/db/db.py index 114b50b..e30cb66 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/db/db.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/db/db.py @@ -1,4 +1,3 @@ -import atexit import time from pymongo import MongoClient from pymongo.errors import AutoReconnect diff --git a/services/register/register_service/app.py b/services/register/register_service/app.py index c92f175..cca3cfb 100644 --- a/services/register/register_service/app.py +++ b/services/register/register_service/app.py @@ -1,12 +1,10 @@ -import os from flask import Flask from controllers.register_controller import register_routes from flask_jwt_extended import JWTManager from OpenSSL.crypto import PKey, TYPE_RSA, X509Req, dump_certificate_request, FILETYPE_PEM, dump_privatekey import requests import json -import jwt from config import Config app = Flask(__name__) diff --git a/services/register/register_service/core/register_operations.py b/services/register/register_service/core/register_operations.py index 53f9806..cf5219d 100644 --- a/services/register/register_service/core/register_operations.py +++ b/services/register/register_service/core/register_operations.py @@ -3,7 +3,6 @@ from flask_jwt_extended import create_access_token from db.db import MongoDatabse from datetime import datetime from config import Config -import base64 import uuid class RegisterOperations: diff --git a/services/register/register_service/db/db.py b/services/register/register_service/db/db.py index 3f73712..9e64103 100644 --- a/services/register/register_service/db/db.py +++ b/services/register/register_service/db/db.py @@ -1,9 +1,7 @@ -import atexit import time from pymongo import MongoClient from pymongo.errors import AutoReconnect from config import Config -from bson.codec_options import CodecOptions class MongoDatabse(): -- GitLab From 7ae2a0e70d332a8cfc2d4b156edda5e583645ccf Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Mon, 10 Jun 2024 16:13:59 +0300 Subject: [PATCH 07/15] Move Discover API from testing to production server & remove unnecessary imports --- .../Dockerfile | 4 ++-- .../requirements.txt | 4 +++- .../service_apis/{__main__.py => app.py} | 16 +++++-------- .../service_apis/config.py | 2 +- .../controllers/default_controller.py | 9 +------ .../service_apis/core/discoveredapis.py | 24 +++++-------------- .../service_apis/core/resources.py | 2 +- .../service_apis/core/responses.py | 18 +++++++++++++- .../service_apis/db/db.py | 4 ++-- .../service_apis/encoder.py | 2 +- .../service_apis/util.py | 6 ++--- .../service_apis/wsgi.py | 4 ++++ .../Dockerfile | 2 -- 13 files changed, 47 insertions(+), 50 deletions(-) rename services/TS29222_CAPIF_Discover_Service_API/service_apis/{__main__.py => app.py} (94%) create mode 100644 services/TS29222_CAPIF_Discover_Service_API/service_apis/wsgi.py diff --git a/services/TS29222_CAPIF_Discover_Service_API/Dockerfile b/services/TS29222_CAPIF_Discover_Service_API/Dockerfile index efa70c9..9f1d46e 100644 --- a/services/TS29222_CAPIF_Discover_Service_API/Dockerfile +++ b/services/TS29222_CAPIF_Discover_Service_API/Dockerfile @@ -12,6 +12,6 @@ COPY . /usr/src/app EXPOSE 8080 -ENTRYPOINT ["python3"] +ENTRYPOINT ["gunicorn"] -CMD ["-m", "service_apis"] \ No newline at end of file +CMD ["--bind", "0.0.0.0:8080", "--chdir", "/usr/src/app/service_apis", "wsgi:app"] \ No newline at end of file diff --git a/services/TS29222_CAPIF_Discover_Service_API/requirements.txt b/services/TS29222_CAPIF_Discover_Service_API/requirements.txt index 33a22f4..1732b50 100644 --- a/services/TS29222_CAPIF_Discover_Service_API/requirements.txt +++ b/services/TS29222_CAPIF_Discover_Service_API/requirements.txt @@ -19,4 +19,6 @@ fluent-logger == 0.10.0 opentelemetry-api == 1.17.0 opentelemetry-sdk == 1.17.0 flask_executor == 1.0.0 -flask_executor == 1.0.0 \ No newline at end of file +flask_executor == 1.0.0 +gunicorn==22.0.0 +packaging==24.0 \ No newline at end of file diff --git a/services/TS29222_CAPIF_Discover_Service_API/service_apis/__main__.py b/services/TS29222_CAPIF_Discover_Service_API/service_apis/app.py similarity index 94% rename from services/TS29222_CAPIF_Discover_Service_API/service_apis/__main__.py rename to services/TS29222_CAPIF_Discover_Service_API/service_apis/app.py index 57326e9..4b4c169 100644 --- a/services/TS29222_CAPIF_Discover_Service_API/service_apis/__main__.py +++ b/services/TS29222_CAPIF_Discover_Service_API/service_apis/app.py @@ -2,18 +2,15 @@ import connexion -from service_apis import encoder +import encoder -import pymongo import logging -from flask import Flask, jsonify, request from flask_jwt_extended import JWTManager, jwt_required, create_access_token -from pymongo import MongoClient from logging.handlers import RotatingFileHandler -from .config import Config +from config import Config + import os from fluent import sender -from flask_executor import Executor from opentelemetry.instrumentation.flask import FlaskInstrumentor from opentelemetry import trace from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter @@ -23,10 +20,9 @@ from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.instrumentation.redis import RedisInstrumentor - - NAME = "Discover-Service" + def configure_monitoring(app, config): resource = Resource(attributes={"service.name": NAME}) @@ -127,5 +123,5 @@ if eval(os.environ.get("MONITORING").lower().capitalize()): jwt = JWTManager(app.app) -if __name__ == '__main__': - app.run(debug=True, port=8080) +# if __name__ == '__main__': +# app.run(debug=True, port=8080) diff --git a/services/TS29222_CAPIF_Discover_Service_API/service_apis/config.py b/services/TS29222_CAPIF_Discover_Service_API/service_apis/config.py index d04bd1a..97ab831 100644 --- a/services/TS29222_CAPIF_Discover_Service_API/service_apis/config.py +++ b/services/TS29222_CAPIF_Discover_Service_API/service_apis/config.py @@ -5,7 +5,7 @@ import os class Config: def __init__(self): self.cached = 0 - self.file="./config.yaml" + self.file="../config.yaml" self.my_config = {} stamp = os.stat(self.file).st_mtime diff --git a/services/TS29222_CAPIF_Discover_Service_API/service_apis/controllers/default_controller.py b/services/TS29222_CAPIF_Discover_Service_API/service_apis/controllers/default_controller.py index aef2022..2c81a78 100644 --- a/services/TS29222_CAPIF_Discover_Service_API/service_apis/controllers/default_controller.py +++ b/services/TS29222_CAPIF_Discover_Service_API/service_apis/controllers/default_controller.py @@ -1,13 +1,6 @@ -import sys -from service_apis.core.discoveredapis import DiscoverApisOperations -import json +from ..core.discoveredapis import DiscoverApisOperations from flask import Response, request, current_app -from service_apis.encoder import JSONEncoder -from service_apis.models.problem_details import ProblemDetails -from cryptography import x509 -from cryptography.hazmat.backends import default_backend -import pymongo discover_apis = DiscoverApisOperations() diff --git a/services/TS29222_CAPIF_Discover_Service_API/service_apis/core/discoveredapis.py b/services/TS29222_CAPIF_Discover_Service_API/service_apis/core/discoveredapis.py index f56b585..9ad5462 100644 --- a/services/TS29222_CAPIF_Discover_Service_API/service_apis/core/discoveredapis.py +++ b/services/TS29222_CAPIF_Discover_Service_API/service_apis/core/discoveredapis.py @@ -1,18 +1,9 @@ -import sys -import pymongo from flask import current_app, Flask, Response -import json -from service_apis.core.responses import internal_server_error, forbidden_error ,make_response, not_found_error -from service_apis.db.db import MongoDatabse -from service_apis.encoder import JSONEncoder -from service_apis.models.problem_details import ProblemDetails -from service_apis.models.service_api_description import ServiceAPIDescription -from service_apis.models.discovered_apis import DiscoveredAPIs -from service_apis.util import dict_to_camel_case, clean_empty -from service_apis.core.resources import Resource -from bson import json_util - +from ..core.responses import internal_server_error, forbidden_error ,make_response, not_found_error +from ..models.discovered_apis import DiscoveredAPIs +from ..util import dict_to_camel_case, clean_empty +from ..core.resources import Resource class DiscoverApisOperations(Resource): @@ -46,16 +37,13 @@ class DiscoverApisOperations(Resource): discoved_apis = services.find(my_query, {"_id":0, "api_name":1, "api_id":1, "aef_profiles":1, "description":1, "supported_features":1, "shareable_info":1, "service_api_category":1, "api_supp_feats":1, "pub_api_path":1, "ccf_id":1}) json_docs = [] for discoved_api in discoved_apis: - my_api = dict_to_camel_case(discoved_api) - my_api = clean_empty(my_api) - json_docs.append(my_api) + json_docs.append(discoved_api) if len(json_docs) == 0: return not_found_error(detail="API Invoker " + api_invoker_id + " has no API Published that accomplish filter conditions", cause="No API Published accomplish filter conditions") apis_discoveres = DiscoveredAPIs(service_api_descriptions=json_docs) - res = make_response(object=apis_discoveres, status=200) - current_app.logger.debug("Discovered APIs by: " + api_invoker_id) + res = make_response(object=dict_to_camel_case(clean_empty(apis_discoveres.to_dict())), status=200) return res except Exception as e: diff --git a/services/TS29222_CAPIF_Discover_Service_API/service_apis/core/resources.py b/services/TS29222_CAPIF_Discover_Service_API/service_apis/core/resources.py index 94e29ec..efbe3c2 100644 --- a/services/TS29222_CAPIF_Discover_Service_API/service_apis/core/resources.py +++ b/services/TS29222_CAPIF_Discover_Service_API/service_apis/core/resources.py @@ -1,5 +1,5 @@ from abc import ABC, abstractmethod -from ..db.db import MongoDatabse +from db.db import MongoDatabse class Resource(ABC): diff --git a/services/TS29222_CAPIF_Discover_Service_API/service_apis/core/responses.py b/services/TS29222_CAPIF_Discover_Service_API/service_apis/core/responses.py index 4f03578..df9905f 100644 --- a/services/TS29222_CAPIF_Discover_Service_API/service_apis/core/responses.py +++ b/services/TS29222_CAPIF_Discover_Service_API/service_apis/core/responses.py @@ -1,7 +1,7 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder from flask import Response -from bson import json_util +from ..util import dict_to_camel_case, clean_empty import json mimetype = "application/json" @@ -14,19 +14,35 @@ def make_response(object, status): def internal_server_error(detail, cause): prob = ProblemDetails(title="Internal Server Error", status=500, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=500, mimetype=mimetype) def forbidden_error(detail, cause): prob = ProblemDetails(title="Forbidden", status=403, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=403, mimetype=mimetype) def bad_request_error(detail, cause, invalid_params): prob = ProblemDetails(title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=400, mimetype=cause) def not_found_error(detail, cause): prob = ProblemDetails(title="Not Found", status=404, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=404, mimetype=mimetype) \ No newline at end of file diff --git a/services/TS29222_CAPIF_Discover_Service_API/service_apis/db/db.py b/services/TS29222_CAPIF_Discover_Service_API/service_apis/db/db.py index 5445455..2b259ce 100644 --- a/services/TS29222_CAPIF_Discover_Service_API/service_apis/db/db.py +++ b/services/TS29222_CAPIF_Discover_Service_API/service_apis/db/db.py @@ -1,8 +1,7 @@ -import atexit import time from pymongo import MongoClient from pymongo.errors import AutoReconnect -from ..config import Config +from config import Config from bson.codec_options import CodecOptions import os from opentelemetry.instrumentation.pymongo import PymongoInstrumentor @@ -10,6 +9,7 @@ from opentelemetry.instrumentation.pymongo import PymongoInstrumentor if eval(os.environ.get("MONITORING").lower().capitalize()): PymongoInstrumentor().instrument() + class MongoDatabse(): def __init__(self): diff --git a/services/TS29222_CAPIF_Discover_Service_API/service_apis/encoder.py b/services/TS29222_CAPIF_Discover_Service_API/service_apis/encoder.py index c026759..80bad8f 100644 --- a/services/TS29222_CAPIF_Discover_Service_API/service_apis/encoder.py +++ b/services/TS29222_CAPIF_Discover_Service_API/service_apis/encoder.py @@ -1,7 +1,7 @@ from connexion.apps.flask_app import FlaskJSONEncoder import six -from service_apis.models.base_model_ import Model +from models.base_model_ import Model class JSONEncoder(FlaskJSONEncoder): diff --git a/services/TS29222_CAPIF_Discover_Service_API/service_apis/util.py b/services/TS29222_CAPIF_Discover_Service_API/service_apis/util.py index b3f89d7..c39e5fa 100644 --- a/services/TS29222_CAPIF_Discover_Service_API/service_apis/util.py +++ b/services/TS29222_CAPIF_Discover_Service_API/service_apis/util.py @@ -1,9 +1,7 @@ import datetime -import sys import six -import typing -from service_apis import typing_utils +import typing_utils def clean_empty(d): if isinstance(d, dict): @@ -27,6 +25,8 @@ def dict_to_camel_case(my_dict): my_key= ''.join([my_key[0].lower(), my_key[1:]]) if my_key == "serviceApiCategory": my_key = "serviceAPICategory" + elif my_key == "serviceApiDescriptions": + my_key = "serviceAPIDescriptions" if isinstance(value, list): result[my_key] = list(map( diff --git a/services/TS29222_CAPIF_Discover_Service_API/service_apis/wsgi.py b/services/TS29222_CAPIF_Discover_Service_API/service_apis/wsgi.py new file mode 100644 index 0000000..6026b0f --- /dev/null +++ b/services/TS29222_CAPIF_Discover_Service_API/service_apis/wsgi.py @@ -0,0 +1,4 @@ +from app import app + +if __name__ == "__main__": + app.run() diff --git a/services/TS29222_CAPIF_Publish_Service_API/Dockerfile b/services/TS29222_CAPIF_Publish_Service_API/Dockerfile index 9f298a3..c11e2d6 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/Dockerfile +++ b/services/TS29222_CAPIF_Publish_Service_API/Dockerfile @@ -12,8 +12,6 @@ COPY . /usr/src/app EXPOSE 8080 -# ENTRYPOINT ["python3"] ENTRYPOINT ["gunicorn"] -# CMD ["-m", "published_apis"] CMD ["--bind", "0.0.0.0:8080", "--chdir", "/usr/src/app/published_apis", "wsgi:app"] \ No newline at end of file -- GitLab From 2500a7d3e8a6ef1e5d3a078f13d1075286a82df7 Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Tue, 11 Jun 2024 10:18:47 +0300 Subject: [PATCH 08/15] Move Security Context API from testing to production server and remove unnecessary imports --- .../capif_security/{__main__.py => app.py} | 58 +++++++++---------- .../capif_security/config.py | 2 +- .../controllers/default_controller.py | 24 +++----- .../capif_security/core/consumer_messager.py | 5 -- .../core/internal_security_ops.py | 1 - .../capif_security/core/notification.py | 4 +- .../capif_security/core/publisher.py | 2 +- .../capif_security/core/resources.py | 5 +- .../capif_security/core/responses.py | 28 ++++++++- .../capif_security/core/servicesecurity.py | 40 ++++++------- .../capif_security/db/db.py | 2 +- .../capif_security/encoder.py | 2 +- .../capif_security/util.py | 3 +- .../capif_security/wsgi.py | 4 ++ .../requirements.txt | 4 +- .../security_prepare.sh | 4 +- 16 files changed, 99 insertions(+), 89 deletions(-) rename services/TS29222_CAPIF_Security_API/capif_security/{__main__.py => app.py} (78%) create mode 100644 services/TS29222_CAPIF_Security_API/capif_security/wsgi.py diff --git a/services/TS29222_CAPIF_Security_API/capif_security/__main__.py b/services/TS29222_CAPIF_Security_API/capif_security/app.py similarity index 78% rename from services/TS29222_CAPIF_Security_API/capif_security/__main__.py rename to services/TS29222_CAPIF_Security_API/capif_security/app.py index 98d3964..30fc3a4 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/__main__.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/app.py @@ -2,14 +2,11 @@ import connexion import logging -from capif_security import encoder +import encoder from flask_jwt_extended import JWTManager -from .config import Config -from .core.consumer_messager import Subscriber -from threading import Thread -from flask_executor import Executor +from config import Config +from core.consumer_messager import Subscriber from logging.handlers import RotatingFileHandler -import sys import os from fluent import sender from flask_executor import Executor @@ -22,10 +19,9 @@ from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.instrumentation.redis import RedisInstrumentor - - NAME = "Security-Service" + def configure_monitoring(app, config): resource = Resource(attributes={"service.name": NAME}) @@ -110,39 +106,37 @@ def verbose_formatter(): datefmt='%d/%m/%Y %H:%M:%S' ) -def main(): - - with open("/usr/src/app/capif_security/server.key", "rb") as key_file: - key_data = key_file.read() - app = connexion.App(__name__, specification_dir='./openapi/') - app.app.json_encoder = encoder.JSONEncoder +with open("/usr/src/app/capif_security/server.key", "rb") as key_file: + key_data = key_file.read() +app = connexion.App(__name__, specification_dir='./openapi/') +app.app.json_encoder = encoder.JSONEncoder - app.app.config['JWT_ALGORITHM'] = 'RS256' - app.app.config['JWT_PRIVATE_KEY'] = key_data - app.add_api('openapi.yaml', - arguments={'title': 'CAPIF_Security_API'}, - pythonic_params=True) - JWTManager(app.app) - subscriber = Subscriber() +app.app.config['JWT_ALGORITHM'] = 'RS256' +app.app.config['JWT_PRIVATE_KEY'] = key_data +app.add_api('openapi.yaml', + arguments={'title': 'CAPIF_Security_API'}, + pythonic_params=True) - config = Config() - configure_logging(app.app) +JWTManager(app.app) +subscriber = Subscriber() - if eval(os.environ.get("MONITORING").lower().capitalize()): - configure_monitoring(app.app, config.get_config()) +config = Config() +configure_logging(app.app) - executor = Executor(app.app) +if eval(os.environ.get("MONITORING").lower().capitalize()): + configure_monitoring(app.app, config.get_config()) - @app.app.before_first_request - def up_listener(): - executor.submit(subscriber.listen) +executor = Executor(app.app) +@app.app.before_first_request +def up_listener(): + executor.submit(subscriber.listen) - app.run(port=8080, debug=True) -if __name__ == '__main__': - main() +# +# if __name__ == '__main__': +# main() diff --git a/services/TS29222_CAPIF_Security_API/capif_security/config.py b/services/TS29222_CAPIF_Security_API/capif_security/config.py index 11e1c4f..01f9914 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/config.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/config.py @@ -5,7 +5,7 @@ import os class Config: def __init__(self): self.cached = 0 - self.file="./config.yaml" + self.file="../config.yaml" self.my_config = {} stamp = os.stat(self.file).st_mtime diff --git a/services/TS29222_CAPIF_Security_API/capif_security/controllers/default_controller.py b/services/TS29222_CAPIF_Security_API/capif_security/controllers/default_controller.py index aee7098..6713db1 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/controllers/default_controller.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/controllers/default_controller.py @@ -1,26 +1,20 @@ import connexion -import six - -from capif_security.models.access_token_err import AccessTokenErr # noqa: E501 -from capif_security.models.access_token_rsp import AccessTokenRsp # noqa: E501 -from capif_security.models.access_token_req import AccessTokenReq # noqa: E501 -from capif_security.models.security_notification import SecurityNotification # noqa: E501 -from capif_security.models.service_security import ServiceSecurity # noqa: E501 -from capif_security import util + +from ..models.access_token_req import AccessTokenReq # noqa: E501 +from ..models.security_notification import SecurityNotification # noqa: E501 +from ..models.service_security import ServiceSecurity # noqa: E501 + from ..core.servicesecurity import SecurityOperations -from ..core.consumer_messager import Subscriber + from ..core.publisher import Publisher -import json + from flask import Response, request, current_app -from flask_jwt_extended import jwt_required, get_jwt_identity -from ..encoder import JSONEncoder -from ..models.problem_details import ProblemDetails -import sys + from cryptography import x509 from cryptography.hazmat.backends import default_backend from ..core.validate_user import ControlAccess from functools import wraps -import pymongo + service_security_ops = SecurityOperations() publish_ops = Publisher() diff --git a/services/TS29222_CAPIF_Security_API/capif_security/core/consumer_messager.py b/services/TS29222_CAPIF_Security_API/capif_security/core/consumer_messager.py index fd9c328..749f57e 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/core/consumer_messager.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/core/consumer_messager.py @@ -1,10 +1,5 @@ # subscriber.py import redis -import time -import sys -import json -import asyncio -from threading import Thread from .internal_security_ops import InternalSecurityOps from flask import current_app diff --git a/services/TS29222_CAPIF_Security_API/capif_security/core/internal_security_ops.py b/services/TS29222_CAPIF_Security_API/capif_security/core/internal_security_ops.py index d5cbd96..d1b28d5 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/core/internal_security_ops.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/core/internal_security_ops.py @@ -1,5 +1,4 @@ -from flask import current_app from .resources import Resource class InternalSecurityOps(Resource): diff --git a/services/TS29222_CAPIF_Security_API/capif_security/core/notification.py b/services/TS29222_CAPIF_Security_API/capif_security/core/notification.py index 5d69adc..2efad5f 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/core/notification.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/core/notification.py @@ -1,7 +1,5 @@ import requests -from ..encoder import JSONEncoder -import sys -import json + class Notifications(): diff --git a/services/TS29222_CAPIF_Security_API/capif_security/core/publisher.py b/services/TS29222_CAPIF_Security_API/capif_security/core/publisher.py index f7b0c3c..8292de4 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/core/publisher.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/core/publisher.py @@ -1,5 +1,5 @@ import redis -import sys + class Publisher(): diff --git a/services/TS29222_CAPIF_Security_API/capif_security/core/resources.py b/services/TS29222_CAPIF_Security_API/capif_security/core/resources.py index 2ba2a0f..53a35e5 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/core/resources.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/core/resources.py @@ -1,7 +1,8 @@ -from abc import ABC, abstractmethod -from ..db.db import MongoDatabse +from abc import ABC +from db.db import MongoDatabse from .notification import Notifications + class Resource(ABC): def __init__(self): diff --git a/services/TS29222_CAPIF_Security_API/capif_security/core/responses.py b/services/TS29222_CAPIF_Security_API/capif_security/core/responses.py index 26e82b6..9c2020c 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/core/responses.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/core/responses.py @@ -2,36 +2,62 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder from flask import Response import json -from bson import json_util +from ..util import dict_to_camel_case, clean_empty mimetype = "application/json" + def make_response(object, status): res = Response(json.dumps(object, cls=JSONEncoder), status=status, mimetype=mimetype) return res + def internal_server_error(detail, cause): prob = ProblemDetails(title="Internal Server Error", status=500, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=500, mimetype=mimetype) + def forbidden_error(detail, cause): prob = ProblemDetails(title="Forbidden", status=403, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=403, mimetype=mimetype) + def bad_request_error(detail, cause, invalid_params): prob = ProblemDetails(title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=400, mimetype=cause) + def not_found_error(detail, cause): prob = ProblemDetails(title="Not Found", status=404, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=404, mimetype=mimetype) + def unauthorized_error(detail, cause): prob = ProblemDetails(title="Unauthorized", status=401, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=401, mimetype=mimetype) \ No newline at end of file diff --git a/services/TS29222_CAPIF_Security_API/capif_security/core/servicesecurity.py b/services/TS29222_CAPIF_Security_API/capif_security/core/servicesecurity.py index 69475ac..f553b4d 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/core/servicesecurity.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/core/servicesecurity.py @@ -1,28 +1,19 @@ -import sys -import pymongo from pymongo import ReturnDocument -import secrets -import re + import rfc3987 from flask import current_app, Flask, Response from flask_jwt_extended import create_access_token from datetime import datetime, timedelta import json -from ..db.db import MongoDatabse -from ..encoder import JSONEncoder -from ..models.problem_details import ProblemDetails from ..models.access_token_rsp import AccessTokenRsp from ..models.access_token_claims import AccessTokenClaims from bson import json_util -import requests from ..core.publisher import Publisher from ..models.access_token_err import AccessTokenErr -from ..models.service_security import ServiceSecurity from ..util import dict_to_camel_case, clean_empty from .responses import not_found_error, make_response, bad_request_error, internal_server_error, forbidden_error -from .notification import Notifications from .resources import Resource import os @@ -53,7 +44,8 @@ class SecurityOperations(Resource): if header != "3gpp": current_app.logger.error("Bad format scope") token_error = AccessTokenErr(error="invalid_scope", error_description="The first characters must be '3gpp'") - return make_response(object=token_error, status=400) + # return make_response(object=dict_to_camel_case(clean_empty(token_error.to_dict())), status=400) + return make_response(object=clean_empty(token_error.to_dict()), status=400) _, body = scope.split("#") @@ -67,21 +59,24 @@ class SecurityOperations(Resource): if aef_id not in aef_security_context: current_app.logger.error("Bad format Scope, not valid aef id ") token_error = AccessTokenErr(error="invalid_scope", error_description="One of aef_id not belongs of your security context") - return make_response(object=token_error, status=400) + # return make_response(object=dict_to_camel_case(clean_empty(token_error.to_dict())), status=400) + return make_response(object=clean_empty(token_error.to_dict()), status=400) api_names = api_names.split(",") for api_name in api_names: service = capif_service_col.find_one({"$and": [{"api_name":api_name},{self.filter_aef_id:aef_id}]}) if service is None: current_app.logger.error("Bad format Scope, not valid api name") token_error = AccessTokenErr(error="invalid_scope", error_description="One of the api names does not exist or is not associated with the aef id provided") - return make_response(object=token_error, status=400) + # return make_response(object=dict_to_camel_case(clean_empty(token_error.to_dict())), status=400) + return make_response(object=clean_empty(token_error.to_dict()), status=400) return None except Exception as e: current_app.logger.error("Bad format Scope: " + e) token_error = AccessTokenErr(error="invalid_scope", error_description="malformed scope") - return make_response(object=token_error, status=400) + # return make_response(object=dict_to_camel_case(clean_empty(token_error.to_dict())), status=400) + return make_response(object=clean_empty(token_error.to_dict()), status=400) def __init__(self): Resource.__init__(self) @@ -182,7 +177,7 @@ class SecurityOperations(Resource): rec.update(service_security.to_dict()) mycol.insert_one(rec) - res = make_response(object=service_security, status=201) + res = make_response(object=dict_to_camel_case(clean_empty(service_security.to_dict())), status=201) res.headers['Location'] = "https://{}/capif-security/v1/trustedInvokers/{}".format(os.getenv('CAPIF_HOSTNAME'),str(api_invoker_id)) return res @@ -244,17 +239,19 @@ class SecurityOperations(Resource): invoker = invokers_col.find_one({"api_invoker_id": access_token_req["client_id"]}) if invoker is None: client_id_error = AccessTokenErr(error="invalid_client", error_description="Client Id not found") - return make_response(object=client_id_error, status=400) + # return make_response(object=dict_to_camel_case(clean_empty(client_id_error.to_dict())), status=400) + return make_response(object=clean_empty(client_id_error.to_dict()), status=400) if access_token_req["grant_type"] != "client_credentials": client_id_error = AccessTokenErr(error="unsupported_grant_type", error_description="Invalid value for `grant_type` ({0}), must be one of ['client_credentials'] - 'grant_type'" .format(access_token_req["grant_type"])) - return make_response(object=client_id_error, status=400) + # return make_response(object=dict_to_camel_case(clean_empty(client_id_error.to_dict())), status=400) + return make_response(object=clean_empty(client_id_error.to_dict()), status=400) service_security = mycol.find_one({"api_invoker_id": security_id}) if service_security is None: - current_app.logger.error("Not found securoty context with id: " + security_id) + current_app.logger.error("Not found security context with id: " + security_id) return not_found_error(detail= security_context_not_found_detail, cause=api_invoker_no_context_cause) result = self.__check_scope(access_token_req["scope"], service_security) @@ -271,7 +268,8 @@ class SecurityOperations(Resource): current_app.logger.debug("Created access token") - res = make_response(object=access_token_resp, status=200) + # res = make_response(object=dict_to_camel_case(clean_empty(access_token_resp.to_dict())), status=200) + res = make_response(object=clean_empty(access_token_resp.to_dict()), status=200) return res except Exception as e: exception = "An exception occurred in return token" @@ -318,11 +316,11 @@ class SecurityOperations(Resource): result = mycol.find_one_and_update(old_object, {"$set":service_security}, projection={'_id': 0, "api_invoker_id":0},return_document=ReturnDocument.AFTER ,upsert=False) - result = clean_empty(result) + # result = clean_empty(result) current_app.logger.debug("Updated security context") - res= make_response(object=dict_to_camel_case(result), status=200) + res= make_response(object=dict_to_camel_case(clean_empty(result)), status=200) res.headers['Location'] = "https://${CAPIF_HOSTNAME}/capif-security/v1/trustedInvokers/" + str( api_invoker_id) return res diff --git a/services/TS29222_CAPIF_Security_API/capif_security/db/db.py b/services/TS29222_CAPIF_Security_API/capif_security/db/db.py index dbbb99e..4a009db 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/db/db.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/db/db.py @@ -2,7 +2,7 @@ import atexit import time from pymongo import MongoClient from pymongo.errors import AutoReconnect -from ..config import Config +from config import Config from bson.codec_options import CodecOptions import os from opentelemetry.instrumentation.pymongo import PymongoInstrumentor diff --git a/services/TS29222_CAPIF_Security_API/capif_security/encoder.py b/services/TS29222_CAPIF_Security_API/capif_security/encoder.py index 9d6964e..80bad8f 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/encoder.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/encoder.py @@ -1,7 +1,7 @@ from connexion.apps.flask_app import FlaskJSONEncoder import six -from capif_security.models.base_model_ import Model +from models.base_model_ import Model class JSONEncoder(FlaskJSONEncoder): diff --git a/services/TS29222_CAPIF_Security_API/capif_security/util.py b/services/TS29222_CAPIF_Security_API/capif_security/util.py index 873c290..00ceb15 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/util.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/util.py @@ -1,8 +1,7 @@ import datetime import six -import typing -from capif_security import typing_utils +import typing_utils def clean_empty(d): diff --git a/services/TS29222_CAPIF_Security_API/capif_security/wsgi.py b/services/TS29222_CAPIF_Security_API/capif_security/wsgi.py new file mode 100644 index 0000000..6026b0f --- /dev/null +++ b/services/TS29222_CAPIF_Security_API/capif_security/wsgi.py @@ -0,0 +1,4 @@ +from app import app + +if __name__ == "__main__": + app.run() diff --git a/services/TS29222_CAPIF_Security_API/requirements.txt b/services/TS29222_CAPIF_Security_API/requirements.txt index 220adaf..835b8ca 100644 --- a/services/TS29222_CAPIF_Security_API/requirements.txt +++ b/services/TS29222_CAPIF_Security_API/requirements.txt @@ -19,4 +19,6 @@ fluent == 0.10.0 fluent-logger == 0.10.0 opentelemetry-api == 1.17.0 opentelemetry-sdk == 1.17.0 -flask_executor == 1.0.0 \ No newline at end of file +flask_executor == 1.0.0 +gunicorn==22.0.0 +packaging==24.0 \ No newline at end of file diff --git a/services/TS29222_CAPIF_Security_API/security_prepare.sh b/services/TS29222_CAPIF_Security_API/security_prepare.sh index c28b389..94bece0 100644 --- a/services/TS29222_CAPIF_Security_API/security_prepare.sh +++ b/services/TS29222_CAPIF_Security_API/security_prepare.sh @@ -15,5 +15,5 @@ curl -k -retry 30 \ --request GET "$VAULT_ADDR/v1/secret/data/server_cert/private" 2>/dev/null | jq -r '.data.data.key' -j > /usr/src/app/capif_security/server.key -cd /usr/src/app/ -python3 -m capif_security \ No newline at end of file +gunicorn --bind 0.0.0.0:8080 \ + --chdir /usr/src/app/capif_security wsgi:app \ No newline at end of file -- GitLab From e4038e14581eb66e2c00b2a895d450096436ac48 Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Tue, 11 Jun 2024 12:57:25 +0300 Subject: [PATCH 09/15] Move ACL API from testing to production server, rename basic folder and remove unnecessary imports --- .../Dockerfile | 4 ++-- .../{openapi_server => capif_acl}/__init__.py | 0 .../__main__.py => capif_acl/app.py} | 18 ++++++--------- .../{openapi_server => capif_acl}/config.py | 2 +- .../controllers/__init__.py | 0 .../controllers/default_controller.py | 3 ++- .../controllers/security_controller_.py | 0 .../core/accesscontrolpolicyapi.py | 3 ++- .../core/consumer_messager.py | 2 +- .../core/internal_service_ops.py | 8 ++++--- .../core/publisher.py | 3 +-- .../capif_acl/core/resources.py | 8 +++++++ .../core/responses.py | 22 +++++++++++++++++++ .../{openapi_server => capif_acl}/db/db.py | 4 ++-- .../{openapi_server => capif_acl}/encoder.py | 2 +- .../capif_acl/models/__init__.py | 10 +++++++++ .../models/access_control_policy_list.py | 8 +++---- .../models/api_invoker_policy.py | 8 +++---- .../models/base_model_.py | 2 +- .../models/invalid_param.py | 4 ++-- .../models/problem_details.py | 8 +++---- .../models/time_range_list.py | 4 ++-- .../openapi/openapi.yaml | 2 +- .../test/__init__.py | 2 +- .../test/test_default_controller.py | 7 +----- .../typing_utils.py | 0 .../{openapi_server => capif_acl}/util.py | 7 +++--- .../capif_acl/wsgi.py | 5 +++++ .../openapi_server/core/resources.py | 7 ------ .../openapi_server/models/__init__.py | 10 --------- .../requirements.txt | 2 ++ 31 files changed, 94 insertions(+), 71 deletions(-) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/__init__.py (100%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server/__main__.py => capif_acl/app.py} (94%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/config.py (92%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/controllers/__init__.py (100%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/controllers/default_controller.py (98%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/controllers/security_controller_.py (100%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/core/accesscontrolpolicyapi.py (98%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/core/consumer_messager.py (98%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/core/internal_service_ops.py (96%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/core/publisher.py (83%) create mode 100644 services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/resources.py rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/core/responses.py (72%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/db/db.py (97%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/encoder.py (91%) create mode 100644 services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/__init__.py rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/models/access_control_policy_list.py (90%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/models/api_invoker_policy.py (96%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/models/base_model_.py (98%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/models/invalid_param.py (96%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/models/problem_details.py (97%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/models/time_range_list.py (96%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/openapi/openapi.yaml (99%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/test/__init__.py (89%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/test/test_default_controller.py (79%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/typing_utils.py (100%) rename services/TS29222_CAPIF_Access_Control_Policy_API/{openapi_server => capif_acl}/util.py (98%) create mode 100644 services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/wsgi.py delete mode 100644 services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/resources.py delete mode 100644 services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/__init__.py diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/Dockerfile b/services/TS29222_CAPIF_Access_Control_Policy_API/Dockerfile index 92dcb33..c69bd56 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/Dockerfile +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/Dockerfile @@ -11,6 +11,6 @@ COPY . /usr/src/app EXPOSE 8080 -ENTRYPOINT ["python3"] +ENTRYPOINT ["gunicorn"] -CMD ["-m", "openapi_server"] \ No newline at end of file +CMD ["--bind", "0.0.0.0:8080", "--chdir", "/usr/src/app/capif_acl", "wsgi:app"] \ No newline at end of file diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/__init__.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/__init__.py similarity index 100% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/__init__.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/__init__.py diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/__main__.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/app.py similarity index 94% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/__main__.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/app.py index 215e85e..da28365 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/__main__.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/app.py @@ -2,19 +2,17 @@ import connexion -from openapi_server import encoder +import encoder import logging -from flask import Flask, jsonify, request from flask_jwt_extended import JWTManager, jwt_required, create_access_token -from pymongo import MongoClient from logging.handlers import RotatingFileHandler -from .config import Config +from config import Config from datetime import datetime import os from fluent import sender -from .core.consumer_messager import Subscriber +from core.consumer_messager import Subscriber from flask_executor import Executor from flask_apscheduler import APScheduler from opentelemetry.instrumentation.flask import FlaskInstrumentor @@ -117,11 +115,8 @@ app.add_api('openapi.yaml', arguments={'title': 'CAPIF_Access_Control_policy_API'}, pythonic_params=True) - config = Config() - - jwt = JWTManager(app.app) configure_logging(app.app) @@ -138,12 +133,13 @@ subscriber = Subscriber() scheduler = APScheduler() scheduler.api_enabled = True scheduler.init_app(app.app) +scheduler.start() @scheduler.task('date', id='listener', next_run_time=datetime.now()) def up_listener(): with scheduler.app.app_context(): executor.submit(subscriber.listen()) -if __name__ == '__main__': - scheduler.start() - app.run(debug=True,port=8080, use_reloader=False) +# if __name__ == '__main__': +# scheduler.start() +# app.run(debug=True,port=8080, use_reloader=False) diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/config.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/config.py similarity index 92% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/config.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/config.py index 11e1c4f..01f9914 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/config.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/config.py @@ -5,7 +5,7 @@ import os class Config: def __init__(self): self.cached = 0 - self.file="./config.yaml" + self.file="../config.yaml" self.my_config = {} stamp = os.stat(self.file).st_mtime diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/controllers/__init__.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/controllers/__init__.py similarity index 100% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/controllers/__init__.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/controllers/__init__.py diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/controllers/default_controller.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/controllers/default_controller.py similarity index 98% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/controllers/default_controller.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/controllers/default_controller.py index c17e195..eb047f0 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/controllers/default_controller.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/controllers/default_controller.py @@ -1,4 +1,4 @@ -from typing import Dict + from functools import wraps from flask import request, current_app from cryptography import x509 @@ -6,6 +6,7 @@ from cryptography.hazmat.backends import default_backend from ..core.accesscontrolpolicyapi import accessControlPolicyApi + def cert_validation(): def _cert_validation(f): @wraps(f) diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/controllers/security_controller_.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/controllers/security_controller_.py similarity index 100% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/controllers/security_controller_.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/controllers/security_controller_.py diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/accesscontrolpolicyapi.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/accesscontrolpolicyapi.py similarity index 98% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/accesscontrolpolicyapi.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/accesscontrolpolicyapi.py index fd14e80..4a7280d 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/accesscontrolpolicyapi.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/accesscontrolpolicyapi.py @@ -4,6 +4,7 @@ from .responses import make_response, not_found_error, internal_server_error from ..models.access_control_policy_list import AccessControlPolicyList from ..util import dict_to_camel_case, clean_empty + class accessControlPolicyApi(Resource): def get_acl(self, service_api_id, aef_id, api_invoker_id, supported_features): @@ -45,7 +46,7 @@ class accessControlPolicyApi(Resource): return not_found_error(f"No ACLs found for the requested service: {service_api_id}, aef_id: {aef_id}, invoker: {api_invoker_id} and supportedFeatures: {supported_features}", "Wrong id") acl = AccessControlPolicyList(api_invoker_policies) - response = acl.to_dict() + response = clean_empty(acl.to_dict()) return make_response(object=dict_to_camel_case(response), status=200) except Exception as e: diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/consumer_messager.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/consumer_messager.py similarity index 98% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/consumer_messager.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/consumer_messager.py index 72c51ee..0da2440 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/consumer_messager.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/consumer_messager.py @@ -1,6 +1,6 @@ # subscriber.py import redis -from ..config import Config +from config import Config from .internal_service_ops import InternalServiceOps from flask import current_app diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/internal_service_ops.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/internal_service_ops.py similarity index 96% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/internal_service_ops.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/internal_service_ops.py index e10986a..82d1f43 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/internal_service_ops.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/internal_service_ops.py @@ -1,12 +1,14 @@ from flask import current_app from .resources import Resource -from ..models.api_invoker_policy import ApiInvokerPolicy -from ..models.time_range_list import TimeRangeList +from models.api_invoker_policy import ApiInvokerPolicy +from models.time_range_list import TimeRangeList from datetime import datetime, timedelta -from ..core.publisher import Publisher +from core.publisher import Publisher publisher_ops = Publisher() + + class InternalServiceOps(Resource): def create_acl(self, invoker_id, service_id, aef_id): diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/publisher.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/publisher.py similarity index 83% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/publisher.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/publisher.py index 3898c4b..8292de4 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/publisher.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/publisher.py @@ -1,6 +1,5 @@ import redis -import sys -from flask import current_app + class Publisher(): diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/resources.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/resources.py new file mode 100644 index 0000000..d5a3552 --- /dev/null +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/resources.py @@ -0,0 +1,8 @@ +from abc import ABC +from db.db import MongoDatabse + + +class Resource(ABC): + + def __init__(self): + self.db = MongoDatabse() \ No newline at end of file diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/responses.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/responses.py similarity index 72% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/responses.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/responses.py index 962c4b6..9d5ea09 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/responses.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/responses.py @@ -1,31 +1,53 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder from flask import Response +from ..util import dict_to_camel_case, clean_empty import json mimetype = "application/json" + def make_response(object, status): res = Response(json.dumps(object, cls=JSONEncoder), status=status, mimetype=mimetype) return res + def internal_server_error(detail, cause): prob = ProblemDetails(title="Internal Server Error", status=500, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=500, mimetype=mimetype) + def forbidden_error(detail, cause): prob = ProblemDetails(title="Forbidden", status=403, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=403, mimetype=mimetype) + def bad_request_error(detail, cause, invalid_params): prob = ProblemDetails(title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=400, mimetype=cause) + def not_found_error(detail, cause): prob = ProblemDetails(title="Not Found", status=404, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=404, mimetype=mimetype) \ No newline at end of file diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/db/db.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/db/db.py similarity index 97% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/db/db.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/db/db.py index b25c794..d1185c2 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/db/db.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/db/db.py @@ -1,8 +1,8 @@ -import atexit + import time from pymongo import MongoClient from pymongo.errors import AutoReconnect -from ..config import Config +from config import Config from bson.codec_options import CodecOptions import os from opentelemetry.instrumentation.pymongo import PymongoInstrumentor diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/encoder.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/encoder.py similarity index 91% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/encoder.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/encoder.py index 3bbef85..80bad8f 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/encoder.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/encoder.py @@ -1,7 +1,7 @@ from connexion.apps.flask_app import FlaskJSONEncoder import six -from openapi_server.models.base_model_ import Model +from models.base_model_ import Model class JSONEncoder(FlaskJSONEncoder): diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/__init__.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/__init__.py new file mode 100644 index 0000000..4c4e60f --- /dev/null +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/__init__.py @@ -0,0 +1,10 @@ +# coding: utf-8 + +# flake8: noqa +from __future__ import absolute_import +# import models into model package +from capif_acl.models.access_control_policy_list import AccessControlPolicyList +from capif_acl.models.api_invoker_policy import ApiInvokerPolicy +from capif_acl.models.invalid_param import InvalidParam +from capif_acl.models.problem_details import ProblemDetails +from capif_acl.models.time_range_list import TimeRangeList diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/access_control_policy_list.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/access_control_policy_list.py similarity index 90% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/access_control_policy_list.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/access_control_policy_list.py index 98f3fc1..b3cacd4 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/access_control_policy_list.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/access_control_policy_list.py @@ -5,11 +5,11 @@ from datetime import date, datetime # noqa: F401 from typing import List, Dict # noqa: F401 -from openapi_server.models.base_model_ import Model -from openapi_server.models.api_invoker_policy import ApiInvokerPolicy -from openapi_server import util +from capif_acl.models.base_model_ import Model +from capif_acl.models.api_invoker_policy import ApiInvokerPolicy +from capif_acl import util -from openapi_server.models.api_invoker_policy import ApiInvokerPolicy # noqa: E501 +from capif_acl.models.api_invoker_policy import ApiInvokerPolicy # noqa: E501 class AccessControlPolicyList(Model): """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/api_invoker_policy.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/api_invoker_policy.py similarity index 96% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/api_invoker_policy.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/api_invoker_policy.py index a5f1b47..86ffec0 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/api_invoker_policy.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/api_invoker_policy.py @@ -5,11 +5,11 @@ from datetime import date, datetime # noqa: F401 from typing import List, Dict # noqa: F401 -from openapi_server.models.base_model_ import Model -from openapi_server.models.time_range_list import TimeRangeList -from openapi_server import util +from capif_acl.models.base_model_ import Model +from capif_acl.models.time_range_list import TimeRangeList +from capif_acl import util -from openapi_server.models.time_range_list import TimeRangeList # noqa: E501 +from capif_acl.models.time_range_list import TimeRangeList # noqa: E501 class ApiInvokerPolicy(Model): """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/base_model_.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/base_model_.py similarity index 98% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/base_model_.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/base_model_.py index 916e582..cce5379 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/base_model_.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/base_model_.py @@ -3,7 +3,7 @@ import pprint import six import typing -from openapi_server import util +from capif_acl import util T = typing.TypeVar('T') diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/invalid_param.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/invalid_param.py similarity index 96% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/invalid_param.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/invalid_param.py index 8d91e6c..88606c4 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/invalid_param.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/invalid_param.py @@ -5,8 +5,8 @@ from datetime import date, datetime # noqa: F401 from typing import List, Dict # noqa: F401 -from openapi_server.models.base_model_ import Model -from openapi_server import util +from capif_acl.models.base_model_ import Model +from capif_acl import util class InvalidParam(Model): diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/problem_details.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/problem_details.py similarity index 97% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/problem_details.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/problem_details.py index 08f2908..25caab4 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/problem_details.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/problem_details.py @@ -5,12 +5,12 @@ from datetime import date, datetime # noqa: F401 from typing import List, Dict # noqa: F401 -from openapi_server.models.base_model_ import Model -from openapi_server.models.invalid_param import InvalidParam +from capif_acl.models.base_model_ import Model +from capif_acl.models.invalid_param import InvalidParam import re -from openapi_server import util +from capif_acl import util -from openapi_server.models.invalid_param import InvalidParam # noqa: E501 +from capif_acl.models.invalid_param import InvalidParam # noqa: E501 import re # noqa: E501 class ProblemDetails(Model): diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/time_range_list.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/time_range_list.py similarity index 96% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/time_range_list.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/time_range_list.py index eb18a7e..eaacad6 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/time_range_list.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/models/time_range_list.py @@ -5,8 +5,8 @@ from datetime import date, datetime # noqa: F401 from typing import List, Dict # noqa: F401 -from openapi_server.models.base_model_ import Model -from openapi_server import util +from capif_acl.models.base_model_ import Model +from capif_acl import util class TimeRangeList(Model): diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/openapi/openapi.yaml b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/openapi/openapi.yaml similarity index 99% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/openapi/openapi.yaml rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/openapi/openapi.yaml index 6f8c99d..1621baa 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/openapi/openapi.yaml +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/openapi/openapi.yaml @@ -130,7 +130,7 @@ paths: description: Service Unavailable default: description: Generic Error - x-openapi-router-controller: openapi_server.controllers.default_controller + x-openapi-router-controller: capif_acl.controllers.default_controller components: responses: "307": diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/test/__init__.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/test/__init__.py similarity index 89% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/test/__init__.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/test/__init__.py index 364aba9..5d664f8 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/test/__init__.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/test/__init__.py @@ -3,7 +3,7 @@ import logging import connexion from flask_testing import TestCase -from openapi_server.encoder import JSONEncoder +from capif_acl.encoder import JSONEncoder class BaseTestCase(TestCase): diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/test/test_default_controller.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/test/test_default_controller.py similarity index 79% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/test/test_default_controller.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/test/test_default_controller.py index c850757..44ed0be 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/test/test_default_controller.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/test/test_default_controller.py @@ -3,12 +3,7 @@ from __future__ import absolute_import import unittest -from flask import json -from six import BytesIO - -from openapi_server.models.access_control_policy_list import AccessControlPolicyList # noqa: E501 -from openapi_server.models.problem_details import ProblemDetails # noqa: E501 -from openapi_server.test import BaseTestCase +from test import BaseTestCase class TestDefaultController(BaseTestCase): diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/typing_utils.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/typing_utils.py similarity index 100% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/typing_utils.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/typing_utils.py diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/util.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/util.py similarity index 98% rename from services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/util.py rename to services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/util.py index 672406d..2790390 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/util.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/util.py @@ -1,8 +1,8 @@ import datetime import six -import typing -from openapi_server import typing_utils +import typing_utils + def clean_empty(d): if isinstance(d, dict): @@ -15,6 +15,7 @@ def clean_empty(d): return [v for v in map(clean_empty, d) if v] return d + def dict_to_camel_case(my_dict): @@ -41,8 +42,6 @@ def dict_to_camel_case(my_dict): return result - - def _deserialize(data, klass): """Deserializes dict, list, str into an object. diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/wsgi.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/wsgi.py new file mode 100644 index 0000000..e72413c --- /dev/null +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/wsgi.py @@ -0,0 +1,5 @@ +from app import app + +if __name__ == "__main__": + # app.scheduler.start() + app.run() diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/resources.py b/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/resources.py deleted file mode 100644 index 94e29ec..0000000 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/core/resources.py +++ /dev/null @@ -1,7 +0,0 @@ -from abc import ABC, abstractmethod -from ..db.db import MongoDatabse - -class Resource(ABC): - - def __init__(self): - self.db = MongoDatabse() \ No newline at end of file diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/__init__.py b/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/__init__.py deleted file mode 100644 index a4269de..0000000 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/openapi_server/models/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# coding: utf-8 - -# flake8: noqa -from __future__ import absolute_import -# import models into model package -from openapi_server.models.access_control_policy_list import AccessControlPolicyList -from openapi_server.models.api_invoker_policy import ApiInvokerPolicy -from openapi_server.models.invalid_param import InvalidParam -from openapi_server.models.problem_details import ProblemDetails -from openapi_server.models.time_range_list import TimeRangeList diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/requirements.txt b/services/TS29222_CAPIF_Access_Control_Policy_API/requirements.txt index 03d8aaf..087fc12 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/requirements.txt +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/requirements.txt @@ -27,3 +27,5 @@ redis == 4.5.4 flask_executor == 1.0.0 Flask-APScheduler == 1.12.4 Flask-Script == 2.0.6 +gunicorn==22.0.0 +packaging==24.0 \ No newline at end of file -- GitLab From 05998bf22b3e4db817c9cb34e8e5f6e4c1ff9649 Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Tue, 11 Jun 2024 14:27:18 +0300 Subject: [PATCH 10/15] Move Audit API from testing to production server --- .../TS29222_CAPIF_Auditing_API/Dockerfile | 4 ++-- .../logs/{__main__.py => app.py} | 8 +++---- .../TS29222_CAPIF_Auditing_API/logs/config.py | 2 +- .../logs/controllers/default_controller.py | 21 ++++--------------- .../logs/core/auditoperations.py | 14 +++++-------- .../logs/core/resources.py | 4 ++-- .../logs/core/responses.py | 17 +++++++++++++++ .../TS29222_CAPIF_Auditing_API/logs/db/db.py | 5 ++--- .../logs/encoder.py | 2 +- .../TS29222_CAPIF_Auditing_API/logs/util.py | 5 +++-- .../TS29222_CAPIF_Auditing_API/logs/wsgi.py | 4 ++++ .../requirements.txt | 2 ++ 12 files changed, 47 insertions(+), 41 deletions(-) rename services/TS29222_CAPIF_Auditing_API/logs/{__main__.py => app.py} (97%) create mode 100644 services/TS29222_CAPIF_Auditing_API/logs/wsgi.py diff --git a/services/TS29222_CAPIF_Auditing_API/Dockerfile b/services/TS29222_CAPIF_Auditing_API/Dockerfile index d7030b6..4908c19 100644 --- a/services/TS29222_CAPIF_Auditing_API/Dockerfile +++ b/services/TS29222_CAPIF_Auditing_API/Dockerfile @@ -12,6 +12,6 @@ COPY . /usr/src/app EXPOSE 8080 -ENTRYPOINT ["python3"] +ENTRYPOINT ["gunicorn"] -CMD ["-m", "logs"] \ No newline at end of file +CMD ["--bind", "0.0.0.0:8080", "--chdir", "/usr/src/app/logs", "wsgi:app"] \ No newline at end of file diff --git a/services/TS29222_CAPIF_Auditing_API/logs/__main__.py b/services/TS29222_CAPIF_Auditing_API/logs/app.py similarity index 97% rename from services/TS29222_CAPIF_Auditing_API/logs/__main__.py rename to services/TS29222_CAPIF_Auditing_API/logs/app.py index 385f0b5..b89c1a6 100644 --- a/services/TS29222_CAPIF_Auditing_API/logs/__main__.py +++ b/services/TS29222_CAPIF_Auditing_API/logs/app.py @@ -3,8 +3,8 @@ import connexion import logging from logging.handlers import RotatingFileHandler -from logs import encoder -from .config import Config +import encoder +from config import Config import os from fluent import sender from opentelemetry.instrumentation.flask import FlaskInstrumentor @@ -112,5 +112,5 @@ config = Config() if eval(os.environ.get("MONITORING").lower().capitalize()): configure_monitoring(app.app, config.get_config()) -if __name__ == '__main__': - app.run(port=8080) +# if __name__ == '__main__': +# app.run(port=8080) diff --git a/services/TS29222_CAPIF_Auditing_API/logs/config.py b/services/TS29222_CAPIF_Auditing_API/logs/config.py index d04bd1a..97ab831 100644 --- a/services/TS29222_CAPIF_Auditing_API/logs/config.py +++ b/services/TS29222_CAPIF_Auditing_API/logs/config.py @@ -5,7 +5,7 @@ import os class Config: def __init__(self): self.cached = 0 - self.file="./config.yaml" + self.file="../config.yaml" self.my_config = {} stamp = os.stat(self.file).st_mtime diff --git a/services/TS29222_CAPIF_Auditing_API/logs/controllers/default_controller.py b/services/TS29222_CAPIF_Auditing_API/logs/controllers/default_controller.py index c330f47..ead9ec5 100644 --- a/services/TS29222_CAPIF_Auditing_API/logs/controllers/default_controller.py +++ b/services/TS29222_CAPIF_Auditing_API/logs/controllers/default_controller.py @@ -1,21 +1,8 @@ -import connexion -import six -import sys - -from logs.models.interface_description import InterfaceDescription # noqa: E501 -from logs.models.invocation_log import InvocationLog # noqa: E501 -from logs.models.operation import Operation # noqa: E501 -from logs.models.problem_details import ProblemDetails # noqa: E501 -from logs.models.protocol import Protocol # noqa: E501 -from logs import util +from ..util import deserialize_datetime from ..core.auditoperations import AuditOperations -import json from flask import Response, request, current_app -from ..encoder import JSONEncoder -from cryptography import x509 -from cryptography.hazmat.backends import default_backend -import pymongo + from ..core.responses import bad_request_error audit_operations = AuditOperations() @@ -65,8 +52,8 @@ def api_invocation_logs_get(aef_id=None, api_invoker_id=None, time_range_start=N cause="Mandatory parameters missing", invalid_params=[ {"param": "aef_id or api_invoker_id", "reason": "missing"}]) - time_range_start = util.deserialize_datetime(time_range_start) - time_range_end = util.deserialize_datetime(time_range_end) + time_range_start = deserialize_datetime(time_range_start) + time_range_end = deserialize_datetime(time_range_end) query_params = {"aef_id": aef_id, "api_invoker_id": api_invoker_id, diff --git a/services/TS29222_CAPIF_Auditing_API/logs/core/auditoperations.py b/services/TS29222_CAPIF_Auditing_API/logs/core/auditoperations.py index ac83701..6632d28 100644 --- a/services/TS29222_CAPIF_Auditing_API/logs/core/auditoperations.py +++ b/services/TS29222_CAPIF_Auditing_API/logs/core/auditoperations.py @@ -1,11 +1,9 @@ -import sys from flask import current_app, Flask, Response import json -import sys -from datetime import datetime + from .resources import Resource -from bson import json_util + from ..util import dict_to_camel_case, clean_empty from .responses import bad_request_error, not_found_error, forbidden_error, internal_server_error, make_response from ..models.invocation_log import InvocationLog @@ -57,11 +55,9 @@ class AuditOperations (Resource): if not result['logs']: return not_found_error(detail="Parameters do not match any log entry", cause="No logs found") - - result = dict_to_camel_case(clean_empty(result)) - invocation_log = InvocationLog(result['aefId'], result['apiInvokerId'], result['logs'], - result['supportedFeatures']) - res = make_response(object=invocation_log, status=200) + invocation_log = InvocationLog(result['aef_id'], result['api_invoker_id'], result['logs'], + result['supported_features']) + res = make_response(object=dict_to_camel_case(clean_empty(invocation_log.to_dict())), status=200) current_app.logger.debug("Found invocation logs") return res diff --git a/services/TS29222_CAPIF_Auditing_API/logs/core/resources.py b/services/TS29222_CAPIF_Auditing_API/logs/core/resources.py index d55b30c..d5a3552 100644 --- a/services/TS29222_CAPIF_Auditing_API/logs/core/resources.py +++ b/services/TS29222_CAPIF_Auditing_API/logs/core/resources.py @@ -1,5 +1,5 @@ -from abc import ABC, abstractmethod -from ..db.db import MongoDatabse +from abc import ABC +from db.db import MongoDatabse class Resource(ABC): diff --git a/services/TS29222_CAPIF_Auditing_API/logs/core/responses.py b/services/TS29222_CAPIF_Auditing_API/logs/core/responses.py index 5986c50..9d5ea09 100644 --- a/services/TS29222_CAPIF_Auditing_API/logs/core/responses.py +++ b/services/TS29222_CAPIF_Auditing_API/logs/core/responses.py @@ -1,6 +1,7 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder from flask import Response +from ..util import dict_to_camel_case, clean_empty import json mimetype = "application/json" @@ -15,22 +16,38 @@ def make_response(object, status): def internal_server_error(detail, cause): prob = ProblemDetails(title="Internal Server Error", status=500, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=500, mimetype=mimetype) def forbidden_error(detail, cause): prob = ProblemDetails(title="Forbidden", status=403, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=403, mimetype=mimetype) def bad_request_error(detail, cause, invalid_params): prob = ProblemDetails(title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=400, mimetype=cause) def not_found_error(detail, cause): prob = ProblemDetails(title="Not Found", status=404, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=404, mimetype=mimetype) \ No newline at end of file diff --git a/services/TS29222_CAPIF_Auditing_API/logs/db/db.py b/services/TS29222_CAPIF_Auditing_API/logs/db/db.py index f3286d2..17a93fe 100644 --- a/services/TS29222_CAPIF_Auditing_API/logs/db/db.py +++ b/services/TS29222_CAPIF_Auditing_API/logs/db/db.py @@ -1,9 +1,8 @@ -import atexit + import time from pymongo import MongoClient from pymongo.errors import AutoReconnect -from ..config import Config -from bson.codec_options import CodecOptions +from config import Config import os from opentelemetry.instrumentation.pymongo import PymongoInstrumentor diff --git a/services/TS29222_CAPIF_Auditing_API/logs/encoder.py b/services/TS29222_CAPIF_Auditing_API/logs/encoder.py index 55259f5..80bad8f 100644 --- a/services/TS29222_CAPIF_Auditing_API/logs/encoder.py +++ b/services/TS29222_CAPIF_Auditing_API/logs/encoder.py @@ -1,7 +1,7 @@ from connexion.apps.flask_app import FlaskJSONEncoder import six -from logs.models.base_model_ import Model +from models.base_model_ import Model class JSONEncoder(FlaskJSONEncoder): diff --git a/services/TS29222_CAPIF_Auditing_API/logs/util.py b/services/TS29222_CAPIF_Auditing_API/logs/util.py index ff81257..ec14301 100644 --- a/services/TS29222_CAPIF_Auditing_API/logs/util.py +++ b/services/TS29222_CAPIF_Auditing_API/logs/util.py @@ -1,8 +1,8 @@ import datetime import six -import typing -from logs import typing_utils +import typing_utils + def clean_empty(d): if isinstance(d, dict): @@ -15,6 +15,7 @@ def clean_empty(d): return [v for v in map(clean_empty, d) if v] return d + def dict_to_camel_case(my_dict): diff --git a/services/TS29222_CAPIF_Auditing_API/logs/wsgi.py b/services/TS29222_CAPIF_Auditing_API/logs/wsgi.py new file mode 100644 index 0000000..6026b0f --- /dev/null +++ b/services/TS29222_CAPIF_Auditing_API/logs/wsgi.py @@ -0,0 +1,4 @@ +from app import app + +if __name__ == "__main__": + app.run() diff --git a/services/TS29222_CAPIF_Auditing_API/requirements.txt b/services/TS29222_CAPIF_Auditing_API/requirements.txt index 197399f..cb1e439 100644 --- a/services/TS29222_CAPIF_Auditing_API/requirements.txt +++ b/services/TS29222_CAPIF_Auditing_API/requirements.txt @@ -18,3 +18,5 @@ opentelemetry-api == 1.17.0 opentelemetry-sdk == 1.17.0 flask_executor == 1.0.0 pyopenssl == 23.0.0 +gunicorn==22.0.0 +packaging==24.0 \ No newline at end of file -- GitLab From c7f153130470e2a2f6284ba9ec7876cef8131647 Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Tue, 11 Jun 2024 14:46:18 +0300 Subject: [PATCH 11/15] Move Logging API from testing to production server --- .../Dockerfile | 4 ++-- .../{__main__.py => app.py} | 11 +++++----- .../api_invocation_logs/config.py | 2 +- .../controllers/default_controller.py | 6 ++--- .../core/invocationlogs.py | 13 ++++------- .../api_invocation_logs/core/resources.py | 4 ++-- .../api_invocation_logs/core/responses.py | 22 ++++++++++++++++++- .../api_invocation_logs/core/validate_user.py | 5 +++++ .../api_invocation_logs/db/db.py | 5 ++--- .../api_invocation_logs/encoder.py | 2 +- .../api_invocation_logs/util.py | 5 +++-- .../api_invocation_logs/wsgi.py | 4 ++++ .../requirements.txt | 2 ++ 13 files changed, 54 insertions(+), 31 deletions(-) rename services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/{__main__.py => app.py} (97%) create mode 100644 services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/wsgi.py diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/Dockerfile b/services/TS29222_CAPIF_Logging_API_Invocation_API/Dockerfile index 7339cec..4248907 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/Dockerfile +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/Dockerfile @@ -12,6 +12,6 @@ COPY . /usr/src/app EXPOSE 8080 -ENTRYPOINT ["python3"] +ENTRYPOINT ["gunicorn"] -CMD ["-m", "api_invocation_logs"] \ No newline at end of file +CMD ["--bind", "0.0.0.0:8080", "--chdir", "/usr/src/app/api_invocation_logs", "wsgi:app"] \ No newline at end of file diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/__main__.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/app.py similarity index 97% rename from services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/__main__.py rename to services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/app.py index f5323c9..519cc15 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/__main__.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/app.py @@ -3,8 +3,8 @@ import connexion import logging from logging.handlers import RotatingFileHandler -from api_invocation_logs import encoder -from .config import Config +import encoder +from config import Config import os from fluent import sender from opentelemetry.instrumentation.flask import FlaskInstrumentor @@ -16,10 +16,9 @@ from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor - - NAME = "Logging-Service" + def configure_monitoring(app, config): resource = Resource(attributes={"service.name": NAME}) @@ -116,5 +115,5 @@ config = Config() if eval(os.environ.get("MONITORING").lower().capitalize()): configure_monitoring(app.app, config.get_config()) -if __name__ == '__main__': - app.run(port=8080) +# if __name__ == '__main__': +# app.run(port=8080) diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/config.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/config.py index d04bd1a..97ab831 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/config.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/config.py @@ -5,7 +5,7 @@ import os class Config: def __init__(self): self.cached = 0 - self.file="./config.yaml" + self.file="../config.yaml" self.my_config = {} stamp = os.stat(self.file).st_mtime diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/controllers/default_controller.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/controllers/default_controller.py index eb0cd98..7ce9972 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/controllers/default_controller.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/controllers/default_controller.py @@ -1,13 +1,11 @@ import connexion -from api_invocation_logs.models.invocation_log import InvocationLog # noqa: E501 +from ..models.invocation_log import InvocationLog # noqa: E501 from ..core.invocationlogs import LoggingInvocationOperations -import json from flask import Response, request, current_app -from ..encoder import JSONEncoder -from ..models.problem_details import ProblemDetails + from ..core.validate_user import ControlAccess from cryptography import x509 from cryptography.hazmat.backends import default_backend diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py index dde0c64..fe4fc9f 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py @@ -1,18 +1,13 @@ -import sys + import os -import pymongo + import secrets from flask import current_app, Flask, Response -import json -from ..db.db import MongoDatabse -from ..encoder import JSONEncoder -from ..models.problem_details import ProblemDetails from pymongo import ReturnDocument from ..util import dict_to_camel_case, clean_empty from .resources import Resource -from .responses import bad_request_error, internal_server_error, forbidden_error, not_found_error, unauthorized_error, make_response -from ..models.invocation_log import InvocationLog +from .responses import internal_server_error, not_found_error, unauthorized_error, make_response class LoggingInvocationOperations(Resource): @@ -104,7 +99,7 @@ class LoggingInvocationOperations(Resource): existing_invocationlog['logs'].append(updated_invocation_log) mycol.find_one_and_update(my_query, {"$set": existing_invocationlog}, projection={'_id': 0, 'log_id': 0}, return_document=ReturnDocument.AFTER, upsert=False) - res = make_response(object=invocationlog, status=201) + res = make_response(object=dict_to_camel_case(clean_empty(invocationlog.to_dict())), status=201) current_app.logger.debug("Invocation Logs response ready") apis_added = {log.api_id:log.api_name for log in invocationlog.logs} diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/resources.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/resources.py index d55b30c..d5a3552 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/resources.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/resources.py @@ -1,5 +1,5 @@ -from abc import ABC, abstractmethod -from ..db.db import MongoDatabse +from abc import ABC +from db.db import MongoDatabse class Resource(ABC): diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/responses.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/responses.py index 3a136b1..6940f64 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/responses.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/responses.py @@ -1,8 +1,8 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder from flask import Response +from ..util import dict_to_camel_case, clean_empty import json -from bson import json_util mimetype = "application/json" @@ -16,28 +16,48 @@ def make_response(object, status): def internal_server_error(detail, cause): prob = ProblemDetails(title="Internal Server Error", status=500, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=500, mimetype=mimetype) def forbidden_error(detail, cause): prob = ProblemDetails(title="Forbidden", status=403, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=403, mimetype=mimetype) def bad_request_error(detail, cause, invalid_params): prob = ProblemDetails(title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=400, mimetype=cause) def not_found_error(detail, cause): prob = ProblemDetails(title="Not Found", status=404, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=404, mimetype=mimetype) def unauthorized_error(detail, cause): prob = ProblemDetails(title="Unauthorized", status=401, detail=detail, cause=cause) + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=401, mimetype=mimetype) \ No newline at end of file diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/validate_user.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/validate_user.py index 2a89437..13d8b6a 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/validate_user.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/validate_user.py @@ -4,6 +4,8 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder from .resources import Resource from .responses import internal_server_error +from ..util import dict_to_camel_case, clean_empty + class ControlAccess(Resource): @@ -18,6 +20,9 @@ class ControlAccess(Resource): if cert_entry is not None: if cert_entry["cert_signature"] != cert_signature: prob = ProblemDetails(title="Unauthorized", detail="User not authorized", cause="You are not the owner of this resource") + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) return Response(json.dumps(prob, cls=JSONEncoder), status=401, mimetype="application/json") except Exception as e: diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/db/db.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/db/db.py index 96a39f3..f706e5f 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/db/db.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/db/db.py @@ -1,9 +1,8 @@ -import atexit + import time from pymongo import MongoClient from pymongo.errors import AutoReconnect -from ..config import Config -from bson.codec_options import CodecOptions +from config import Config import os from opentelemetry.instrumentation.pymongo import PymongoInstrumentor diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/encoder.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/encoder.py index efa1154..80bad8f 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/encoder.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/encoder.py @@ -1,7 +1,7 @@ from connexion.apps.flask_app import FlaskJSONEncoder import six -from api_invocation_logs.models.base_model_ import Model +from models.base_model_ import Model class JSONEncoder(FlaskJSONEncoder): diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/util.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/util.py index af55567..ec14301 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/util.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/util.py @@ -1,8 +1,8 @@ import datetime import six -import typing -from api_invocation_logs import typing_utils +import typing_utils + def clean_empty(d): if isinstance(d, dict): @@ -15,6 +15,7 @@ def clean_empty(d): return [v for v in map(clean_empty, d) if v] return d + def dict_to_camel_case(my_dict): diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/wsgi.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/wsgi.py new file mode 100644 index 0000000..6026b0f --- /dev/null +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/wsgi.py @@ -0,0 +1,4 @@ +from app import app + +if __name__ == "__main__": + app.run() diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/requirements.txt b/services/TS29222_CAPIF_Logging_API_Invocation_API/requirements.txt index 197399f..cb1e439 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/requirements.txt +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/requirements.txt @@ -18,3 +18,5 @@ opentelemetry-api == 1.17.0 opentelemetry-sdk == 1.17.0 flask_executor == 1.0.0 pyopenssl == 23.0.0 +gunicorn==22.0.0 +packaging==24.0 \ No newline at end of file -- GitLab From fd5925bd2ac5dd93fee01b3445b367343ad5dca8 Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Wed, 12 Jun 2024 17:16:50 +0300 Subject: [PATCH 12/15] [Mock server tests failing] Fix Events testing --- .../capif_events/core/notifications.py | 5 +++-- .../capif_events/core/validate_user.py | 6 ++++++ .../api_invocation_logs/core/invocationlogs.py | 4 ++-- .../register/register_service/core/register_operations.py | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/services/TS29222_CAPIF_Events_API/capif_events/core/notifications.py b/services/TS29222_CAPIF_Events_API/capif_events/core/notifications.py index 1ca9f2f..3b32d11 100644 --- a/services/TS29222_CAPIF_Events_API/capif_events/core/notifications.py +++ b/services/TS29222_CAPIF_Events_API/capif_events/core/notifications.py @@ -10,6 +10,7 @@ import json from flask import current_app import asyncio import aiohttp +from util import dict_to_camel_case, clean_empty class Notifications(): @@ -33,9 +34,9 @@ class Notifications(): event_detail={redis_event.get('key'):redis_event.get('information')} current_app.logger.debug(event_detail) data = EventNotification(sub["subscription_id"], events=redis_event.get('event'), event_detail=event_detail) - current_app.logger.debug(json.dumps(data,cls=JSONEncoder)) + current_app.logger.debug(json.dumps(data.to_dict(),cls=JSONEncoder)) - asyncio.run(self.send(url, json.loads(json.dumps(data,cls=JSONEncoder)))) + asyncio.run(self.send(url, dict_to_camel_case(clean_empty(data.to_dict())))) except Exception as e: current_app.logger.error("An exception occurred ::" + str(e)) diff --git a/services/TS29222_CAPIF_Events_API/capif_events/core/validate_user.py b/services/TS29222_CAPIF_Events_API/capif_events/core/validate_user.py index 18d54a2..be87def 100644 --- a/services/TS29222_CAPIF_Events_API/capif_events/core/validate_user.py +++ b/services/TS29222_CAPIF_Events_API/capif_events/core/validate_user.py @@ -4,6 +4,7 @@ from ..models.problem_details import ProblemDetails from ..encoder import JSONEncoder from .resources import Resource from .responses import internal_server_error +from ..util import dict_to_camel_case, clean_empty class ControlAccess(Resource): @@ -18,6 +19,11 @@ class ControlAccess(Resource): if cert_entry is not None: if cert_entry["cert_signature"] != cert_signature or "event_subscriptions" not in cert_entry["resources"] or event_id not in cert_entry["resources"]["event_subscriptions"]: prob = ProblemDetails(title="Unauthorized", detail="User not authorized", cause="You are not the owner of this resource") + + prob = prob.to_dict() + prob = clean_empty(prob) + prob = dict_to_camel_case(prob) + return Response(json.dumps(prob, cls=JSONEncoder), status=401, mimetype="application/json") except Exception as e: diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py index 752b214..185c056 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py @@ -80,7 +80,7 @@ class LoggingInvocationOperations(Resource): current_app.logger.debug("Check service apis") event=None - invocation_log_base=json.loads(json.dumps(invocationlog, cls=JSONEncoder)) + invocation_log_base=json.loads(json.dumps(invocationlog.to_dict(), cls=JSONEncoder)) for log in invocationlog.logs: result = self.__check_service_apis(log.api_id, log.api_name) @@ -97,7 +97,7 @@ class LoggingInvocationOperations(Resource): event="SERVICE_API_INVOCATION_FAILURE" current_app.logger.info(event) - invocation_log_base['logs']=[log] + invocation_log_base['logs']=[log.to_dict()] invocationLogs=[invocation_log_base] RedisEvent(event,"invocationLogs",invocationLogs).send_event() diff --git a/services/register/register_service/core/register_operations.py b/services/register/register_service/core/register_operations.py index a420fb8..060beca 100644 --- a/services/register/register_service/core/register_operations.py +++ b/services/register/register_service/core/register_operations.py @@ -65,7 +65,7 @@ class RegisterOperations: try: url = f"https://capifcore/helper/deleteEntities/{uuid}" - requests.delete(url, cert=("register_service/certs/superadmin.crt", "register_service/certs/superadmin.key"), verify="register_service/certs/ca_root.crt") + requests.delete(url, cert=("certs/superadmin.crt", "certs/superadmin.key"), verify="certs/ca_root.crt") mycol.delete_one({"uuid": uuid}) -- GitLab From 552781bf1e9c2b1900c977d3980c55b0bcc9873b Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Thu, 13 Jun 2024 13:41:19 +0300 Subject: [PATCH 13/15] Fix bugs in Events API. All tests succeed --- .../capif_events/util.py | 19 +++++++------------ .../core/invocationlogs.py | 2 +- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/services/TS29222_CAPIF_Events_API/capif_events/util.py b/services/TS29222_CAPIF_Events_API/capif_events/util.py index 5a99e67..f067fde 100644 --- a/services/TS29222_CAPIF_Events_API/capif_events/util.py +++ b/services/TS29222_CAPIF_Events_API/capif_events/util.py @@ -10,36 +10,31 @@ def clean_empty(d): return { k: v for k, v in ((k, clean_empty(v)) for k, v in d.items()) - if v + if v is not None or v == 0 } if isinstance(d, list): - return [v for v in map(clean_empty, d) if v] + return [v for v in map(clean_empty, d) if v is not None or v == 0] return d def dict_to_camel_case(my_dict): - - result = {} - for attr, value in my_dict.items(): - - my_key = ''.join(word.title() for word in attr.split('_')) - my_key= ''.join([my_key[0].lower(), my_key[1:]]) - + if len(attr.split('_')) != 1: + my_key = ''.join(word.title() for word in attr.split('_')) + my_key= ''.join([my_key[0].lower(), my_key[1:]]) + else: + my_key = attr if isinstance(value, list): result[my_key] = list(map( lambda x: dict_to_camel_case(x) if isinstance(x, dict) else x, value )) - elif hasattr(value, "to_dict"): result[my_key] = dict_to_camel_case(value) - elif isinstance(value, dict): value = dict_to_camel_case(value) result[my_key] = value else: result[my_key] = value - return result diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py index 185c056..06e597c 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py @@ -99,7 +99,7 @@ class LoggingInvocationOperations(Resource): current_app.logger.info(event) invocation_log_base['logs']=[log.to_dict()] invocationLogs=[invocation_log_base] - RedisEvent(event,"invocationLogs",invocationLogs).send_event() + RedisEvent(event,"invocation_logs",invocationLogs).send_event() current_app.logger.debug("After log check") -- GitLab From 14b221464902f7146f7d3c6d3542a0be9190efb6 Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Thu, 20 Jun 2024 12:51:55 +0300 Subject: [PATCH 14/15] Resolve review comment: Remove commented code --- .../api_invoker_management/app.py | 7 +------ .../prepare_invoker.sh | 2 -- .../api_provider_management/core/responses.py | 4 ---- .../capif_acl/app.py | 4 ---- .../capif_acl/core/internal_service_ops.py | 3 --- .../capif_acl/wsgi.py | 1 - services/TS29222_CAPIF_Auditing_API/logs/app.py | 3 --- .../TS29222_CAPIF_Discover_Service_API/service_apis/app.py | 4 ---- services/TS29222_CAPIF_Events_API/capif_events/app.py | 3 --- .../api_invocation_logs/app.py | 3 --- .../published_apis/app.py | 4 ---- .../capif_routing_info/app.py | 7 ------- .../capif_routing_info/controllers/default_controller.py | 5 ----- services/TS29222_CAPIF_Security_API/capif_security/app.py | 6 ------ services/helper/helper_service/app.py | 2 -- 15 files changed, 1 insertion(+), 57 deletions(-) diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/app.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/app.py index 5d8cc4b..a85597d 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/app.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/app.py @@ -135,9 +135,4 @@ subscriber = Subscriber() @app.app.before_first_request def create_listener_message(): - executor.submit(subscriber.listen) - -# if __name__ == '__main__': -# import logging -# app.run(debug=True, port=8080) - + executor.submit(subscriber.listen) \ No newline at end of file diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/prepare_invoker.sh b/services/TS29222_CAPIF_API_Invoker_Management_API/prepare_invoker.sh index 76843be..df73fa6 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/prepare_invoker.sh +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/prepare_invoker.sh @@ -14,7 +14,5 @@ curl -vv -k -retry 30 \ --request GET "$VAULT_ADDR/v1/secret/data/server_cert/pub" 2>/dev/null | jq -r '.data.data.pub_key' -j > /usr/src/app/api_invoker_management/pubkey.pem -#cd /usr/src/app/ -#python3 -m api_invoker_management gunicorn --bind 0.0.0.0:8080 \ --chdir /usr/src/app/api_invoker_management wsgi:app \ No newline at end of file diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/responses.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/responses.py index f047297..4ad6bb8 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/responses.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/responses.py @@ -14,7 +14,6 @@ def make_response(object, status): def internal_server_error(detail, cause): - # prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Internal Server Error", status=500, detail=detail, cause=cause, invalid_params=[{"param":"","reason":""}], supported_features="fffff") prob = ProblemDetails(title="Internal Server Error", status=500, detail=detail, cause=cause) prob = prob.to_dict() @@ -29,12 +28,10 @@ def forbidden_error(detail, cause): prob = prob.to_dict() prob = clean_empty(prob) - # return Response(json.dumps(dict_to_camel_case(prob.to_dict()), cls=JSONEncoder), status=403, mimetype=mimetype) return Response(json.dumps(dict_to_camel_case(prob), cls=JSONEncoder), status=403, mimetype=mimetype) def bad_request_error(detail, cause, invalid_params): - # prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params, supported_features="fffff") prob = ProblemDetails(title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params) prob = prob.to_dict() @@ -44,7 +41,6 @@ def bad_request_error(detail, cause, invalid_params): def not_found_error(detail, cause): - # prob = ProblemDetails(type="http://www.ietf.org/rfc/rfc2396.txt", instance="http://www.ietf.org/rfc/rfc2396.txt", title="Not Found", status=404, detail=detail, cause=cause, invalid_params=[{"param":"","reason":""}], supported_features="fffff") prob = ProblemDetails(title="Not Found", status=404, detail=detail, cause=cause) prob = prob.to_dict() diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/app.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/app.py index da28365..344df6b 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/app.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/app.py @@ -139,7 +139,3 @@ scheduler.start() def up_listener(): with scheduler.app.app_context(): executor.submit(subscriber.listen()) - -# if __name__ == '__main__': -# scheduler.start() -# app.run(debug=True,port=8080, use_reloader=False) diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/internal_service_ops.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/internal_service_ops.py index 68c7ef5..1e5aa20 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/internal_service_ops.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/internal_service_ops.py @@ -5,12 +5,9 @@ from models.api_invoker_policy import ApiInvokerPolicy from models.time_range_list import TimeRangeList from datetime import datetime, timedelta -from core.publisher import Publisher from .redis_event import RedisEvent from util import dict_to_camel_case, clean_empty -publisher_ops = Publisher() - class InternalServiceOps(Resource): diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/wsgi.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/wsgi.py index e72413c..6026b0f 100644 --- a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/wsgi.py +++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/wsgi.py @@ -1,5 +1,4 @@ from app import app if __name__ == "__main__": - # app.scheduler.start() app.run() diff --git a/services/TS29222_CAPIF_Auditing_API/logs/app.py b/services/TS29222_CAPIF_Auditing_API/logs/app.py index b89c1a6..9a94d5a 100644 --- a/services/TS29222_CAPIF_Auditing_API/logs/app.py +++ b/services/TS29222_CAPIF_Auditing_API/logs/app.py @@ -111,6 +111,3 @@ configure_logging(app.app) config = Config() if eval(os.environ.get("MONITORING").lower().capitalize()): configure_monitoring(app.app, config.get_config()) - -# if __name__ == '__main__': -# app.run(port=8080) diff --git a/services/TS29222_CAPIF_Discover_Service_API/service_apis/app.py b/services/TS29222_CAPIF_Discover_Service_API/service_apis/app.py index 4b4c169..d3cbec7 100644 --- a/services/TS29222_CAPIF_Discover_Service_API/service_apis/app.py +++ b/services/TS29222_CAPIF_Discover_Service_API/service_apis/app.py @@ -121,7 +121,3 @@ if eval(os.environ.get("MONITORING").lower().capitalize()): configure_monitoring(app.app, config.get_config()) jwt = JWTManager(app.app) - - -# if __name__ == '__main__': -# app.run(debug=True, port=8080) diff --git a/services/TS29222_CAPIF_Events_API/capif_events/app.py b/services/TS29222_CAPIF_Events_API/capif_events/app.py index d72ecc6..ead8b52 100644 --- a/services/TS29222_CAPIF_Events_API/capif_events/app.py +++ b/services/TS29222_CAPIF_Events_API/capif_events/app.py @@ -145,6 +145,3 @@ subscriber = Subscriber() @app.app.before_first_request def create_listener_message(): executor.submit(subscriber.listen) - -# if __name__ == '__main__': -# app.run(debug=True, port=8080) diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/app.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/app.py index 519cc15..e7b8397 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/app.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/app.py @@ -114,6 +114,3 @@ config = Config() if eval(os.environ.get("MONITORING").lower().capitalize()): configure_monitoring(app.app, config.get_config()) - -# if __name__ == '__main__': -# app.run(port=8080) diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/app.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/app.py index d3abb2d..d8c3fc5 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/app.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/app.py @@ -135,7 +135,3 @@ subscriber = Subscriber() @app.app.before_first_request def up_listener(): executor.submit(subscriber.listen) - - -# if __name__ == '__main__': -# app.run(debug=True, port=8080) diff --git a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/app.py b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/app.py index e669f46..8913580 100644 --- a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/app.py +++ b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/app.py @@ -4,15 +4,8 @@ import connexion import encoder -# def main(): app = connexion.App(__name__, specification_dir='./openapi/') app.app.json_encoder = encoder.JSONEncoder app.add_api('openapi.yaml', arguments={'title': 'CAPIF_Routing_Info_API'}, pythonic_params=True) - -# app.run(port=8080) - - -# if __name__ == '__main__': -# main() diff --git a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/controllers/default_controller.py b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/controllers/default_controller.py index 442fa80..13c24a3 100644 --- a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/controllers/default_controller.py +++ b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/controllers/default_controller.py @@ -1,9 +1,4 @@ -import connexion -import six - -from ..models.problem_details import ProblemDetails # noqa: E501 from ..models.routing_info import RoutingInfo # noqa: E501 -# from capif_routing_info import util def service_apis_service_api_id_get(service_api_id, aef_id, supp_feat=None): # noqa: E501 diff --git a/services/TS29222_CAPIF_Security_API/capif_security/app.py b/services/TS29222_CAPIF_Security_API/capif_security/app.py index 30fc3a4..975488e 100644 --- a/services/TS29222_CAPIF_Security_API/capif_security/app.py +++ b/services/TS29222_CAPIF_Security_API/capif_security/app.py @@ -134,9 +134,3 @@ executor = Executor(app.app) @app.app.before_first_request def up_listener(): executor.submit(subscriber.listen) - - -# -# if __name__ == '__main__': -# main() - diff --git a/services/helper/helper_service/app.py b/services/helper/helper_service/app.py index 2534195..bdc0007 100644 --- a/services/helper/helper_service/app.py +++ b/services/helper/helper_service/app.py @@ -63,5 +63,3 @@ cert_file.close() app.register_blueprint(helper_routes) app.logger.setLevel(logging.DEBUG) -# if __name__ == '__main__': -# app.run(host='0.0.0.0', port=8080, debug=True) \ No newline at end of file -- GitLab From bce1415cf15d090989031764abdf0a50d9744741 Mon Sep 17 00:00:00 2001 From: Stavros-Anastasios Charismiadis Date: Thu, 20 Jun 2024 15:27:58 +0300 Subject: [PATCH 15/15] Some more commented code --- .../api_provider_management/app.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/app.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/app.py index 7eefe68..3769205 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/app.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/app.py @@ -105,8 +105,6 @@ def verbose_formatter(): datefmt='%d/%m/%Y %H:%M:%S' ) -# def main(): - with open("/usr/src/app/api_provider_management/pubkey.pem", "rb") as pub_file: pub_data = pub_file.read() @@ -127,10 +125,3 @@ app.app.config['JWT_ALGORITHM'] = 'RS256' app.app.config['JWT_PUBLIC_KEY'] = pub_data JWTManager(app.app) - - -# app.run(port=8080, debug=True) - - -# if __name__ == '__main__': -# main() -- GitLab