Loading services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/app.py +10 −13 Original line number Original line Diff line number Diff line Loading @@ -10,6 +10,8 @@ from logging.handlers import RotatingFileHandler import os import os from fluent import sender from fluent import sender from flask_executor import Executor from flask_executor import Executor from flask_apscheduler import APScheduler from datetime import datetime from opentelemetry.instrumentation.flask import FlaskInstrumentor from opentelemetry.instrumentation.flask import FlaskInstrumentor from opentelemetry import trace from opentelemetry import trace from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator Loading Loading @@ -137,16 +139,11 @@ if monitoring_value == "true": executor = Executor(app.app) executor = Executor(app.app) subscriber = Subscriber() subscriber = Subscriber() scheduler = APScheduler() first = True scheduler.init_app(app.app) scheduler.start() @app.app.before_request def create_listener_message(): @scheduler.task('date', id='listener', next_run_time=datetime.now()) global first def up_listener(): if first: with scheduler.app.app_context(): executor.submit(subscriber.listen) executor.submit(subscriber.listen()) first = False # @app.app.before_first_request # def create_listener_message(): # executor.submit(subscriber.listen) No newline at end of file services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py +55 −32 Original line number Original line Diff line number Diff line Loading @@ -3,18 +3,22 @@ from pymongo import ReturnDocument import secrets import secrets import requests import requests from .responses import bad_request_error, not_found_error, forbidden_error, internal_server_error, make_response from .responses import bad_request_error, not_found_error, forbidden_error, internal_server_error, make_response from flask import current_app, Flask, Response from flask import current_app, Response import json import json from datetime import datetime from datetime import datetime from ..util import dict_to_camel_case, clean_empty, serialize_clean_camel_case from ..util import dict_to_camel_case, serialize_clean_camel_case from .auth_manager import AuthManager from .auth_manager import AuthManager from .resources import Resource from .resources import Resource from ..config import Config from ..config import Config from api_invoker_management.models.api_invoker_enrolment_details import APIInvokerEnrolmentDetails from api_invoker_management.models.api_invoker_enrolment_details import APIInvokerEnrolmentDetails from .redis_event import RedisEvent from .redis_event import RedisEvent from .redis_internal_event import RedisInternalEvent from .publisher import Publisher from .publisher import Publisher import os publisher_ops = Publisher() publisher_ops = Publisher() class InvokerManagementOperations(Resource): class InvokerManagementOperations(Resource): def __check_api_invoker_id(self, api_invoker_id): def __check_api_invoker_id(self, api_invoker_id): Loading @@ -41,7 +45,8 @@ class InvokerManagementOperations(Resource): 'common_name': invoker_id 'common_name': invoker_id } } response = requests.request("POST", url, headers=headers, data=data, verify = self.config["ca_factory"].get("verify", False)) response = requests.request("POST", url, headers=headers, data=data, verify=self.config["ca_factory"].get("verify", False)) print(response) print(response) response_payload = json.loads(response.text) response_payload = json.loads(response.text) Loading @@ -52,17 +57,18 @@ class InvokerManagementOperations(Resource): self.auth_manager = AuthManager() self.auth_manager = AuthManager() self.config = Config().get_config() self.config = Config().get_config() def add_apiinvokerenrolmentdetail(self, apiinvokerenrolmentdetail, username, uuid): def add_apiinvokerenrolmentdetail(self, apiinvokerenrolmentdetail, username, uuid): mycol = self.db.get_col_by_name(self.db.invoker_enrolment_details) mycol = self.db.get_col_by_name(self.db.invoker_enrolment_details) # try: # try: current_app.logger.debug("Creating invoker resource") current_app.logger.debug("Creating invoker resource") res = mycol.find_one({'onboarding_information.api_invoker_public_key': apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key}) res = mycol.find_one({'onboarding_information.api_invoker_public_key': apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key}) if res is not None: if res is not None: current_app.logger.error("Generating forbbiden error, invoker registered") current_app.logger.error( "Generating forbbiden error, invoker registered") return forbidden_error(detail="Invoker already registered", cause="Identical invoker public key") return forbidden_error(detail="Invoker already registered", cause="Identical invoker public key") if rfc3987.match(apiinvokerenrolmentdetail.notification_destination, rule="URI") is None: if rfc3987.match(apiinvokerenrolmentdetail.notification_destination, rule="URI") is None: Loading @@ -72,11 +78,13 @@ class InvokerManagementOperations(Resource): current_app.logger.debug("Signing Certificate") current_app.logger.debug("Signing Certificate") api_invoker_id = 'INV'+str(secrets.token_hex(15)) api_invoker_id = 'INV'+str(secrets.token_hex(15)) cert = self.__sign_cert(apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key, api_invoker_id) cert = self.__sign_cert( apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key, api_invoker_id) apiinvokerenrolmentdetail.api_invoker_id = api_invoker_id apiinvokerenrolmentdetail.api_invoker_id = api_invoker_id current_app.logger.debug(cert) current_app.logger.debug(cert) apiinvokerenrolmentdetail.onboarding_information.api_invoker_certificate = cert['data']['certificate'] apiinvokerenrolmentdetail.onboarding_information.api_invoker_certificate = cert[ 'data']['certificate'] # Onboarding Date Record # Onboarding Date Record invoker_dict = apiinvokerenrolmentdetail.to_dict() invoker_dict = apiinvokerenrolmentdetail.to_dict() Loading @@ -89,14 +97,17 @@ class InvokerManagementOperations(Resource): current_app.logger.debug("Invoker inserted in database") current_app.logger.debug("Invoker inserted in database") current_app.logger.debug("Netapp onboarded sucessfuly") current_app.logger.debug("Netapp onboarded sucessfuly") self.auth_manager.add_auth_invoker(cert['data']['certificate'], api_invoker_id) self.auth_manager.add_auth_invoker( cert['data']['certificate'], api_invoker_id) res = make_response(object=serialize_clean_camel_case(apiinvokerenrolmentdetail), status=201) res = make_response(object=serialize_clean_camel_case( res.headers['Location'] = "/api-invoker-management/v1/onboardedInvokers/" + str(api_invoker_id) apiinvokerenrolmentdetail), status=201) res.headers['Location'] = f"https://{os.getenv("CAPIF_HOSTNAME")}/api-invoker-management/v1/onboardedInvokers/{str(api_invoker_id)}" if res.status_code == 201: if res.status_code == 201: current_app.logger.info("Invoker Created") current_app.logger.info("Invoker Created") RedisEvent("API_INVOKER_ONBOARDED", ["apiInvokerIds"], [[str(api_invoker_id)]]).send_event() RedisEvent("API_INVOKER_ONBOARDED", api_invoker_ids=[str(api_invoker_id)]).send_event() return res return res def update_apiinvokerenrolmentdetail(self, onboard_id, apiinvokerenrolmentdetail): def update_apiinvokerenrolmentdetail(self, onboard_id, apiinvokerenrolmentdetail): Loading @@ -111,16 +122,23 @@ class InvokerManagementOperations(Resource): return result return result if apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key != result["onboarding_information"]["api_invoker_public_key"]: if apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key != result["onboarding_information"]["api_invoker_public_key"]: cert = self.__sign_cert(apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key, result["api_invoker_id"]) cert = self.__sign_cert( apiinvokerenrolmentdetail.onboarding_information.api_invoker_certificate = cert['data']['certificate'] apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key, result["api_invoker_id"]) self.auth_manager.update_auth_invoker(cert['data']["certificate"], onboard_id) apiinvokerenrolmentdetail.onboarding_information.api_invoker_certificate = cert[ 'data']['certificate'] self.auth_manager.update_auth_invoker( cert['data']["certificate"], onboard_id) apiinvokerenrolmentdetail_update = apiinvokerenrolmentdetail.to_dict() apiinvokerenrolmentdetail_update = apiinvokerenrolmentdetail.to_dict() apiinvokerenrolmentdetail_update = { apiinvokerenrolmentdetail_update = { key: value for key, value in apiinvokerenrolmentdetail_update.items() if value is not None key: value for key, value in apiinvokerenrolmentdetail_update.items() if value is not None } } result = mycol.find_one_and_update(result, {"$set":apiinvokerenrolmentdetail_update}, projection={'_id': 0},return_document=ReturnDocument.AFTER ,upsert=False) result = mycol.find_one_and_update(result, {"$set": apiinvokerenrolmentdetail_update}, projection={'_id': 0}, return_document=ReturnDocument.AFTER, upsert=False) result = { result = { key: value for key, value in result.items() if value is not None key: value for key, value in result.items() if value is not None Loading @@ -130,10 +148,12 @@ class InvokerManagementOperations(Resource): invoker_updated = APIInvokerEnrolmentDetails().from_dict(dict_to_camel_case(result)) invoker_updated = APIInvokerEnrolmentDetails().from_dict(dict_to_camel_case(result)) res = make_response(object=serialize_clean_camel_case(invoker_updated), status=200) res = make_response(object=serialize_clean_camel_case( invoker_updated), status=200) if res.status_code == 200: if res.status_code == 200: current_app.logger.info("Invoker Updated") current_app.logger.info("Invoker Updated") RedisEvent("API_INVOKER_UPDATED", ["apiInvokerIds"], [[onboard_id]]).send_event() RedisEvent("API_INVOKER_UPDATED", api_invoker_ids=[onboard_id]).send_event() return res return res except Exception as e: except Exception as e: Loading @@ -160,13 +180,16 @@ class InvokerManagementOperations(Resource): res = make_response(out, status=204) res = make_response(out, status=204) if res.status_code == 204: if res.status_code == 204: current_app.logger.info("Invoker Removed") current_app.logger.info("Invoker Removed") RedisEvent("API_INVOKER_OFFBOARDED", ["apiInvokerIds"], [[onboard_id]]).send_event() RedisEvent("API_INVOKER_OFFBOARDED", publisher_ops.publish_message("internal-messages", f"invoker-removed:{onboard_id}") api_invoker_ids=[onboard_id]).send_event() RedisInternalEvent("INVOKER-REMOVED", "invokerId", { "api_invoker_id": onboard_id }).send_event() return res return res except Exception as e: except Exception as e: exception = "An exception occurred in remove invoker" exception = "An exception occurred in remove invoker" current_app.logger.error(exception + "::" + str(e)) current_app.logger.error(exception + "::" + str(e)) return internal_server_error(detail=exception, cause=str(e)) return internal_server_error(detail=exception, cause=str(e)) services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/consumer_messager.py +37 −10 Original line number Original line Diff line number Diff line Loading @@ -2,6 +2,8 @@ import redis import redis from .invoker_internal_ops import InvokerInternalOperations from .invoker_internal_ops import InvokerInternalOperations from flask import current_app from flask import current_app import json class Subscriber(): class Subscriber(): Loading @@ -14,13 +16,38 @@ class Subscriber(): def listen(self): def listen(self): for raw_message in self.p.listen(): for raw_message in self.p.listen(): if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "internal-messages": if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "internal-messages": message, invoker_id, api_id = raw_message["data"].decode('utf-8').split(":") current_app.logger.info("New internal event received") if message == "security-context-created": internal_redis_event = json.loads( current_app.logger.debug("Internal message received, updating Api list on invoker") raw_message["data"].decode('utf-8')) self.invoker_ops.update_services_list(invoker_id, api_id) if internal_redis_event.get('event') == "SECURITY-CONTEXT-CREATED": if message == "security-context-removed": current_app.logger.debug( current_app.logger.debug("Internal message received, removing service in Api list of invoker") "Internal message received, updating Api list on invoker") self.invoker_ops.remove_services_list(invoker_id, api_id) security_context_information = internal_redis_event.get( 'information', None) if security_context_information is not None: api_invoker_id = security_context_information.get( 'api_invoker_id') api_id = security_context_information.get('api_id') self.invoker_ops.update_services_list( api_invoker_id, api_id) elif internal_redis_event.get('event') == "SECURITY-CONTEXT-REMOVED": current_app.logger.debug( "Internal message received, removing service in Api list of invoker") security_context_information = internal_redis_event.get( 'information', None) if security_context_information is not None: api_invoker_id = security_context_information.get( 'api_invoker_id') api_id = security_context_information.get('api_id') self.invoker_ops.remove_services_list( api_invoker_id, api_id) # elif internal_redis_event.get('event') == "INVOKER-REMOVED": # api_invoker_id = internal_redis_event.get( # 'information', {"api_invoker_id": None}).get('api_invoker_id') # if api_invoker_id is not None: # self.acls_ops.remove_invoker_acl(api_invoker_id) # elif internal_redis_event.get('event') == "PROVIDER-REMOVED": # aef_ids = internal_redis_event.get( # 'information', {"aef_ids": []}).get('aef_ids') # if len(aef_ids) > 0: # self.acls_ops.remove_provider_acls(aef_ids[0]) services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/redis_event.py +25 −4 Original line number Original line Diff line number Diff line Loading @@ -6,7 +6,14 @@ publisher_ops = Publisher() class RedisEvent(): class RedisEvent(): def __init__(self, event, event_detail_key=None, information=None) -> None: def __init__(self, event, service_api_descriptions=None, api_ids=None, api_invoker_ids=None, acc_ctrl_pol_list=None, invocation_logs=None, api_topo_hide=None) -> None: self.EVENTS_ENUM = [ self.EVENTS_ENUM = [ 'SERVICE_API_AVAILABLE', 'SERVICE_API_AVAILABLE', 'SERVICE_API_UNAVAILABLE', 'SERVICE_API_UNAVAILABLE', Loading @@ -27,9 +34,23 @@ class RedisEvent(): self.redis_event = { self.redis_event = { "event": event "event": event } } if event_detail_key != None and information != None: # Add event filter keys to an auxiliary object self.redis_event['key'] = event_detail_key event_detail = { self.redis_event['information'] = information "serviceAPIDescriptions": service_api_descriptions, "apiIds": api_ids, "apiInvokerIds": api_invoker_ids, "accCtrlPolList": acc_ctrl_pol_list, "invocationLogs": invocation_logs, "apiTopoHide": api_topo_hide } # Filter keys with not None values filtered_event_detail = {k: v for k, v in event_detail.items() if v is not None} # If there are valid values then add to redis event. if filtered_event_detail: self.redis_event["event_detail"] = filtered_event_detail def to_string(self): def to_string(self): return json.dumps(self.redis_event, cls=JSONEncoder) return json.dumps(self.redis_event, cls=JSONEncoder) Loading services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/redis_internal_event.py 0 → 100644 +35 −0 Original line number Original line Diff line number Diff line from ..encoder import JSONEncoder from .publisher import Publisher import json publisher_ops = Publisher() class RedisInternalEvent(): def __init__(self, event, event_detail_key=None, information=None) -> None: self.INTERNAL_MESSAGES = [ 'INVOKER-REMOVED', 'PROVIDER-REMOVED', 'SECURITY-CONTEXT-CREATED', 'SECURITY-CONTEXT-REMOVED', 'create-acl', 'remove-acl', ] if event not in self.INTERNAL_MESSAGES: raise Exception( "Internal Message (" + event + ") is not on INTERNAL_MESSAGES enum (" + ','.join(self.INTERNAL_MESSAGES) + ")") self.redis_event = { "event": event } if event_detail_key is not None and information is not None: self.redis_event['key'] = event_detail_key self.redis_event['information'] = information def to_string(self): return json.dumps(self.redis_event, cls=JSONEncoder) def send_event(self): publisher_ops.publish_message("internal-messages", self.to_string()) def __call__(self): return self.redis_event Loading
services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/app.py +10 −13 Original line number Original line Diff line number Diff line Loading @@ -10,6 +10,8 @@ from logging.handlers import RotatingFileHandler import os import os from fluent import sender from fluent import sender from flask_executor import Executor from flask_executor import Executor from flask_apscheduler import APScheduler from datetime import datetime from opentelemetry.instrumentation.flask import FlaskInstrumentor from opentelemetry.instrumentation.flask import FlaskInstrumentor from opentelemetry import trace from opentelemetry import trace from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator Loading Loading @@ -137,16 +139,11 @@ if monitoring_value == "true": executor = Executor(app.app) executor = Executor(app.app) subscriber = Subscriber() subscriber = Subscriber() scheduler = APScheduler() first = True scheduler.init_app(app.app) scheduler.start() @app.app.before_request def create_listener_message(): @scheduler.task('date', id='listener', next_run_time=datetime.now()) global first def up_listener(): if first: with scheduler.app.app_context(): executor.submit(subscriber.listen) executor.submit(subscriber.listen()) first = False # @app.app.before_first_request # def create_listener_message(): # executor.submit(subscriber.listen) No newline at end of file
services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py +55 −32 Original line number Original line Diff line number Diff line Loading @@ -3,18 +3,22 @@ from pymongo import ReturnDocument import secrets import secrets import requests import requests from .responses import bad_request_error, not_found_error, forbidden_error, internal_server_error, make_response from .responses import bad_request_error, not_found_error, forbidden_error, internal_server_error, make_response from flask import current_app, Flask, Response from flask import current_app, Response import json import json from datetime import datetime from datetime import datetime from ..util import dict_to_camel_case, clean_empty, serialize_clean_camel_case from ..util import dict_to_camel_case, serialize_clean_camel_case from .auth_manager import AuthManager from .auth_manager import AuthManager from .resources import Resource from .resources import Resource from ..config import Config from ..config import Config from api_invoker_management.models.api_invoker_enrolment_details import APIInvokerEnrolmentDetails from api_invoker_management.models.api_invoker_enrolment_details import APIInvokerEnrolmentDetails from .redis_event import RedisEvent from .redis_event import RedisEvent from .redis_internal_event import RedisInternalEvent from .publisher import Publisher from .publisher import Publisher import os publisher_ops = Publisher() publisher_ops = Publisher() class InvokerManagementOperations(Resource): class InvokerManagementOperations(Resource): def __check_api_invoker_id(self, api_invoker_id): def __check_api_invoker_id(self, api_invoker_id): Loading @@ -41,7 +45,8 @@ class InvokerManagementOperations(Resource): 'common_name': invoker_id 'common_name': invoker_id } } response = requests.request("POST", url, headers=headers, data=data, verify = self.config["ca_factory"].get("verify", False)) response = requests.request("POST", url, headers=headers, data=data, verify=self.config["ca_factory"].get("verify", False)) print(response) print(response) response_payload = json.loads(response.text) response_payload = json.loads(response.text) Loading @@ -52,17 +57,18 @@ class InvokerManagementOperations(Resource): self.auth_manager = AuthManager() self.auth_manager = AuthManager() self.config = Config().get_config() self.config = Config().get_config() def add_apiinvokerenrolmentdetail(self, apiinvokerenrolmentdetail, username, uuid): def add_apiinvokerenrolmentdetail(self, apiinvokerenrolmentdetail, username, uuid): mycol = self.db.get_col_by_name(self.db.invoker_enrolment_details) mycol = self.db.get_col_by_name(self.db.invoker_enrolment_details) # try: # try: current_app.logger.debug("Creating invoker resource") current_app.logger.debug("Creating invoker resource") res = mycol.find_one({'onboarding_information.api_invoker_public_key': apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key}) res = mycol.find_one({'onboarding_information.api_invoker_public_key': apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key}) if res is not None: if res is not None: current_app.logger.error("Generating forbbiden error, invoker registered") current_app.logger.error( "Generating forbbiden error, invoker registered") return forbidden_error(detail="Invoker already registered", cause="Identical invoker public key") return forbidden_error(detail="Invoker already registered", cause="Identical invoker public key") if rfc3987.match(apiinvokerenrolmentdetail.notification_destination, rule="URI") is None: if rfc3987.match(apiinvokerenrolmentdetail.notification_destination, rule="URI") is None: Loading @@ -72,11 +78,13 @@ class InvokerManagementOperations(Resource): current_app.logger.debug("Signing Certificate") current_app.logger.debug("Signing Certificate") api_invoker_id = 'INV'+str(secrets.token_hex(15)) api_invoker_id = 'INV'+str(secrets.token_hex(15)) cert = self.__sign_cert(apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key, api_invoker_id) cert = self.__sign_cert( apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key, api_invoker_id) apiinvokerenrolmentdetail.api_invoker_id = api_invoker_id apiinvokerenrolmentdetail.api_invoker_id = api_invoker_id current_app.logger.debug(cert) current_app.logger.debug(cert) apiinvokerenrolmentdetail.onboarding_information.api_invoker_certificate = cert['data']['certificate'] apiinvokerenrolmentdetail.onboarding_information.api_invoker_certificate = cert[ 'data']['certificate'] # Onboarding Date Record # Onboarding Date Record invoker_dict = apiinvokerenrolmentdetail.to_dict() invoker_dict = apiinvokerenrolmentdetail.to_dict() Loading @@ -89,14 +97,17 @@ class InvokerManagementOperations(Resource): current_app.logger.debug("Invoker inserted in database") current_app.logger.debug("Invoker inserted in database") current_app.logger.debug("Netapp onboarded sucessfuly") current_app.logger.debug("Netapp onboarded sucessfuly") self.auth_manager.add_auth_invoker(cert['data']['certificate'], api_invoker_id) self.auth_manager.add_auth_invoker( cert['data']['certificate'], api_invoker_id) res = make_response(object=serialize_clean_camel_case(apiinvokerenrolmentdetail), status=201) res = make_response(object=serialize_clean_camel_case( res.headers['Location'] = "/api-invoker-management/v1/onboardedInvokers/" + str(api_invoker_id) apiinvokerenrolmentdetail), status=201) res.headers['Location'] = f"https://{os.getenv("CAPIF_HOSTNAME")}/api-invoker-management/v1/onboardedInvokers/{str(api_invoker_id)}" if res.status_code == 201: if res.status_code == 201: current_app.logger.info("Invoker Created") current_app.logger.info("Invoker Created") RedisEvent("API_INVOKER_ONBOARDED", ["apiInvokerIds"], [[str(api_invoker_id)]]).send_event() RedisEvent("API_INVOKER_ONBOARDED", api_invoker_ids=[str(api_invoker_id)]).send_event() return res return res def update_apiinvokerenrolmentdetail(self, onboard_id, apiinvokerenrolmentdetail): def update_apiinvokerenrolmentdetail(self, onboard_id, apiinvokerenrolmentdetail): Loading @@ -111,16 +122,23 @@ class InvokerManagementOperations(Resource): return result return result if apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key != result["onboarding_information"]["api_invoker_public_key"]: if apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key != result["onboarding_information"]["api_invoker_public_key"]: cert = self.__sign_cert(apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key, result["api_invoker_id"]) cert = self.__sign_cert( apiinvokerenrolmentdetail.onboarding_information.api_invoker_certificate = cert['data']['certificate'] apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key, result["api_invoker_id"]) self.auth_manager.update_auth_invoker(cert['data']["certificate"], onboard_id) apiinvokerenrolmentdetail.onboarding_information.api_invoker_certificate = cert[ 'data']['certificate'] self.auth_manager.update_auth_invoker( cert['data']["certificate"], onboard_id) apiinvokerenrolmentdetail_update = apiinvokerenrolmentdetail.to_dict() apiinvokerenrolmentdetail_update = apiinvokerenrolmentdetail.to_dict() apiinvokerenrolmentdetail_update = { apiinvokerenrolmentdetail_update = { key: value for key, value in apiinvokerenrolmentdetail_update.items() if value is not None key: value for key, value in apiinvokerenrolmentdetail_update.items() if value is not None } } result = mycol.find_one_and_update(result, {"$set":apiinvokerenrolmentdetail_update}, projection={'_id': 0},return_document=ReturnDocument.AFTER ,upsert=False) result = mycol.find_one_and_update(result, {"$set": apiinvokerenrolmentdetail_update}, projection={'_id': 0}, return_document=ReturnDocument.AFTER, upsert=False) result = { result = { key: value for key, value in result.items() if value is not None key: value for key, value in result.items() if value is not None Loading @@ -130,10 +148,12 @@ class InvokerManagementOperations(Resource): invoker_updated = APIInvokerEnrolmentDetails().from_dict(dict_to_camel_case(result)) invoker_updated = APIInvokerEnrolmentDetails().from_dict(dict_to_camel_case(result)) res = make_response(object=serialize_clean_camel_case(invoker_updated), status=200) res = make_response(object=serialize_clean_camel_case( invoker_updated), status=200) if res.status_code == 200: if res.status_code == 200: current_app.logger.info("Invoker Updated") current_app.logger.info("Invoker Updated") RedisEvent("API_INVOKER_UPDATED", ["apiInvokerIds"], [[onboard_id]]).send_event() RedisEvent("API_INVOKER_UPDATED", api_invoker_ids=[onboard_id]).send_event() return res return res except Exception as e: except Exception as e: Loading @@ -160,13 +180,16 @@ class InvokerManagementOperations(Resource): res = make_response(out, status=204) res = make_response(out, status=204) if res.status_code == 204: if res.status_code == 204: current_app.logger.info("Invoker Removed") current_app.logger.info("Invoker Removed") RedisEvent("API_INVOKER_OFFBOARDED", ["apiInvokerIds"], [[onboard_id]]).send_event() RedisEvent("API_INVOKER_OFFBOARDED", publisher_ops.publish_message("internal-messages", f"invoker-removed:{onboard_id}") api_invoker_ids=[onboard_id]).send_event() RedisInternalEvent("INVOKER-REMOVED", "invokerId", { "api_invoker_id": onboard_id }).send_event() return res return res except Exception as e: except Exception as e: exception = "An exception occurred in remove invoker" exception = "An exception occurred in remove invoker" current_app.logger.error(exception + "::" + str(e)) current_app.logger.error(exception + "::" + str(e)) return internal_server_error(detail=exception, cause=str(e)) return internal_server_error(detail=exception, cause=str(e))
services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/consumer_messager.py +37 −10 Original line number Original line Diff line number Diff line Loading @@ -2,6 +2,8 @@ import redis import redis from .invoker_internal_ops import InvokerInternalOperations from .invoker_internal_ops import InvokerInternalOperations from flask import current_app from flask import current_app import json class Subscriber(): class Subscriber(): Loading @@ -14,13 +16,38 @@ class Subscriber(): def listen(self): def listen(self): for raw_message in self.p.listen(): for raw_message in self.p.listen(): if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "internal-messages": if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "internal-messages": message, invoker_id, api_id = raw_message["data"].decode('utf-8').split(":") current_app.logger.info("New internal event received") if message == "security-context-created": internal_redis_event = json.loads( current_app.logger.debug("Internal message received, updating Api list on invoker") raw_message["data"].decode('utf-8')) self.invoker_ops.update_services_list(invoker_id, api_id) if internal_redis_event.get('event') == "SECURITY-CONTEXT-CREATED": if message == "security-context-removed": current_app.logger.debug( current_app.logger.debug("Internal message received, removing service in Api list of invoker") "Internal message received, updating Api list on invoker") self.invoker_ops.remove_services_list(invoker_id, api_id) security_context_information = internal_redis_event.get( 'information', None) if security_context_information is not None: api_invoker_id = security_context_information.get( 'api_invoker_id') api_id = security_context_information.get('api_id') self.invoker_ops.update_services_list( api_invoker_id, api_id) elif internal_redis_event.get('event') == "SECURITY-CONTEXT-REMOVED": current_app.logger.debug( "Internal message received, removing service in Api list of invoker") security_context_information = internal_redis_event.get( 'information', None) if security_context_information is not None: api_invoker_id = security_context_information.get( 'api_invoker_id') api_id = security_context_information.get('api_id') self.invoker_ops.remove_services_list( api_invoker_id, api_id) # elif internal_redis_event.get('event') == "INVOKER-REMOVED": # api_invoker_id = internal_redis_event.get( # 'information', {"api_invoker_id": None}).get('api_invoker_id') # if api_invoker_id is not None: # self.acls_ops.remove_invoker_acl(api_invoker_id) # elif internal_redis_event.get('event') == "PROVIDER-REMOVED": # aef_ids = internal_redis_event.get( # 'information', {"aef_ids": []}).get('aef_ids') # if len(aef_ids) > 0: # self.acls_ops.remove_provider_acls(aef_ids[0])
services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/redis_event.py +25 −4 Original line number Original line Diff line number Diff line Loading @@ -6,7 +6,14 @@ publisher_ops = Publisher() class RedisEvent(): class RedisEvent(): def __init__(self, event, event_detail_key=None, information=None) -> None: def __init__(self, event, service_api_descriptions=None, api_ids=None, api_invoker_ids=None, acc_ctrl_pol_list=None, invocation_logs=None, api_topo_hide=None) -> None: self.EVENTS_ENUM = [ self.EVENTS_ENUM = [ 'SERVICE_API_AVAILABLE', 'SERVICE_API_AVAILABLE', 'SERVICE_API_UNAVAILABLE', 'SERVICE_API_UNAVAILABLE', Loading @@ -27,9 +34,23 @@ class RedisEvent(): self.redis_event = { self.redis_event = { "event": event "event": event } } if event_detail_key != None and information != None: # Add event filter keys to an auxiliary object self.redis_event['key'] = event_detail_key event_detail = { self.redis_event['information'] = information "serviceAPIDescriptions": service_api_descriptions, "apiIds": api_ids, "apiInvokerIds": api_invoker_ids, "accCtrlPolList": acc_ctrl_pol_list, "invocationLogs": invocation_logs, "apiTopoHide": api_topo_hide } # Filter keys with not None values filtered_event_detail = {k: v for k, v in event_detail.items() if v is not None} # If there are valid values then add to redis event. if filtered_event_detail: self.redis_event["event_detail"] = filtered_event_detail def to_string(self): def to_string(self): return json.dumps(self.redis_event, cls=JSONEncoder) return json.dumps(self.redis_event, cls=JSONEncoder) Loading
services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/redis_internal_event.py 0 → 100644 +35 −0 Original line number Original line Diff line number Diff line from ..encoder import JSONEncoder from .publisher import Publisher import json publisher_ops = Publisher() class RedisInternalEvent(): def __init__(self, event, event_detail_key=None, information=None) -> None: self.INTERNAL_MESSAGES = [ 'INVOKER-REMOVED', 'PROVIDER-REMOVED', 'SECURITY-CONTEXT-CREATED', 'SECURITY-CONTEXT-REMOVED', 'create-acl', 'remove-acl', ] if event not in self.INTERNAL_MESSAGES: raise Exception( "Internal Message (" + event + ") is not on INTERNAL_MESSAGES enum (" + ','.join(self.INTERNAL_MESSAGES) + ")") self.redis_event = { "event": event } if event_detail_key is not None and information is not None: self.redis_event['key'] = event_detail_key self.redis_event['information'] = information def to_string(self): return json.dumps(self.redis_event, cls=JSONEncoder) def send_event(self): publisher_ops.publish_message("internal-messages", self.to_string()) def __call__(self): return self.redis_event