def es_query_ddo():
    """Get a list of DDOs that match with the executed query.
    ---
    tags:
      - ddo
    consumes:
      - application/json
    parameters:
      - in: body
        name: body
        required: true
        description: Asset metadata.
        schema:
          type: object
          properties:
            query:
              type: string
              description: Query to realize
              example: {"value":1}
            text:
              type: string or list of strings
              description: Fulltext query
              example: ["text to search"]
            sort:
              type: object
              description: Key or list of keys to sort the result
              example: {"value":1}
            offset:
              type: int
              description: Number of records per page
              example: 100
            page:
              type: int
              description: Page showed
              example: 1
    responses:
      200:
        description: successful action

    example:
        {"query": {"query_string": {"query": "(covid) -isInPurgatory:true"}}, "offset":1, "page": 1}

    """
    assert isinstance(request.json, dict), 'invalid payload format.'
    data = request.json
    query_result, search_model = process_es_query(data)
    for ddo in query_result[0]:
        sanitize_record(ddo)

    response = make_paginate_response(query_result, search_model)
    return Response(json.dumps(response, default=datetime_converter),
                    200,
                    content_type='application/json')
def query_text():
    """Get a list of DDOs that match with the given text.
    ---
    tags:
      - ddo
    parameters:
      - name: text
        in: query
        description: ID of the asset.
        required: true
        type: string
      - name: sort
        in: query
        type: object
        description: Key or list of keys to sort the result
        example: {"value":1}
      - name: offset
        in: query
        type: int
        description: Number of records per page
        example: 100
      - name: page
        in: query
        type: int
        description: Page showed
        example: 1
    responses:
      200:
        description: successful action
    """
    data = get_request_data(request)
    assert isinstance(
        data,
        dict), 'invalid `args` type, should already formatted into a dict.'
    sort = data.get('sort', None)
    if sort is not None and isinstance(sort, str):
        sort = json.loads(sort)

    search_model = FullTextModel(text=data.get('text', None),
                                 sort=sort,
                                 offset=int(data.get('offset', 100)),
                                 page=int(data.get('page', 1)))
    query_result = dao.query(search_model)
    for i in query_result[0]:
        sanitize_record(i)

    response = make_paginate_response(query_result, search_model)
    return Response(json.dumps(response, default=datetime_converter),
                    200,
                    content_type='application/json')
def get_asset_ddos():
    """Get DDO of all assets.
    ---
    tags:
      - ddo
    responses:
      200:
        description: successful action
    """
    _assets = dao.get_all_listed_assets()
    for _record in _assets:
        sanitize_record(_record)
    return Response(json.dumps(_assets, default=datetime_converter),
                    200,
                    content_type='application/json')
def get_ddo(did):
    """Get DDO of a particular asset.
    ---
    tags:
      - ddo
    parameters:
      - name: did
        in: path
        description: DID of the asset.
        required: true
        type: string
    responses:
      200:
        description: successful operation
      404:
        description: This asset DID is not in OceanDB
    """
    try:
        asset_record = dao.get(did)
        return Response(sanitize_record(asset_record),
                        200,
                        content_type='application/json')
    except Exception as e:
        logger.error(f'get_ddo: {str(e)}')
        return f'{did} asset DID is not in OceanDB', 404
def get_metadata(did):
    """Get metadata of a particular asset
    ---
    tags:
      - metadata
    parameters:
      - name: did
        in: path
        description: DID of the asset.
        required: true
        type: string
    responses:
      200:
        description: successful operation.
      404:
        description: This asset DID is not in OceanDB.
    """
    try:
        asset_record = dao.get(did)
        metadata = get_metadata_from_services(asset_record['service'])
        return Response(sanitize_record(metadata),
                        200,
                        content_type='application/json')
    except Exception as e:
        logger.error(f'get_metadata: {str(e)}')
        return f'{did} asset DID is not in OceanDB', 404
Esempio n. 6
0
def test_sanitize_record_through_rbac(monkeypatch):
    monkeypatch.setenv("RBAC_SERVER_URL", "test")

    with patch("requests.post") as mock:
        response = Mock(spec=Response)
        response.json.return_value = {"this_is": "SPARTAAA!"}
        response.status_code = 200
        mock.return_value = response

        result = json.loads(sanitize_record({}))
        assert result["this_is"] == "SPARTAAA!"

    with patch("requests.post") as mock:
        response = Mock(spec=Response)
        response.status_code = 404
        mock.return_value = response

        result = json.loads(sanitize_record({"this_is": "something else"}))
        assert result["this_is"] == "something else"
