Example #1
0
class ServiceEventConsumer(EventConsumer):
    _connection = Repository(NETWORK_ID, NETWORKS=NETWORKS)
    _service_repository = ServiceRepository(_connection)

    def __init__(self, ws_provider, ipfs_url, ipfs_port):
        self._blockchain_util = BlockChainUtil("WS_PROVIDER", ws_provider)
        self._s3_util = S3Util(S3_BUCKET_ACCESS_KEY, S3_BUCKET_SECRET_KEY)
        self._ipfs_util = IPFSUtil(ipfs_url, ipfs_port)

    def on_event(self, event):
        pass

    def _fetch_tags(self, registry_contract, org_id_hex, service_id_hex):
        tags_data = registry_contract.functions.getServiceRegistrationById(
            org_id_hex, service_id_hex).call()
        return tags_data

    def _get_org_id_from_event(self, event):
        event_data = event['data']
        service_data = eval(event_data['json_str'])
        org_id_bytes = service_data['orgId']
        org_id = Web3.toText(org_id_bytes).rstrip("\x00")
        return org_id

    def _get_service_id_from_event(self, event):
        event_data = event['data']
        service_data = eval(event_data['json_str'])
        service_id_bytes = service_data['serviceId']
        service_id = Web3.toText(service_id_bytes).rstrip("\x00")
        return service_id

    def _get_metadata_uri_from_event(self, event):
        event_data = event['data']
        service_data = eval(event_data['json_str'])
        metadata_uri = Web3.toText(
            service_data['metadataURI'])[7:].rstrip("\u0000")
        return metadata_uri

    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_service_details_from_blockchain(self, event):
        logger.info(f"processing service event {event}")

        registry_contract = self._get_registry_contract()
        org_id = self._get_org_id_from_event(event)
        service_id = self._get_service_id_from_event(event)

        tags_data = self._fetch_tags(registry_contract=registry_contract,
                                     org_id_hex=org_id.encode("utf-8"),
                                     service_id_hex=service_id.encode("utf-8"))

        return org_id, service_id, tags_data
 def curate_service(self, org_id, service_id, curated):
     service_repo = ServiceRepository(self.repo)
     if str(curated).lower() == "true":
         service_repo.curate_service(org_id, service_id, 1)
     elif str(curated).lower() == "false":
         service_repo.curate_service(org_id, service_id, 0)
     else:
         Exception("Invalid curation flag")
    def test_on_service_created_event(self, mock_fetch_tags, nock_read_bytesio_from_ipfs, mock_ipfs_read, mock_s3_push):
        event = {"data": {'row_id': 202, 'block_no': 6325625, 'event': 'ServiceCreated',
                          'json_str': "{'orgId': b'snet\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00', 'serviceId': b'gene-annotation-service\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00', 'metadataURI': b'ipfs://QmdGjaVYPMSGpC1qT3LDALSNCCu7JPf7j51H1GQirvQJYf\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'}",
                          'processed': b'\x00',
                          'transactionHash': 'b"\\xa7P*\\xaf\\xfd\\xd5.E\\x8c\\x0bKAF\'\\x15\\x03\\xef\\xdaO\'\\x86/<\\xfb\\xc4\\xf0@\\xf0\\xc1P\\x8c\\xc7"',
                          'logIndex': '0', 'error_code': 1, 'error_msg': '',
                          'row_updated': datetime(2019, 10, 21, 9, 59, 37),
                          'row_created': datetime(2019, 10, 21, 9, 59, 37)}, "name": "ServiceCreated"}

        connection = Repository(NETWORK_ID, NETWORKS=NETWORKS)
        service_repository = ServiceRepository(connection)
        service_repository.delete_service(org_id='snet', service_id='gene-annotation-service')
        service_repository.delete_service_dependents(org_id='snet', service_id='gene-annotation-service')

        nock_read_bytesio_from_ipfs.return_value = "some_value to_be_pushed_to_s3_whic_is_mocked"
        mock_ipfs_read.return_value = {
            "version": 1,
            "display_name": "Annotation Service",
            "encoding": "proto",
            "service_type": "grpc",
            "model_ipfs_hash": "QmXqonxB9EvNBe11J8oCYXMQAtPKAb2x8CyFLmQpkvVaLf",
            "mpe_address": "0x8FB1dC8df86b388C7e00689d1eCb533A160B4D0C",
            "groups": [
                {
                    "group_name": "default_group",
                    "pricing": [
                        {
                            "price_model": "fixed_price",
                            "price_in_cogs": 1,
                            "default": True
                        }
                    ],
                    "endpoints": [
                        "https://mozi.ai:8000"
                    ],
                    "group_id": "m5FKWq4hW0foGW5qSbzGSjgZRuKs7A1ZwbIrJ9e96rc="
                }
            ],
            "assets": {
                "hero_image": "QmVcE6fEDP764ibadXTjZHk251Lmt5xAxdc4P9mPA4kksk/hero_gene-annotation-2b.png"
            },
            "service_description": {
                "url": "https://mozi-ai.github.io/annotation-service/",
                "description": "Use this service to annotate a humane genome with uniform terms, Reactome pathway memberships, and BioGrid protein interactions.",
                "short_description": "short description"
            },
            "contributors": [
                {
                    "name": "dummy dummy",
                    "email_id": "*****@*****.**"
                }
            ]
        }
        mock_fetch_tags.return_value = ["test", "", "", [b'\x61\x74\x6F\x6D\x65\x73\x65',
                                                         b'\x62\x69\x6F\x69\x6E\x66\x6F\x72\x6D\x61\x74\x69\x63\x73']]
        mock_s3_push.return_value = "https://test-s3-push"
        org_event_consumer = ServiceCreatedEventConsumer("wss://ropsten.infura.io/ws", "http://ipfs.singularitynet.io",
                                                         80)
        org_event_consumer.on_event(event=event)

        service = service_repository.get_service(org_id='snet', service_id='gene-annotation-service')
        service_metadata = service_repository.get_service_metadata(org_id='snet', service_id='gene-annotation-service')
        service_endpoints = service_repository.get_service_endpoints(org_id='snet',
                                                                     service_id='gene-annotation-service')
        service_tags = service_repository.get_service_tags(org_id='snet', service_id='gene-annotation-service')

        assert service == {'org_id': 'snet', 'service_id': 'gene-annotation-service', 'service_path': None,
                           'ipfs_hash': 'QmdGjaVYPMSGpC1qT3LDALSNCCu7JPf7j51H1GQirvQJYf', 'is_curated': 0}
        assert service_metadata == {'org_id': 'snet', 'service_id': 'gene-annotation-service',
                                    'display_name': 'Annotation Service',
                                    'description': 'Use this service to annotate a humane genome with uniform terms, Reactome pathway memberships, and BioGrid protein interactions.',
                                    'short_description': 'short description',
                                    'url': 'https://mozi-ai.github.io/annotation-service/', 'json': '',
                                    'model_ipfs_hash': 'QmXqonxB9EvNBe11J8oCYXMQAtPKAb2x8CyFLmQpkvVaLf',
                                    'encoding': 'proto', 'type': 'grpc',
                                    'mpe_address': '0x8FB1dC8df86b388C7e00689d1eCb533A160B4D0C',
                                    'assets_url': '{"hero_image": "https://test-s3-push"}',
                                    'assets_hash': '{"hero_image": "QmVcE6fEDP764ibadXTjZHk251Lmt5xAxdc4P9mPA4kksk/hero_gene-annotation-2b.png"}',
                                    'service_rating': '{"rating": 0.0, "total_users_rated": 0}', 'ranking': 1,
                                    'contributors': '[{"name": "dummy dummy", "email_id": "*****@*****.**"}]'}
        assert service_endpoints == [{'org_id': 'snet', 'service_id': 'gene-annotation-service',
                                      'group_id': 'm5FKWq4hW0foGW5qSbzGSjgZRuKs7A1ZwbIrJ9e96rc=',
                                      'endpoint': 'https://mozi.ai:8000'}]
        assert service_tags == [{'org_id': 'snet', 'service_id': 'gene-annotation-service', 'tag_name': 'atomese'},
                                {'org_id': 'snet', 'service_id': 'gene-annotation-service',
                                 'tag_name': 'bioinformatics'}]
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
    def test_on_service_created_event_with_media(self, nock_read_bytesio_from_ipfs, mock_ipfs_read,
                                                 mock_s3_push):
        event = {"data": {'row_id': 202, 'block_no': 6325625, 'event': 'ServiceCreated',
                          'json_str': "{'orgId': b'snet\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00', 'serviceId': b'gene-annotation-service\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00', 'metadataURI': b'ipfs://QmdGjaVYPMSGpC1qT3LDALSNCCu7JPf7j51H1GQirvQJYf\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'}",
                          'processed': b'\x00',
                          'transactionHash': 'b"\\xa7P*\\xaf\\xfd\\xd5.E\\x8c\\x0bKAF\'\\x15\\x03\\xef\\xdaO\'\\x86/<\\xfb\\xc4\\xf0@\\xf0\\xc1P\\x8c\\xc7"',
                          'logIndex': '0', 'error_code': 1, 'error_msg': '',
                          'row_updated': datetime(2019, 10, 21, 9, 59, 37),
                          'row_created': datetime(2019, 10, 21, 9, 59, 37)}, "name": "ServiceCreated"}

        connection = Repository(NETWORK_ID, NETWORKS=NETWORKS)
        service_repository = ServiceRepository(connection)
        service_repository.delete_service(org_id='snet', service_id='gene-annotation-service')
        service_repository.delete_service_dependents(org_id='snet', service_id='gene-annotation-service')

        nock_read_bytesio_from_ipfs.return_value = "some_value to_be_pushed_to_s3_whic_is_mocked"
        mock_ipfs_read.return_value = {
            "version": 1,
            "display_name": "Annotation Service",
            "encoding": "proto",
            "service_type": "grpc",
            "model_ipfs_hash": "QmXqonxB9EvNBe11J8oCYXMQAtPKAb2x8CyFLmQpkvVaLf",
            "mpe_address": "0x8FB1dC8df86b388C7e00689d1eCb533A160B4D0C",

            "groups": [
                {
                    "free_calls": 12,
                    "free_call_signer_address": "0x7DF35C98f41F3Af0df1dc4c7F7D4C19a71Dd059F",
                    "group_name": "default_group",
                    "pricing": [
                        {
                            "price_model": "fixed_price",
                            "price_in_cogs": 1,
                            "default": True
                        }
                    ],
                    "endpoints": [
                        "https://mozi.ai:8000"
                    ],
                    "group_id": "m5FKWq4hW0foGW5qSbzGSjgZRuKs7A1ZwbIrJ9e96rc="
                }
            ],
            "assets": {
                "hero_image": "QmVcE6fEDP764ibadXTjZHk251Lmt5xAxdc4P9mPA4kksk/hero_gene-annotation-2b.png"
            },
            "media":[
                       {
                        "file_type": "video",
                        "url": "https://youtu.be/7mj-p1Os6QA",
                        "asset_type": "image updated",
                        "order": 5,
                        "alt_text": "alternate text sample updated",
                    },
                    {
                        "file_type": "text",
                        "url": "Qmbb7tmKZX2TSxDKsK6DEAbp3tPgNUYP11CC93Cft7EkFb/hero_fbprophet_forecast1",
                        "order": 2,
                        "alt_text": "text sample updated",
                    }],
            "service_description": {
                "url": "https://mozi-ai.github.io/annotation-service/",
                "description": "Use this service to annotate a humane genome with uniform terms, Reactome pathway memberships, and BioGrid protein interactions.",
                "short_description": "short description"
            },
            "contributors": [
                {
                    "name": "dummy dummy",
                    "email_id": "*****@*****.**"
                }
            ],
            "tags": ["1234", "3241"]
        }
        mock_s3_push.return_value = "https://test-s3-push"
        org_event_consumer = ServiceCreatedEventConsumer("wss://ropsten.infura.io/ws", "http://ipfs.singularitynet.io",
                                                         80)
        org_event_consumer.on_event(event=event)

        service = service_repository.get_service(org_id='snet', service_id='gene-annotation-service')
        service_metadata = service_repository.get_service_metadata(org_id='snet', service_id='gene-annotation-service')
        service_endpoints = service_repository.get_service_endpoints(org_id='snet',
                                                                     service_id='gene-annotation-service')
        service_tags = service_repository.get_service_tags(org_id='snet', service_id='gene-annotation-service')

        service_groups=service_repository.get_service_group(org_id='snet',service_id='gene-annotation-service')

        service_media = service_repository.get_service_media(org_id='snet',service_id='gene-annotation-service')

        assert service == {'org_id': 'snet', 'service_id': 'gene-annotation-service', 'service_path': None,
                           'ipfs_hash': 'QmdGjaVYPMSGpC1qT3LDALSNCCu7JPf7j51H1GQirvQJYf', 'is_curated': 0}
        assert service_metadata == {'org_id': 'snet', 'service_id': 'gene-annotation-service',
                                    'display_name': 'Annotation Service',
                                    'description': 'Use this service to annotate a humane genome with uniform terms, Reactome pathway memberships, and BioGrid protein interactions.',
                                    'short_description': 'short description',
                                    'url': 'https://mozi-ai.github.io/annotation-service/', 'json': '',
                                    'model_ipfs_hash': 'QmXqonxB9EvNBe11J8oCYXMQAtPKAb2x8CyFLmQpkvVaLf',
                                    'encoding': 'proto', 'type': 'grpc',
                                    'mpe_address': '0x8FB1dC8df86b388C7e00689d1eCb533A160B4D0C',
                                    'assets_url': '{"hero_image": "https://test-s3-push"}',
                                    'assets_hash': '{"hero_image": "QmVcE6fEDP764ibadXTjZHk251Lmt5xAxdc4P9mPA4kksk/hero_gene-annotation-2b.png"}',
                                    'service_rating': '{"rating": 0.0, "total_users_rated": 0}', 'ranking': 1,
                                    'contributors': '[{"name": "dummy dummy", "email_id": "*****@*****.**"}]'}
        assert service_endpoints == [{'org_id': 'snet', 'service_id': 'gene-annotation-service',
                                      'group_id': 'm5FKWq4hW0foGW5qSbzGSjgZRuKs7A1ZwbIrJ9e96rc=',
                                      'endpoint': 'https://mozi.ai:8000'}]
        assert service_tags == [{'org_id': 'snet', 'service_id': 'gene-annotation-service', 'tag_name': '1234'},
                                {'org_id': 'snet', 'service_id': 'gene-annotation-service', 'tag_name': '3241'}]

        assert service_groups == {'org_id': 'snet', 'service_id': 'gene-annotation-service', 'group_id': 'm5FKWq4hW0foGW5qSbzGSjgZRuKs7A1ZwbIrJ9e96rc=', 'group_name': 'default_group', 'pricing': '[{"default": true, "price_model": "fixed_price", "price_in_cogs": 1}]', 'free_call_signer_address': '0x7DF35C98f41F3Af0df1dc4c7F7D4C19a71Dd059F', 'free_calls': 12}

        for media_item in service_media:
            media_item.pop('row_id')

        assert service_media == [
            {'org_id': 'snet', 'service_id': 'gene-annotation-service', 'url': 'https://test-s3-push', 'order': 2, 'file_type': 'text', 'asset_type': '', 'alt_text': 'text sample updated', 'ipfs_url': 'Qmbb7tmKZX2TSxDKsK6DEAbp3tPgNUYP11CC93Cft7EkFb/hero_fbprophet_forecast1'},
            {'org_id': 'snet', 'service_id': 'gene-annotation-service', 'url': 'https://youtu.be/7mj-p1Os6QA', 'order': 5, 'file_type': 'video', 'asset_type': 'image updated', 'alt_text': 'alternate text sample updated', 'ipfs_url': ''},
            {'org_id': 'snet', 'service_id': 'gene-annotation-service', 'url': 'https://test-s3-push', 'order': 6, 'file_type': 'asset', 'asset_type': 'hero_image', 'alt_text': '', 'ipfs_url': 'QmVcE6fEDP764ibadXTjZHk251Lmt5xAxdc4P9mPA4kksk/hero_gene-annotation-2b.png'}
        ]