Loading services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py +41 −26 Original line number Diff line number Diff line Loading @@ -58,26 +58,6 @@ def find_duplicate_service_by_api_name_and_aef( return collection.find_one(duplicate_query), aef_ids def shared_capif_prov_doms(shareable_info): """Return the CAPIF provider domains a service API is meant to be shared with.""" shareable_info = shareable_info or {} if not shareable_info.get("is_shareable"): return [] return shareable_info.get("capif_prov_doms") or [] def interconnection_payload(service_api): """Serialize a service API the way a peer CCF expects to receive it.""" payload = { key: value for key, value in service_api.items() if key not in ("_id", "apf_id", "onboarding_date") } # The peer stores the service API as its own, it must not share it any further payload["shareable_info"] = {"is_shareable": False} return json.dumps(clean_n_camel_case(payload), cls=encoder.CustomJSONEncoder) def return_negotiated_supp_feat_dict(supp_feat): Loading Loading @@ -216,7 +196,7 @@ class PublishServiceOperations(Resource): ) published, interconnection_error = self.publish_to_interconnected_ccfs( rec, shared_capif_prov_doms(rec.get("shareable_info"))) rec, self.shared_capif_prov_doms(rec.get("shareable_info"))) if interconnection_error is not None: # Nothing is stored here, so a copy left on a peer would be an orphan and Loading Loading @@ -424,7 +404,7 @@ class PublishServiceOperations(Resource): 'accept': 'application/json', 'Content-Type': 'application/json' } body = interconnection_payload(service_api) body = self.interconnection_payload(service_api) for dom in capif_prov_doms: if interconnected_col.find_one({"dst_prov_dom": dom}) is None: Loading Loading @@ -482,7 +462,7 @@ class PublishServiceOperations(Resource): 'accept': 'application/json', 'Content-Type': 'application/json' } body = interconnection_payload(service_api) body = self.interconnection_payload(service_api) published = [] for dom in capif_prov_doms: Loading Loading @@ -539,8 +519,8 @@ class PublishServiceOperations(Resource): store and an error response if any peer could not be aligned, in which case the caller must leave the service API untouched. """ old_doms = shared_capif_prov_doms(old_service_api.get("shareable_info")) new_doms = shared_capif_prov_doms(service_api.get("shareable_info")) old_doms = self.shared_capif_prov_doms(old_service_api.get("shareable_info")) new_doms = self.shared_capif_prov_doms(service_api.get("shareable_info")) pub_api_path = old_service_api.get("pub_api_path") if not old_doms and not new_doms: Loading Loading @@ -611,7 +591,7 @@ class PublishServiceOperations(Resource): # "_" contains the CCF ids where the API was successfully deleted _, interconnection_error = self.unpublish_from_interconnected_ccfs( serviceapidescription_dict.get("api_name"), shared_capif_prov_doms(serviceapidescription_dict.get("shareable_info"))) self.shared_capif_prov_doms(serviceapidescription_dict.get("shareable_info"))) if interconnection_error is not None: return interconnection_error Loading Loading @@ -949,3 +929,38 @@ class PublishServiceOperations(Resource): current_app.logger.debug("Service available") service_api_status = "SERVICE_API_AVAILABLE" return service_api_status def interconnection_payload(self, service_api): """Serialize a service API the way a peer CCF expects to receive it.""" payload = { key: value for key, value in service_api.items() if key not in ("_id", "apf_id", "onboarding_date") } # The peer stores the service API as its own, it must not share it any further payload["shareable_info"] = {"is_shareable": False} # Publish between CCFs (Interface CAPIF-6 and CAPIF-6e) must include ccfId to contact when serviceAPICategory is used. if service_api.get("service_api_category") is not None: config_col = self.db.get_col_by_name(self.db.capif_configuration) config = config_col.find_one({}, {"_id": 0}) payload['ccf_id'] = config['ccf_id'] return json.dumps(clean_n_camel_case(payload), cls=encoder.CustomJSONEncoder) def shared_capif_prov_doms(self, shareable_info): """Return the CAPIF provider domains a service API is meant to be shared with.""" shareable_info = shareable_info or {} if not shareable_info.get("is_shareable"): return [] capif_prov_doms = shareable_info.get("capif_prov_doms") if capif_prov_doms is not None: return capif_prov_doms else: interconnected_col = self.db.get_col_by_name(self.db.interconnected) dst_prov_doms = interconnected_col.distinct("dst_prov_dom") current_app.logger.debug(dst_prov_doms) return dst_prov_doms # return shareable_info.get("capif_prov_doms") or [] No newline at end of file services/envs/dev1.env +1 −0 Original line number Diff line number Diff line export CAPIF_NETWORK_NAME=capif-network-a export COMPOSE_PROJECT_NAME=ocf_a export CAPIF_INTERCONNECTION_HOSTNAME=capifcore-b # Capif vault configuration export CAPIF_VAULT_PORT=8200 Loading services/envs/dev2.env +1 −0 Original line number Diff line number Diff line export CAPIF_NETWORK_NAME=capif-network-b export COMPOSE_PROJECT_NAME=ocf_b export CAPIF_INTERCONNECTION_HOSTNAME=capifcore-a # Capif vault configuration export DEPLOY_VAULT=false Loading services/helper/helper_service/services/interconnection/core/ccfinstancedetails.py +10 −2 Original line number Diff line number Diff line Loading @@ -104,9 +104,13 @@ class CcfInstanceOperations(Resource): services_col = self.db.get_col_by_name(self.db.services_col) shareable_apis = services_col.find({ "shareable_info.is_shareable": True, "shareable_info.capif_prov_doms": peer_dom, "apf_id": {"$ne": peer_ccf_id}, "pub_api_path.ccf_ids": {"$ne": peer_ccf_id} "pub_api_path.ccf_ids": {"$ne": peer_ccf_id}, "$or": [ {"shareable_info.capif_prov_doms": peer_dom}, {"shareable_info.capif_prov_doms": {"$exists": False}}, {"shareable_info.capif_prov_doms": None} ] }) url = "https://{}/published-apis/v1/{}/service-apis".format(peer_dom, local_ccf_id) Loading @@ -130,6 +134,10 @@ class CcfInstanceOperations(Resource): # The peer stores the API as its own, it must not share it any further payload['shareable_info'] = {"is_shareable": False} # Publish between CCFs (Interface CAPIF-6 and CAPIF-6e) must include ccfId to contact when serviceAPICategory is used. if service_api.get("service_api_category") is not None: payload['ccf_id'] = local_ccf_id try: response = session.post(url, data=json.dumps(clean_n_camel_case(payload), cls=CustomJSONEncoder), Loading services/remove_users.sh +1 −1 Original line number Diff line number Diff line Loading @@ -119,4 +119,4 @@ docker run $DOCKER_ROBOT_TTY_OPTIONS --rm --network="host" \ --variable NOTIFICATION_DESTINATION_URL:$NOTIFICATION_DESTINATION_URL \ --variable MOCK_SERVER_URL:$MOCK_SERVER_URL \ --variable USERNAME_PREFIX:$USERNAME_PREFIX \ --include remove-users --include remove-users-by-prefix Loading
services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py +41 −26 Original line number Diff line number Diff line Loading @@ -58,26 +58,6 @@ def find_duplicate_service_by_api_name_and_aef( return collection.find_one(duplicate_query), aef_ids def shared_capif_prov_doms(shareable_info): """Return the CAPIF provider domains a service API is meant to be shared with.""" shareable_info = shareable_info or {} if not shareable_info.get("is_shareable"): return [] return shareable_info.get("capif_prov_doms") or [] def interconnection_payload(service_api): """Serialize a service API the way a peer CCF expects to receive it.""" payload = { key: value for key, value in service_api.items() if key not in ("_id", "apf_id", "onboarding_date") } # The peer stores the service API as its own, it must not share it any further payload["shareable_info"] = {"is_shareable": False} return json.dumps(clean_n_camel_case(payload), cls=encoder.CustomJSONEncoder) def return_negotiated_supp_feat_dict(supp_feat): Loading Loading @@ -216,7 +196,7 @@ class PublishServiceOperations(Resource): ) published, interconnection_error = self.publish_to_interconnected_ccfs( rec, shared_capif_prov_doms(rec.get("shareable_info"))) rec, self.shared_capif_prov_doms(rec.get("shareable_info"))) if interconnection_error is not None: # Nothing is stored here, so a copy left on a peer would be an orphan and Loading Loading @@ -424,7 +404,7 @@ class PublishServiceOperations(Resource): 'accept': 'application/json', 'Content-Type': 'application/json' } body = interconnection_payload(service_api) body = self.interconnection_payload(service_api) for dom in capif_prov_doms: if interconnected_col.find_one({"dst_prov_dom": dom}) is None: Loading Loading @@ -482,7 +462,7 @@ class PublishServiceOperations(Resource): 'accept': 'application/json', 'Content-Type': 'application/json' } body = interconnection_payload(service_api) body = self.interconnection_payload(service_api) published = [] for dom in capif_prov_doms: Loading Loading @@ -539,8 +519,8 @@ class PublishServiceOperations(Resource): store and an error response if any peer could not be aligned, in which case the caller must leave the service API untouched. """ old_doms = shared_capif_prov_doms(old_service_api.get("shareable_info")) new_doms = shared_capif_prov_doms(service_api.get("shareable_info")) old_doms = self.shared_capif_prov_doms(old_service_api.get("shareable_info")) new_doms = self.shared_capif_prov_doms(service_api.get("shareable_info")) pub_api_path = old_service_api.get("pub_api_path") if not old_doms and not new_doms: Loading Loading @@ -611,7 +591,7 @@ class PublishServiceOperations(Resource): # "_" contains the CCF ids where the API was successfully deleted _, interconnection_error = self.unpublish_from_interconnected_ccfs( serviceapidescription_dict.get("api_name"), shared_capif_prov_doms(serviceapidescription_dict.get("shareable_info"))) self.shared_capif_prov_doms(serviceapidescription_dict.get("shareable_info"))) if interconnection_error is not None: return interconnection_error Loading Loading @@ -949,3 +929,38 @@ class PublishServiceOperations(Resource): current_app.logger.debug("Service available") service_api_status = "SERVICE_API_AVAILABLE" return service_api_status def interconnection_payload(self, service_api): """Serialize a service API the way a peer CCF expects to receive it.""" payload = { key: value for key, value in service_api.items() if key not in ("_id", "apf_id", "onboarding_date") } # The peer stores the service API as its own, it must not share it any further payload["shareable_info"] = {"is_shareable": False} # Publish between CCFs (Interface CAPIF-6 and CAPIF-6e) must include ccfId to contact when serviceAPICategory is used. if service_api.get("service_api_category") is not None: config_col = self.db.get_col_by_name(self.db.capif_configuration) config = config_col.find_one({}, {"_id": 0}) payload['ccf_id'] = config['ccf_id'] return json.dumps(clean_n_camel_case(payload), cls=encoder.CustomJSONEncoder) def shared_capif_prov_doms(self, shareable_info): """Return the CAPIF provider domains a service API is meant to be shared with.""" shareable_info = shareable_info or {} if not shareable_info.get("is_shareable"): return [] capif_prov_doms = shareable_info.get("capif_prov_doms") if capif_prov_doms is not None: return capif_prov_doms else: interconnected_col = self.db.get_col_by_name(self.db.interconnected) dst_prov_doms = interconnected_col.distinct("dst_prov_dom") current_app.logger.debug(dst_prov_doms) return dst_prov_doms # return shareable_info.get("capif_prov_doms") or [] No newline at end of file
services/envs/dev1.env +1 −0 Original line number Diff line number Diff line export CAPIF_NETWORK_NAME=capif-network-a export COMPOSE_PROJECT_NAME=ocf_a export CAPIF_INTERCONNECTION_HOSTNAME=capifcore-b # Capif vault configuration export CAPIF_VAULT_PORT=8200 Loading
services/envs/dev2.env +1 −0 Original line number Diff line number Diff line export CAPIF_NETWORK_NAME=capif-network-b export COMPOSE_PROJECT_NAME=ocf_b export CAPIF_INTERCONNECTION_HOSTNAME=capifcore-a # Capif vault configuration export DEPLOY_VAULT=false Loading
services/helper/helper_service/services/interconnection/core/ccfinstancedetails.py +10 −2 Original line number Diff line number Diff line Loading @@ -104,9 +104,13 @@ class CcfInstanceOperations(Resource): services_col = self.db.get_col_by_name(self.db.services_col) shareable_apis = services_col.find({ "shareable_info.is_shareable": True, "shareable_info.capif_prov_doms": peer_dom, "apf_id": {"$ne": peer_ccf_id}, "pub_api_path.ccf_ids": {"$ne": peer_ccf_id} "pub_api_path.ccf_ids": {"$ne": peer_ccf_id}, "$or": [ {"shareable_info.capif_prov_doms": peer_dom}, {"shareable_info.capif_prov_doms": {"$exists": False}}, {"shareable_info.capif_prov_doms": None} ] }) url = "https://{}/published-apis/v1/{}/service-apis".format(peer_dom, local_ccf_id) Loading @@ -130,6 +134,10 @@ class CcfInstanceOperations(Resource): # The peer stores the API as its own, it must not share it any further payload['shareable_info'] = {"is_shareable": False} # Publish between CCFs (Interface CAPIF-6 and CAPIF-6e) must include ccfId to contact when serviceAPICategory is used. if service_api.get("service_api_category") is not None: payload['ccf_id'] = local_ccf_id try: response = session.post(url, data=json.dumps(clean_n_camel_case(payload), cls=CustomJSONEncoder), Loading
services/remove_users.sh +1 −1 Original line number Diff line number Diff line Loading @@ -119,4 +119,4 @@ docker run $DOCKER_ROBOT_TTY_OPTIONS --rm --network="host" \ --variable NOTIFICATION_DESTINATION_URL:$NOTIFICATION_DESTINATION_URL \ --variable MOCK_SERVER_URL:$MOCK_SERVER_URL \ --variable USERNAME_PREFIX:$USERNAME_PREFIX \ --include remove-users --include remove-users-by-prefix