Esempio n. 7
0
def get_metadata(did):
    """Get metadata of a particular asset
    ---
    tags:
      - metadata
    parameters:
      - name: did
        in: path
        description: DID of the asset.
        required: true
        type: string
    responses:
      200:
        description: successful operation.
        example:
          application/json: {
            "main": {
                "type": "dataset",
                "name": "Nu nl",
                "dateCreated": "2021-04-02T17:59:32Z",
                "author": "ab",
                "license": "MIT",
                "files": [
                    {
                        "index": 0,
                        "contentType": "application/json"
                    }
                ],
                "datePublished": "2021-04-20T22:56:01Z"
            },
            "encryptedFiles": "0x047c992274f3fa2bf9c5cc57d0e0852f7b3ec22d7ab4e798e3e73e77e7f971ff04896129c9f58deac"
          }
      404:
        description: This asset DID is not in ES.
    """
    try:
        asset_record = es_instance.get(did)
        response = app.response_class(
            response=sanitize_record(asset_record["metadata"]),
            status=200,
            mimetype="application/json",
        )
        return response
    except Exception as e:
        logger.error(f"get_metadata: {str(e)}")
        return (
            jsonify(
                error=f"Error encountered while retrieving metadata: {str(e)}."
            ),
            404,
        )
def query_ddo():
    """Get a list of DDOs that match with the executed query.
    ---
    tags:
      - ddo
    consumes:
      - application/json
    parameters:
      - in: body
        name: body
        required: true
        description: Asset metadata.
        schema:
          type: object
          properties:
            query:
              type: string
              description: Query to realize
              example: {"value":1}
            sort:
              type: object
              description: Key or list of keys to sort the result
              example: {"value":1}
            offset:
              type: int
              description: Number of records per page
              example: 100
            page:
              type: int
              description: Page showed
              example: 1
    responses:
      200:
        description: successful action
    """
    assert isinstance(request.json, dict), 'invalid payload format.'
    data = request.json
    assert isinstance(
        data, dict), 'invalid `body` type, should be formatted as a dict.'

    native_query = None
    if 'nativeSearch' in data:
        native_query = data.pop('nativeSearch')

    query = data.get('query', {})
    if not native_query and 'nativeSearch' in query:
        native_query = query.pop('nativeSearch')

    if native_query:
        query_result, search_model = process_es_query(data)
    else:
        search_model = QueryModel(query=query,
                                  sort=data.get('sort'),
                                  offset=data.get('offset', 100),
                                  page=data.get('page', 1))
        query_result = dao.query(search_model)

    for ddo in query_result[0]:
        sanitize_record(ddo)

    response = make_paginate_response(query_result, search_model)
    return Response(json.dumps(response, default=datetime_converter),
                    200,
                    content_type='application/json')
Esempio n. 9
0
def trigger_caching():
    """Triggers manual caching of a specific transaction (MetadataCreated or MetadataUpdated event)
    ---
    tags:
      - name
    consumes:
      - application/json
    parameters:
      - name: transactionId
        required: true
        description: transaction id containing MetadataCreated or MetadataUpdated event
      - name: logIndex
        required: false
        description: zero-based index in log if transaction contains more events
    responses:
      200:
        description: successful operation.
      400:
        description: bad request. Log index not found or event not found.
      500:
        description: server error/exception
    """
    try:
        data = request.args if request.args else request.json
        tx_id = data.get("transactionId")
        log_index = int(data.get("logIndex", 0))

        config_file = app.config["AQUARIUS_CONFIG_FILE"]
        web3 = setup_web3(config_file)
        tx_receipt = web3.eth.wait_for_transaction_receipt(tx_id)

        if len(tx_receipt.logs) <= log_index or log_index < 0:
            return jsonify(error=f"Log index {log_index} not found"), 400

        dt_address = tx_receipt.logs[log_index].address
        dt_contract = web3.eth.contract(
            abi=ERC721Template.abi, address=web3.toChecksumAddress(dt_address))
        created_event = dt_contract.events.MetadataCreated().processReceipt(
            tx_receipt, errors=DISCARD)
        updated_event = dt_contract.events.MetadataUpdated().processReceipt(
            tx_receipt, errors=DISCARD)

        if not created_event and not updated_event:
            return jsonify(
                error="No metadata created/updated event found in tx."), 400

        es_instance = ElasticsearchInstance(config_file)
        allowed_publishers = get_allowed_publishers()
        purgatory = (Purgatory(es_instance) if
                     (os.getenv("ASSET_PURGATORY_URL")
                      or os.getenv("ACCOUNT_PURGATORY_URL")) else None)
        chain_id = web3.eth.chain_id
        processor_args = [
            es_instance, web3, allowed_publishers, purgatory, chain_id
        ]

        processor = (MetadataCreatedProcessor
                     if created_event else MetadataUpdatedProcessor)
        event_to_process = created_event[
            0] if created_event else updated_event[0]
        event_processor = processor(
            *([event_to_process, dt_contract, tx_receipt["from"]] +
              processor_args))
        event_processor.process()
        did = make_did(dt_address, chain_id)

        response = app.response_class(
            response=sanitize_record(es_instance.get(did)),
            status=200,
            mimetype="application/json",
        )
        return response
    except Exception as e:
        logger.error(f"trigger_caching failed: {str(e)}.")
        return (
            jsonify(
                error=f"Encountered error when triggering caching: {str(e)}."),
            500,
        )
