class HandleContractsDB: def __init__(self, err_obj, net_id): self.err_obj = err_obj self.repo = Repository(net_id, NETWORKS) self.util_obj = Utils() self.ipfs_utll = IPFSUtil(IPFS_URL['url'], IPFS_URL['port']) self.s3_util = S3Util(S3_BUCKET_ACCESS_KEY, S3_BUCKET_SECRET_KEY) # read operations def read_registry_events(self): query = 'select * from registry_events_raw where processed = 0 order by block_no asc limit ' + EVNTS_LIMIT evts_dta = self.repo.execute(query) print('read_registry_events::read_count: ', len(evts_dta)) return evts_dta def read_mpe_events(self): query = 'select * from mpe_events_raw where processed = 0 order by block_no asc limit ' + EVNTS_LIMIT evts_dta = self.repo.execute(query) print('read_mpe_events::read_count: ', len(evts_dta)) return evts_dta def _get_srvc_row_id(self, org_id, service_id): print('get_srvc_row_id::service_id: ', service_id) query = 'SELECT row_id FROM service WHERE service_id = %s AND org_id = %s ' srvc_data = self.repo.execute(query, [service_id, org_id]) print('get_srvc_row_id::srvc_data: ', srvc_data) return srvc_data def _get_srvcs(self, org_id): query = 'SELECT * FROM service WHERE org_id = %s ' srvc_data = self.repo.execute(query, (org_id)) print('_get_srvcs::srvc_data: ', srvc_data) return srvc_data # write operations def _create_or_updt_org(self, org_id, org_name, owner_address, org_metadata_uri, conn): upsert_qry = "Insert into organization (org_id, organization_name, owner_address, org_metadata_uri, row_updated, row_created) " \ "VALUES ( %s, %s, %s, %s, %s , %s) " \ "ON DUPLICATE KEY UPDATE organization_name = %s, owner_address = %s, org_metadata_uri = %s, row_updated = %s " upsert_params = [org_id, org_name, owner_address, org_metadata_uri, dt.utcnow(), dt.utcnow(), org_name, owner_address, org_metadata_uri, dt.utcnow()] print('upsert_qry: ', upsert_qry) qry_resp = conn.execute(upsert_qry, upsert_params) print('_create_or_updt_org::row upserted: ', qry_resp) def _del_org_groups(self, org_id, conn): delete_query = conn.execute( "DELETE FROM org_group WHERE org_id = %s ", [org_id]) def _create_org_groups(self, org_id, groups, conn): insert_qry = "Insert into org_group (org_id, group_id, group_name, payment, row_updated, row_created) " \ "VALUES ( %s, %s, %s, %s, %s, %s ) " cnt = 0 for group in groups: insert_params = [org_id, group['group_id'], group['group_name'], json.dumps( group['payment']), dt.utcnow(), dt.utcnow()] qry_res = conn.execute(insert_qry, insert_params) cnt = cnt + qry_res[0] print('_create_org_groups::row inserted', cnt) def _create_or_updt_members(self, org_id, members, conn): upsrt_members = "INSERT INTO members (org_id, member, row_created, row_updated)" \ "VALUES ( %s, %s, %s, %s )" \ "ON DUPLICATE KEY UPDATE row_updated = %s " cnt = 0 for member in members: upsrt_members_params = [org_id, member, dt.utcnow(), dt.utcnow(), dt.utcnow()] qry_res = conn.execute(upsrt_members, upsrt_members_params) cnt = cnt + qry_res[0] print('create_or_updt_members::row upserted', cnt) def _create_channel(self, q_dta, conn): upsrt_mpe_chnl = "INSERT INTO mpe_channel (channel_id, sender, recipient, groupId, balance_in_cogs, pending, nonce, " \ "expiration, signer, row_created, row_updated) " \ "VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) " \ "ON DUPLICATE KEY UPDATE balance_in_cogs = %s, pending = %s, nonce = %s, " \ "expiration = %s, row_updated = %s" upsrt_mpe_chnl_params = [q_dta['channelId'], q_dta['sender'], q_dta['recipient'], q_dta['groupId'], q_dta['amount'], 0.0, q_dta['nonce'], q_dta['expiration'], q_dta['signer'], dt.utcnow( ), dt.utcnow(), q_dta['amount'], 0.0, q_dta['nonce'], q_dta['expiration'], dt.utcnow()] qry_res = conn.execute(upsrt_mpe_chnl, upsrt_mpe_chnl_params) print('_create_channel::row upserted', qry_res) def _del_srvc(self, org_id, service_id, conn): del_srvc = 'DELETE FROM service WHERE service_id = %s AND org_id = %s ' qry_res = conn.execute(del_srvc, [service_id, org_id]) print('_del_srvc::rows deleted: ', qry_res) def _del_org(self, org_id, conn): del_org = 'DELETE FROM organization WHERE org_id = %s ' qry_res = conn.execute(del_org, org_id) print('_del_org::rows deleted: ', qry_res) def _del_members(self, org_id, conn): del_org = 'DELETE FROM members WHERE org_id = %s ' qry_res = conn.execute(del_org, org_id) print('_del_members::rows deleted: ', qry_res) def _del_tags(self, org_id, service_id, conn): del_srvc_tags = 'DELETE FROM service_tags WHERE service_id = %s AND org_id = %s ' del_srvc_tags_count = conn.execute(del_srvc_tags, [service_id, org_id]) print('_del_tags::del_srvc_tags: ', del_srvc_tags_count) def _del_srvc_dpndts(self, org_id, service_id, conn): print("_del_srvc_dpndts::service_id: ", service_id, '|org_id: ', org_id) del_srvc_grps = 'DELETE FROM service_group WHERE service_id = %s AND org_id = %s ' del_srvc_grps_count = conn.execute(del_srvc_grps, [service_id, org_id]) del_srvc_endpts = 'DELETE FROM service_endpoint WHERE service_id = %s AND org_id = %s ' del_srvc_endpts_count = conn.execute( del_srvc_endpts, [service_id, org_id]) self._del_tags(org_id=org_id, service_id=service_id, conn=conn) print('_del_srvc_dpndts::del_srvc_grps: ', del_srvc_grps_count, '|del_srvc_endpts: ', del_srvc_endpts_count) def _create_or_updt_srvc(self, org_id, service_id, ipfs_hash, conn): upsrt_srvc = "INSERT INTO service (org_id, service_id, is_curated, ipfs_hash, row_created, row_updated) " \ "VALUES (%s, %s, %s, %s, %s, %s) " \ "ON DUPLICATE KEY UPDATE ipfs_hash = %s, row_updated = %s " upsrt_srvc_params = [org_id, service_id, 0, ipfs_hash, dt.utcnow(), dt.utcnow(), ipfs_hash, dt.utcnow()] qry_res = conn.execute(upsrt_srvc, upsrt_srvc_params) print('_create_or_updt_srvc::row upserted', qry_res) return qry_res[len(qry_res) - 1] def _create_or_updt_srvc_mdata(self, srvc_rw_id, org_id, service_id, ipfs_data, assets_url, conn): upsrt_srvc_mdata = "INSERT INTO service_metadata (service_row_id, org_id, service_id, " \ "display_name, model_ipfs_hash, description, url, json, encoding, type, " \ "mpe_address, assets_hash , assets_url, service_rating, row_updated, row_created) " \ "VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s ) " \ "ON DUPLICATE KEY UPDATE service_row_id = %s, " \ "display_name = %s, model_ipfs_hash = %s, description = %s, url = %s, json = %s, " \ "encoding = %s, type = %s, mpe_address = %s, row_updated = %s ,assets_hash = %s ,assets_url = %s" srvc_desc = ipfs_data.get('service_description', {}) desc = srvc_desc.get('description', '') url = srvc_desc.get('url', '') json_str = ipfs_data.get('json', '') assets_hash = json.dumps(ipfs_data.get('assets', {})) assets_url_str = json.dumps(assets_url) upsrt_srvc_mdata_params = [srvc_rw_id, org_id, service_id, ipfs_data['display_name'], ipfs_data['model_ipfs_hash'], desc, url, json_str, ipfs_data['encoding'], ipfs_data['service_type'], ipfs_data['mpe_address'], assets_hash, assets_url_str, '{"rating": 0.0 , "total_users_rated": 0 }', dt.utcnow( ), dt.utcnow(), srvc_rw_id, ipfs_data['display_name'], ipfs_data['model_ipfs_hash'], desc, url, json_str, ipfs_data['encoding'], ipfs_data['service_type'], ipfs_data['mpe_address'], dt.utcnow(), assets_hash, assets_url_str] qry_res = conn.execute(upsrt_srvc_mdata, upsrt_srvc_mdata_params) print('_create_or_updt_srvc_mdata::row upserted', qry_res) def _create_grp(self, srvc_rw_id, org_id, service_id, grp_data, conn): insrt_grp = "INSERT INTO service_group (service_row_id, org_id, service_id, group_id, group_name," \ "pricing, row_updated, row_created)" \ "VALUES(%s, %s, %s, %s, %s, %s, %s, %s)" insrt_grp_params = [srvc_rw_id, org_id, service_id, grp_data['group_id'], grp_data['group_name'], grp_data['pricing'], dt.utcnow(), dt.utcnow()] return conn.execute(insrt_grp, insrt_grp_params) def _create_edpts(self, srvc_rw_id, org_id, service_id, endpt_data, conn): insrt_endpt = "INSERT INTO service_endpoint (service_row_id, org_id, service_id, group_id, endpoint, " \ "row_created, row_updated) " \ "VALUES(%s, %s, %s, %s, %s, %s, %s)" insrt_endpt_params = [srvc_rw_id, org_id, service_id, endpt_data['group_id'], endpt_data['endpoint'], dt.utcnow(), dt.utcnow()] return conn.execute(insrt_endpt, insrt_endpt_params) def _create_tags(self, srvc_rw_id, org_id, service_id, tag_name, conn): insrt_tag = "INSERT INTO service_tags (service_row_id, org_id, service_id, tag_name, row_created, row_updated) " \ "VALUES(%s, %s, %s, %s, %s, %s) " \ "ON DUPLICATE KEY UPDATE tag_name = %s, row_updated = %s " insrt_tag_params = [srvc_rw_id, org_id, service_id, tag_name, dt.utcnow(), dt.utcnow(), tag_name, dt.utcnow()] qry_res = conn.execute(insrt_tag, insrt_tag_params) print('_create_tags::qry_res: ', qry_res) def _updt_raw_evts(self, row_id, type, err_cd, err_msg, conn): try: if type == 'REG': updt_evts = 'UPDATE registry_events_raw SET processed = 1, error_code = %s, error_msg = %s WHERE row_id = %s ' elif type == 'MPE': updt_evts = 'UPDATE mpe_events_raw SET processed = 1, error_code = %s, error_msg = %s WHERE row_id = %s ' updt_evts_resp = self.repo.execute( updt_evts, [err_cd, err_msg, row_id]) print('updt_raw_evts::row updated: ', updt_evts_resp, '|', type) except Exception as e: self.util_obj.report_slack( type=1, slack_msg=repr(e), SLACK_HOOK=SLACK_HOOK) print('Error in updt_reg_evts_raw::error: ', e) def updt_raw_evts(self, row_id, type, err_cd, err_msg): conn = self.repo self._updt_raw_evts(row_id, type, err_cd, err_msg, conn) def del_org(self, org_id): self.repo.auto_commit = False conn = self.repo try: self._del_org(org_id=org_id, conn=conn) self._del_org_groups(org_id=org_id, conn=conn) srvcs = self._get_srvcs(org_id=org_id) for rec in srvcs: self._del_srvc( org_id=org_id, service_id=rec['service_id'], conn=conn) self._commit(conn=conn) except Exception as e: self.util_obj.report_slack( type=1, slack_msg=repr(e), SLACK_HOOK=SLACK_HOOK) self._rollback(conn=conn, err=repr(e)) def del_srvc(self, org_id, service_id): self._del_srvc(org_id=org_id, service_id=service_id, conn=self.repo) def create_channel(self, q_dta): if q_dta['groupId'][0:2] == '0x': q_dta['groupId'] = q_dta['groupId'][2:] q_dta['groupId'] = base64.b64encode( bytes.fromhex(q_dta['groupId'])).decode('utf8') self._create_channel(q_dta, self.repo) def update_channel(self, channel_id, group_id, channel_data): print('update_channel::channel_id: ', channel_id) self._create_channel(q_dta={ 'sender': channel_data[1], 'recipient': channel_data[3], 'nonce': int(channel_data[0]), 'expiration': channel_data[6], 'signer': channel_data[2], 'groupId': group_id, 'channelId': channel_id, 'amount': channel_data[5] }, conn=self.repo) def _push_asset_to_s3_using_hash(self, hash, org_id, service_id): io_bytes = self.ipfs_utll.read_bytesio_from_ipfs(hash) filename = hash.split("/")[1] new_url = self.s3_util.push_io_bytes_to_s3(ASSETS_PREFIX + "/" + org_id + "/" + service_id + "/" + filename, ASSETS_BUCKET_NAME, io_bytes) return new_url def _comapre_assets_and_push_to_s3(self, existing_assets_hash, new_assets_hash, existing_assets_url, org_id, service_id): """ :param existing_assets_hash: contains asset_type and its has value stored in ipfs :param new_assets_hash: contains asset type and its updated hash value in ipfs :param existing_assets_url: contains asset type and s3_url value for given asset_type :param org_id: :param service_id: :return: dict of asset_type and new_s3_url """ # this function compare assets and deletes and update the new assets assets_url_mapping = {} if not existing_assets_hash: existing_assets_hash = {} if not existing_assets_url: existing_assets_url = {} if not new_assets_hash: new_assets_hash = {} for new_asset_type, new_asset_hash in new_assets_hash.items(): if isinstance(new_asset_hash, list): # if this asset_type contains list of assets than remove all existing assetes from s3 and add all new assets to s3 # new_urls_list = [] # remove all existing assets if exits if new_asset_type in existing_assets_url: for url in existing_assets_url[new_asset_type]: self.s3_util.delete_file_from_s3(url) # add new files to s3 and update the url for hash in new_assets_hash[new_asset_type]: new_urls_list.append( self._push_asset_to_s3_using_hash(hash, org_id, service_id)) assets_url_mapping[new_asset_type] = new_urls_list elif isinstance(new_asset_hash, str): # if this asset_type has single value if new_asset_type in existing_assets_hash and existing_assets_hash[new_asset_type] == new_asset_hash: # file is not updated , add existing url assets_url_mapping[new_asset_type] = existing_assets_url[new_asset_type] else: if new_asset_type in existing_assets_url: url_of_file_to_be_removed = existing_assets_url[new_asset_type] self.s3_util.delete_file_from_s3( url_of_file_to_be_removed) hash_of_file_to_be_pushed_to_s3 = new_assets_hash[new_asset_type] assets_url_mapping[new_asset_type] = self._push_asset_to_s3_using_hash( hash_of_file_to_be_pushed_to_s3, org_id, service_id) else: logger.info( "unknown type assets for org_id %s service_id %s", org_id, service_id) return assets_url_mapping def _get_new_assets_url(self, org_id, service_id, new_ipfs_data): new_assets_hash = new_ipfs_data.get('assets', {}) existing_assets_hash = {} existing_assets_url = {} service_metadata_repo = ServiceMetadataRepository() existing_service_metadata = service_metadata_repo.get_service_metatdata_by_servcie_id_and_org_id( service_id, org_id) if existing_service_metadata: existing_assets_hash = existing_service_metadata.assets_hash existing_assets_url = existing_service_metadata.assets_url assets_url_mapping = self._comapre_assets_and_push_to_s3(existing_assets_hash, new_assets_hash, existing_assets_url, org_id, service_id) return assets_url_mapping def process_srvc_data(self, org_id, service_id, ipfs_hash, ipfs_data, tags_data): self.repo.auto_commit = False conn = self.repo try: assets_url = self._get_new_assets_url( org_id, service_id, ipfs_data) self._del_srvc_dpndts( org_id=org_id, service_id=service_id, conn=conn) qry_data = self._create_or_updt_srvc( org_id=org_id, service_id=service_id, ipfs_hash=ipfs_hash, conn=conn) service_row_id = qry_data['last_row_id'] print('service_row_id == ', service_row_id) self._create_or_updt_srvc_mdata(srvc_rw_id=service_row_id, org_id=org_id, service_id=service_id, ipfs_data=ipfs_data, assets_url=assets_url, conn=conn) grps = ipfs_data.get('groups', []) group_insert_count = 0 for grp in grps: qry_data = self._create_grp(srvc_rw_id=service_row_id, org_id=org_id, service_id=service_id, conn=conn, grp_data={ 'group_id': grp['group_id'], 'group_name': grp['group_name'], 'pricing': json.dumps(grp['pricing']) }) group_insert_count = group_insert_count + qry_data[0] endpts = grp.get('endpoints', []) endpt_insert_count = 0 for endpt in endpts: qry_data = self._create_edpts(srvc_rw_id=service_row_id, org_id=org_id, service_id=service_id, conn=conn, endpt_data={ 'endpoint': endpt, 'group_id': grp['group_id'], }) endpt_insert_count = endpt_insert_count + qry_data[0] print('rows insert in endpt: ', endpt_insert_count) print('rows insert in grp: ', group_insert_count) if (tags_data is not None and tags_data[0]): tags = tags_data[3] for tag in tags: tag = tag.decode('utf-8') tag = tag.rstrip("\u0000") self._create_tags(srvc_rw_id=service_row_id, org_id=org_id, service_id=service_id, tag_name=tag, conn=conn) self._commit(conn=conn) except Exception as e: self.util_obj.report_slack( type=1, slack_msg=repr(e), SLACK_HOOK=SLACK_HOOK) self._rollback(conn=conn, err=repr(e)) def process_org_data(self, org_id, org_data, ipfs_data, org_metadata_uri): self.repo.auto_commit = False conn = self.repo try: if (org_data is not None and org_data[0]): self._create_or_updt_org( org_id=org_id, org_name=ipfs_data["org_name"], owner_address=org_data[3], org_metadata_uri=org_metadata_uri, conn=conn) self._del_org_groups(org_id=org_id, conn=conn) self._create_org_groups( org_id=org_id, groups=ipfs_data["groups"], conn=conn) self._del_members(org_id=org_id, conn=conn) self._create_or_updt_members(org_id, org_data[4], conn) self._commit(conn) except Exception as e: self.util_obj.report_slack( type=1, slack_msg=repr(e), SLACK_HOOK=SLACK_HOOK) self._rollback(conn=conn, err=repr(e)) def update_tags(self, org_id, service_id, tags_data): self.repo.auto_commit = False conn = self.repo try: self._del_tags(org_id=org_id, service_id=service_id, conn=conn) if (tags_data is not None and tags_data[0]): tags = tags_data[3] srvc_data = self._get_srvc_row_id( service_id=service_id, org_id=org_id) srvc_rw_id = srvc_data[0]['row_id'] for tag in tags: tag = tag.decode('utf-8') tag = tag.rstrip("\u0000") self._create_tags(srvc_rw_id=srvc_rw_id, org_id=org_id, service_id=service_id, tag_name=tag, conn=conn) self._commit(conn) except Exception as e: self.util_obj.report_slack( type=1, slack_msg=repr(e), SLACK_HOOK=SLACK_HOOK) self._rollback(conn=conn, err=repr(e)) # def _commit(self, conn): conn.auto_commit = True conn.connection.commit() print('_commit') print(conn.connection) def _rollback(self, conn, err): print('_rollback ::error: ', err) conn.auto_commit = True conn.connection.rollback()
class OrganizationEventConsumer(EventConsumer): _connection = Repository(NETWORK_ID, NETWORKS=NETWORKS) _organization_repository = OrganizationRepository(_connection) _service_repository = ServiceRepository(_connection) def __init__(self, ws_provider, ipfs_url, ipfs_port): self._ipfs_util = IPFSUtil(ipfs_url, ipfs_port) self._blockchain_util = BlockChainUtil("WS_PROVIDER", ws_provider) self._s3_util = S3Util(S3_BUCKET_ACCESS_KEY, S3_BUCKET_SECRET_KEY) def on_event(self, event): pass def _push_asset_to_s3_using_hash(self, hash, org_id, service_id): io_bytes = self._ipfs_util.read_bytesio_from_ipfs( hash.lstrip("ipfs://")) filename = hash.split("/")[1] if service_id: s3_filename = ASSETS_PREFIX + "/" + org_id + "/" + service_id + "/" + filename else: s3_filename = ASSETS_PREFIX + "/" + org_id + "/" + filename new_url = self._s3_util.push_io_bytes_to_s3(s3_filename, ASSETS_BUCKET_NAME, io_bytes) return new_url def _get_new_assets_url(self, org_id, new_ipfs_data): new_assets_hash = new_ipfs_data.get('assets', {}) existing_assets_hash = {} existing_assets_url = {} existing_organization = self._organization_repository.get_organization( org_id) if existing_organization: existing_assets_hash = json.loads( existing_organization["assets_hash"]) existing_assets_url = json.loads( existing_organization["org_assets_url"]) new_assets_url_mapping = self._comapre_assets_and_push_to_s3( existing_assets_hash, new_assets_hash, existing_assets_url, org_id, "") return new_assets_url_mapping def _get_org_id_from_event(self, event): event_org_data = eval(event['data']['json_str']) org_id_bytes = event_org_data['orgId'] org_id = Web3.toText(org_id_bytes).rstrip("\x00") return org_id def _get_registry_contract(self): net_id = NETWORK_ID base_contract_path = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..', 'node_modules', 'singularitynet-platform-contracts')) registry_contract = self._blockchain_util.get_contract_instance( base_contract_path, "REGISTRY", net_id) return registry_contract def _get_org_details_from_blockchain(self, event): logger.info(f"processing org event {event}") registry_contract = self._get_registry_contract() org_id = self._get_org_id_from_event(event) blockchain_org_data = registry_contract.functions.getOrganizationById( org_id.encode('utf-8')).call() org_metadata_uri = Web3.toText( blockchain_org_data[2]).rstrip("\x00").lstrip("ipfs://") ipfs_org_metadata = self._ipfs_util.read_file_from_ipfs( org_metadata_uri) return org_id, blockchain_org_data, ipfs_org_metadata, org_metadata_uri