Grant resource id not to requesters but to registered contracts

pull/1124/head
kompotkot 2024-08-20 21:16:57 +00:00
rodzic 6e625a422e
commit 5a9cb0a5c1
2 zmienionych plików z 156 dodań i 34 usunięć

Wyświetl plik

@ -187,18 +187,25 @@ def validate_method_and_params(
return call_request_type
def create_resource_for_registered_contract(user_id: uuid.UUID) -> uuid.UUID:
resource_data = {"type": METATX_REQUESTER_TYPE}
creator_permissions = ["create", "read", "update", "delete"]
def create_resource_for_registered_contract(
registered_contract_id: uuid.UUID, user_id: uuid.UUID
) -> uuid.UUID:
resource_data = {
"type": METATX_REQUESTER_TYPE,
"created_by": str(user_id),
"registered_contract_id": str(registered_contract_id),
}
resource = bugout_client.create_resource(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
application_id=MOONSTREAM_APPLICATION_ID,
resource_data=resource_data,
)
logger.info(f"Created resource with ID: {str(resource.id)}")
logger.info(
f"Created resource with ID: {str(resource.id)} for registered contract with ID: {str(registered_contract_id)}"
)
resource_holder = bugout_client.add_resource_holder_permissions(
_ = bugout_client.add_resource_holder_permissions(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
resource_id=resource.id,
holder_permissions=BugoutResourceHolder(
@ -208,7 +215,7 @@ def create_resource_for_registered_contract(user_id: uuid.UUID) -> uuid.UUID:
),
)
logger.info(
f"Granted {creator_permissions} permissions for resource {str(resource.id)} to metatx requester with ID: {user_id}"
f"Granted creator permissions for resource with ID: {str(resource.id)} to metatx requester with ID: {user_id}"
)
return resource.id
@ -339,8 +346,12 @@ def register_contract(
if blockchain is None:
raise UnsupportedBlockchain("Unsupported blockchain specified")
registered_contract_id = uuid.uuid4()
try:
resource_id = create_resource_for_registered_contract(user_id=user_id)
resource_id = create_resource_for_registered_contract(
registered_contract_id=registered_contract_id, user_id=user_id
)
except Exception as err:
logger.error(repr(err))
raise Exception(
@ -352,6 +363,7 @@ def register_contract(
db_session.execute(metatx_requester_stmt)
contract = RegisteredContract(
id=registered_contract_id,
blockchain_id=blockchain.id,
address=Web3.toChecksumAddress(address),
metatx_requester_id=resource_id,
@ -363,11 +375,11 @@ def register_contract(
db_session.commit()
except IntegrityError as err:
db_session.rollback()
delete_resource_for_registered_contract(resource_id)
delete_resource_for_registered_contract(resource_id=resource_id)
raise ContractAlreadyRegistered()
except Exception as err:
db_session.rollback()
delete_resource_for_registered_contract(resource_id)
delete_resource_for_registered_contract(resource_id=resource_id)
logger.error(repr(err))
raise Exception(
f"Unhandled exception during creating new registered contract for user with ID: {str(user_id)}"

Wyświetl plik

@ -2,14 +2,18 @@ import argparse
import sys
import time
from typing import Any, Dict, List, Optional
from uuid import UUID
from sqlalchemy.sql import delete, distinct, func, insert, update
from .. import db, models
from ..contracts_actions import create_resource_for_registered_contract
from ..contracts_actions import (
create_resource_for_registered_contract,
delete_resource_for_registered_contract,
)
def generate_handler(args: argparse.Namespace):
def update_to_resource_handler(args: argparse.Namespace):
"""
Loop:
1. Fetch all registered contracts
@ -18,11 +22,22 @@ def generate_handler(args: argparse.Namespace):
4. Replace metatx requester in registered contracts table with uuid of resource
"""
with db.yield_db_session_ctx() as db_session:
call_request_subquery = (
db_session.query(
models.CallRequest.registered_contract_id,
func.count(models.CallRequest.id).label("call_requests_cnt"),
)
.group_by(models.CallRequest.registered_contract_id)
.subquery()
)
query = (
db_session.query(
models.RegisteredContract.id,
models.MetatxRequester.id,
func.count(distinct(models.CallRequest.id)).label("call_requests_cnt"),
func.coalesce(call_request_subquery.c.call_requests_cnt, 0).label(
"call_requests_cnt"
),
)
.outerjoin(
models.MetatxRequester,
@ -30,10 +45,15 @@ def generate_handler(args: argparse.Namespace):
== models.MetatxRequester.id,
)
.outerjoin(
models.CallRequest,
models.CallRequest.metatx_requester_id == models.MetatxRequester.id,
call_request_subquery,
models.RegisteredContract.id
== call_request_subquery.c.registered_contract_id,
)
.group_by(
models.RegisteredContract.id,
models.MetatxRequester.id,
call_request_subquery.c.call_requests_cnt,
)
.group_by(models.RegisteredContract.id, models.MetatxRequester.id)
)
result = query.all()
@ -55,16 +75,30 @@ def generate_handler(args: argparse.Namespace):
sys.exit(0)
print("\n")
for mr_id, registered_contracts_cnt, call_requests_cnt in query.all():
for (
registered_contract_id,
metatx_requester_id,
call_requests_cnt,
) in result:
print(
f"Processing metatx_requester_id: {mr_id} with registered_contracts_cnt: {registered_contracts_cnt} and call_requests_cnt: {call_requests_cnt}"
f"Processing registered_contract_id: {registered_contract_id} with metatx_requester_id: {metatx_requester_id} and call_requests_cnt: {call_requests_cnt}"
)
# Create Brood resource and grant permissions to user
try:
resource_id = create_resource_for_registered_contract(user_id=mr_id)
resource_id = create_resource_for_registered_contract(
registered_contract_id=registered_contract_id,
user_id=metatx_requester_id,
)
except Exception as e:
print(str(e))
print(
f"Failed to create resource for registered_contract_id: {registered_contract_id} for user_id: metatx_requester_id, err: {e}"
)
response = input(f"Continue? (yes/y): ").strip().lower()
if response != "yes" and response != "y":
sys.exit(0)
continue
try:
@ -74,36 +108,35 @@ def generate_handler(args: argparse.Namespace):
)
db_session.execute(metatx_requester_stmt)
# Update RegisteredContract table
# Update RegisteredContract table with metatx_requester_id set to resource ID
update_registered_contract = (
update(models.RegisteredContract)
.where(models.RegisteredContract.metatx_requester_id == str(mr_id))
.where(models.RegisteredContract.id == registered_contract_id)
.values(metatx_requester_id=str(resource_id))
)
db_session.execute(update_registered_contract)
# Update CallRequest table
# Update CallRequest table with metatx_requester_id set to resource ID
update_call_request = (
update(models.CallRequest)
.where(models.CallRequest.metatx_requester_id == str(mr_id))
.where(
models.CallRequest.registered_contract_id
== str(registered_contract_id)
)
.values(metatx_requester_id=str(resource_id))
)
db_session.execute(update_call_request)
# Delete old metatx_requester_id
delete_metatx_requester = delete(models.MetatxRequester).where(
models.MetatxRequester.id == str(mr_id)
)
db_session.execute(delete_metatx_requester)
db_session.commit()
print(
f"Updated all metatx_requester_id from {str(mr_id)} to {str(resource_id)} successfully in each table"
f"Updated all metatx_requester_id for registered_contract_id: {str(registered_contract_id)} and belonging call_requests to resource_id: {str(resource_id)} successfully in each table"
)
except Exception as e:
db_session.rollback()
print(f"Failed to update metatx_requester_id: {e}")
delete_resource_for_registered_contract(resource_id=resource_id)
print(
f"Failed to update metatx_requester_id in database, reverted changes, err: {e}"
)
response = input(f"Continue? (yes/y): ").strip().lower()
if response != "yes" and response != "y":
@ -113,6 +146,74 @@ def generate_handler(args: argparse.Namespace):
time.sleep(1)
def clean_metatx_requesters_handler(args: argparse.Namespace):
"""
Search for all metatx requesters in the metatx_requesters table that are
not associated with any registered contract or call request, and delete them one by one.
"""
with db.yield_db_session_ctx() as db_session:
query = (
db_session.query(models.MetatxRequester.id)
.outerjoin(
models.RegisteredContract,
models.MetatxRequester.id
== models.RegisteredContract.metatx_requester_id,
)
.outerjoin(
models.CallRequest,
models.MetatxRequester.id == models.CallRequest.metatx_requester_id,
)
.filter(
models.RegisteredContract.id.is_(None),
models.CallRequest.id.is_(None),
)
.group_by(models.MetatxRequester.id)
)
result = query.all()
if len(result) == 0:
print(
"There are no metatx requesters that are not associated with any registered contract or call request"
)
sys.exit(0)
print("MetatxRequester.id")
print("\n")
for rc in result:
print(f"{rc[0]}")
print("\n")
print(f"There are {len(result)} total results")
response = input(f"Continue? (yes/y): ").strip().lower()
if response != "yes" and response != "y":
sys.exit(0)
print("\n")
for metatx_requester_id in result:
print(
f"Processing deletion of metatx_requester_id: {metatx_requester_id[0]}"
)
try:
delete_metatx_requester = delete(models.MetatxRequester).where(
models.MetatxRequester.id == str(metatx_requester_id[0])
)
db_session.execute(delete_metatx_requester)
db_session.commit()
except Exception as e:
db_session.rollback()
print(
f"Failed to delete metatx_requester_id: {metatx_requester_id}, err: {e}"
)
response = input(f"Continue? (yes/y): ").strip().lower()
if response != "yes" and response != "y":
sys.exit(0)
continue
def main():
parser = argparse.ArgumentParser(
description="Generates for Metatx requesters Brood resources"
@ -120,9 +221,18 @@ def main():
parser.set_defaults(func=lambda _: parser.print_help())
subparsers = parser.add_subparsers()
generate_parser = subparsers.add_parser("generate", help="Generate resources")
update_to_resource_parser = subparsers.add_parser(
"update-to-resource", help="Generate resource and update metatx with it's ID"
)
generate_parser.set_defaults(func=generate_handler)
update_to_resource_parser.set_defaults(func=update_to_resource_handler)
clean_metatx_requesters_parser = subparsers.add_parser(
"clean-metatx-requesters",
help="Clean metatx requesters not belong to any registered contract or call request",
)
clean_metatx_requesters_parser.set_defaults(func=clean_metatx_requesters_handler)
args = parser.parse_args()
args.func(args)