Esempio n. 10
0
def get_ddo(did):
    """Get DDO of a particular asset.
    ---
    tags:
      - ddo
    parameters:
      - name: did
        in: path
        description: DID of the asset.
        required: true
        type: string
    responses:
      200:
        description: On successful operation returns DDO information.
        example:
          application/json: {
              "@context": "https://w3id.org/did/v1",
              "id": "did:op:00018b5b84eA05930f9D0dB8FFbb3B93EF86983b",
              "publicKey": [
                  {
                      "id": "did:op:00018b5b84eA05930f9D0dB8FFbb3B93EF86983b",
                      "type": "EthereumECDSAKey",
                      "owner": "0x8aa92201E19E4930d4D25c0f7a245c1dCdD5A242"
                  }
              ],
              "authentication": [
                  {
                      "type": "RsaSignatureAuthentication2018",
                      "publicKey": "did:op:00018b5b84eA05930f9D0dB8FFbb3B93EF86983b"
                  }
              ],
              "service": [
                  {
                      "type": "metadata",
                      "attributes": {
                          "main": {
                              "type": "dataset",
                              "name": "Nu nl",
                              "dateCreated": "2021-04-02T17:59:32Z",
                              "author": "ab",
                              "license": "MIT",
                              "files": [
                                  {
                                      "index": 0,
                                      "contentType": "application/json"
                                  }
                              ],
                              "datePublished": "2021-04-20T22:56:01Z"
                          },
                          "encryptedFiles": "0x047c992274f3fa2bf9c5cc57d0e0852f7b3ec22d7ab4e798e3e73e77e7f97"
                      },
                      "index": 0
                  },
                  {
                      "type": "access",
                      "index": 1,
                      "serviceEndpoint": "https://provider.datatunnel.allianceblock.io",
                      "attributes": {
                          "main": {
                              "creator": "0x8aa92201E19E4930d4D25c0f7a245c1dCdD5A242",
                              "datePublished": "2021-04-02T17:57:57Z",
                              "cost": "1",
                              "timeout": 2592000000,
                              "name": "dataAssetAccess"
                          }
                      }
                  }
              ],
              "datatoken": "0x00018b5b84eA05930f9D0dB8FFbb3B93EF86983b",
              "created": "2021-04-02T18:00:01Z",
              "proof": {
                  "created": "2021-04-02T17:59:33Z",
                  "creator": "0x8aa92201E19E4930d4D25c0f7a245c1dCdD5A242",
                  "type": "AddressHash",
                  "signatureValue": "0xd23d2f28fcf152347e5b5f1064422ba0288dd608f0ea6cf433a3717fb735a92d"
              },
              "datatokenInfo": {
                  "address": "0x00018b5b84eA05930f9D0dB8FFbb3B93EF86983b",
                  "name": "Parsimonious Plankton Token",
                  "symbol": "PARPLA-59",
                  "decimals": 18,
                  "totalSupply": 100.0,
                  "cap": 1000.0,
                  "minter": "0x8aa92201E19E4930d4D25c0f7a245c1dCdD5A242",
                  "minterBalance": 99.999
              },
              "updated": "2021-04-02T18:00:01Z",
              "price": {
                  "datatoken": 0.0,
                  "ocean": 0.0,
                  "value": 0.0,
                  "type": "",
                  "exchange_id": "",
                  "address": "",
                  "pools": [],
                  "isConsumable": ""
              },
              "isInPurgatory": "false"
            }
        content:
          application/json:
            schema:
              type: object
      404:
        description: This asset DID is not in ES.
    """
    try:
        asset_record = es_instance.get(did)
        response = app.response_class(
            response=sanitize_record(asset_record),
            status=200,
            mimetype="application/json",
        )
        return response
    except elasticsearch.exceptions.NotFoundError:
        return jsonify(
            error=f"Asset DID {did} not found in Elasticsearch."), 404
    except Exception as e:
        return (
            jsonify(
                error=
                f"Error encountered while searching the asset DID {did}: {str(e)}."
            ),
            404,
        )
Esempio n. 11
0
def test_sanitize_record():
    record = {"_id": "something", "other_value": "something else"}
    result = json.loads(sanitize_record(record))
    assert "_id" not in result
    assert result["other_value"] == "something else"