예제 #1
0
def patch(research_id):
    req = request.json

    mdService = Metadata(testing=current_app.config.get("TESTING"))
    result = mdService.updateMetadataForResearch(research_id, req)

    return jsonify({"length": len(result), "list": result})
예제 #2
0
def get(user_id, research_index):
    req = request.json

    md = Metadata(testing=current_app.config.get("TESTING"))

    researchId = md.getResearchId(userId=user_id, researchIndex=research_index)

    result = md.getMetadataForResearch(researchId=researchId,
                                       metadataFields=req)

    return jsonify({
        "researchId": researchId,
        "length": len(result),
        "list": result
    })
예제 #3
0
def get(research_id):
    req = request.json

    result = Metadata(
        testing=current_app.config.get("TESTING")).getMetadataForResearch(
            researchId=research_id, metadataFields=req)

    return jsonify({"length": len(result), "list": result})
예제 #4
0
def put(user_id, research_index):
    mdService = Metadata(testing=current_app.config.get("TESTING"))
    research_id = mdService.getResearchId(user_id, int(research_index))
    resp = mdService.publish(research_id)

    url = "{}".format(
        os.getenv("CENTRAL_SERVICE_RESEARCH_MANAGER",
                  "{}/research".format(current_app.config.get("TESTING"))))
    requests.patch("{}/user/{}/research/{}/status".format(
        url, user_id, research_index),
                   verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
                   json={"finish": True})

    if resp:
        return None, 204

    return None, 400
예제 #5
0
    def test_metadata_get_metadata_from_connector(self):
        """
        This unit tests the ability of metadata object to get metadata from a given connector.
        This is the hard way to get informations from a specific port.
        """
        md = Metadata(testing=testing_address)

        port = "localhost:3000"
        projectId = 5

        metadata = {
            "Creators": [{
                "name": "Mustermann, Max",
                "nameType": "Personal",
                "familyName": "Mustermann",
                "givenName": "Max",
            }],
            "Identifiers": [{
                "identifierType": "DOI",
                "identifier": "10.5072/example"
            }],
            "PublicationYear":
            "2020",
            "Publisher":
            "University of Münster",
            "ResourceType":
            "Poster",
            "SchemaVersion":
            "http://datacite.org/schema/kernel-4",
            "Titles": [{
                "title": "This is a test title",
                "lang": "de"
            }]
        }

        pact.given('A port with metadata informations.').upon_receiving(
            'A call to get the metadata from specific researchId.'
        ).with_request('GET',
                       f"/metadata/project/{projectId}").will_respond_with(
                           200, body=metadata)

        with pact:
            result = md.getMetadataForProjectFromPort(port, projectId)
        self.assertEqual(result, metadata)
예제 #6
0
    def test_metadata_update_metadata_from_connector(self):
        """
        This unit tests the ability of metadata object to update metadata from a given connector.
        This is the hard way.
        """
        md = Metadata(testing=testing_address)

        def test_metadata_response(updateMetadata, projectId):
            port = "localhost:3000"

            metadata = {
                "Creators": [],
                "Identifiers": [],
                "PublicationYear": "",
                "Publisher": "",
                "ResourceType": "",
                "SchemaVersion": "http://datacite.org/schema/kernel-4",
                "Titles": []
            }

            metadata = dict(
                list(metadata.items()) + list(updateMetadata.items()))

            pact.given('A port with metadata informations.').upon_receiving(
                f'A call to update the metadata from specific projectId {projectId}.'
            ).with_request('PATCH',
                           f"/metadata/project/{projectId}").will_respond_with(
                               200, body=updateMetadata)

            with pact:
                result = md.updateMetadataForResearchFromPort(
                    port, projectId, updateMetadata)
            self.assertEqual(result, updateMetadata)

        updateMetadata = {}
        updateMetadata["Creators"] = [{
            "creatorName": "Max Mustermann",
            "nameType": "Personal",
            "familyName": "Mustermann",
            "givenName": "Max",
        }]
        test_metadata_response(updateMetadata, 10)

        updateMetadata["PublicationYear"] = "2020"
        test_metadata_response(updateMetadata, 11)
예제 #7
0
    def test_metadata_get_connector(self):
        """
        This unit tests the ability of metadata object to get connector from a researchId.
        """
        md = Metadata(testing=testing_address)

        def test_getPorts(func, userId, researchId, portIn, portOut):
            research = {
                "userId": userId,
                "status": 1,
                "portIn": portIn,
                "portOut": portOut,
                "researchId": researchIndex
            }

            pact.given('A research service with research.').upon_receiving(
                'A call to get the researchId from userId and researchIndex.'
            ).with_request(
                'GET', f"/research/user/{userId}/research/{researchIndex}"
            ).will_respond_with(200, body=research)

            with pact:
                result = func(userId, researchIndex)
            return result

        userId = "admin"
        researchIndex = 0

        for portIn in [[], ["port-owncloud"], ["port-owncloud",
                                               "port-zenodo"]]:
            for portOut in [[], ["port-owncloud"],
                            ["port-owncloud", "port-zenodo"]]:
                with self.subTest(portIn=portIn, portOut=portOut):
                    result = test_getPorts(md.getPortIn, userId, researchIndex,
                                           portIn, portOut)
                    self.assertEqual(result, portIn)

                    result = test_getPorts(md.getPortOut, userId,
                                           researchIndex, portIn, portOut)
                    self.assertEqual(result, portOut)
예제 #8
0
    def test_metadata_get_researchid(self):
        """
        This unit tests ability of metadata object to get the researchId for corresponding userId and research index.
        """
        md = Metadata(testing=testing_address)

        def test_researchId(userId, researchIndex, researchId):
            nonlocal md

            research = {
                "userId": userId,
                "status": 1,
                "portIn": [],
                "portOut": [],
                "researchIndex": researchIndex,
                "researchId": researchId
            }

            pact.given('A research service with research.').upon_receiving(
                f'A call to get the researchId from userId {userId} and researchIndex {researchIndex}.'
            ).with_request(
                'GET', f"/research/user/{userId}/research/{researchIndex}"
            ).will_respond_with(200, body=research)

            # should be the same as researchIndex, because there are no other research
            with pact:
                result = md.getResearchId(userId, researchIndex)
            self.assertEqual(result, researchId)

        userId = "admin"
        researchIndex = 0
        researchId = 0
        test_researchId(userId, researchIndex, researchId)
        researchIndex = 1
        researchId = 4
        test_researchId(userId, researchIndex, researchId)
예제 #9
0
def patch(user_id, research_index):
    try:
        req = request.json
    except:
        req = None

    if req is None or not req:
        # get ro crate file from portIn
        crates = []

        researchObj = Research(userId=user_id, researchIndex=research_index)
        for port in researchObj.portIn:
            filepath = ""

            for prop in port["properties"]:
                if prop["portType"] == "customProperties":
                    for cProp in prop["value"]:
                        if cProp["key"] == "filepath":
                            if str(cProp["value"]).endswith("/"):
                                filepath = "{}{}".format(
                                    cProp["value"], "ro-crate-metadata.json")
                            else:
                                filepath = "{}{}".format(
                                    cProp["value"], "/ro-crate-metadata.json")

            data = Util.parseToken(Util.loadToken(user_id, port["port"]))
            data["filepath"] = filepath

            crates.append(
                json.loads(
                    BytesIO(
                        requests.get(
                            "http://layer1-{}/storage/file".format(
                                port["port"]),
                            json=data,
                            verify=(os.environ.get("VERIFY_SSL",
                                                   "True") == "True"),
                        ).content).read().decode("UTF-8")))

        # push ro crate content to all portOut metadata
        for crate in crates:
            for port in researchObj.portOut:
                projectId = ""

                for prop in port["properties"]:
                    if prop["portType"] == "customProperties":
                        for cProp in prop["value"]:
                            if cProp["key"] == "projectId":
                                projectId = cProp["value"]

                data = Util.parseToken(Util.loadToken(user_id, port["port"]))
                data["metadata"] = crate

                requests.patch(
                    "http://layer1-{}/metadata/project/{}".format(
                        port["port"], projectId),
                    json=data,
                    verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
                )

        return "", 202

    mdService = Metadata(testing=current_app.config.get("TESTING"))
    research_id = mdService.getResearchId(user_id, research_index)
    result = mdService.updateMetadataForResearch(research_id, req)

    return jsonify({"length": len(result), "list": result})
예제 #10
0
    def test_metadata_get_metadata_from_researchId_filtered(self):
        """
        This unit tests the ability of metadata object to get metadata from a given researchId.
        This is the handy way with researchId.
        Notice: Should be very similar to `test_metadata_get_metadata_from_connector`
        """
        md = Metadata(testing=testing_address)

        userId = 20
        researchIndex = 21
        researchId = 22
        projectId = 5

        metadata = {
            "Creators": [{
                "name": "Mustermann, Max",
                "nameType": "Personal",
                "familyName": "Mustermann",
                "givenName": "Max",
            }],
            "Identifiers": [{
                "identifierType": "DOI",
                "identifier": "10.5072/example"
            }],
            "PublicationYear":
            "2020",
            "Publisher":
            "University of Münster",
            "ResourceType":
            "Poster",
            "SchemaVersion":
            "http://datacite.org/schema/kernel-4",
            "Titles": [{
                "title": "This is a test title",
                "lang": "de"
            }]
        }

        wanted_metadata = {"Titles": "", "Publisher": ""}

        expected_metadata_from_port = {
            "Titles": metadata["Titles"],
            "Publisher": metadata["Publisher"]
        }

        expected_research = {"userId": userId, "researchIndex": researchIndex}

        expected_research["researchId"] = researchId
        expected_research["portIn"] = [{
            "port":
            "port-zenodo",
            "properties": [{
                "portType": "metadata",
                "value": True
            }, {
                "portType":
                "customProperties",
                "value": [{
                    "key": "projectId",
                    "value": str(projectId)
                }]
            }]
        }, {
            "port":
            "port-owncloud",
            "properties": [{
                "portType": "fileStorage",
                "value": True
            }]
        }]

        expected_research["portOut"] = [{
            "port":
            "port-zenodo",
            "properties": [{
                "portType": "metadata",
                "value": True
            }]
        }]

        pact.given('The research manager.').upon_receiving(
            f'A call to get the researchIndex {researchIndex} and user {userId}.'
        ).with_request('GET', f"/research/id/{researchId}").will_respond_with(
            200, body=expected_research)

        expected_metadata = []

        # only portOut, because it has a duplicate from portIn and portIn has port-owncloud,
        # which should be out in results, because it is not of type `metadata`.
        for ports in expected_research["portOut"]:
            skip = True

            for prop in ports["properties"]:
                if prop["portType"] == "metadata":
                    skip = False

            if skip:
                continue

            pact.given('An access token for userid.').upon_receiving(
                f'A call to get the access token for user {userId} for metadata usage.'
            ).with_request(
                'GET',
                f"/user/{userId}/service/port-zenodo").will_respond_with(
                    200,
                    body=json.dumps(self.token1, cls=Util.get_json_encoder()))

            port = ports["port"]
            pact.given('A port with metadata informations.').upon_receiving(
                f'A call to get the metadata from specific projectId {projectId} and port {port} for {expected_metadata_from_port}.'
            ).with_request('GET',
                           f"/metadata/project/{projectId}").will_respond_with(
                               200, body=expected_metadata_from_port)

            expected_metadata.append({
                "port": port,
                "metadata": expected_metadata_from_port
            })

        with pact:
            result = md.getMetadataForResearch(researchId=researchId,
                                               metadataFields=wanted_metadata)
        self.assertEqual(result, expected_metadata)
예제 #11
0
    def test_metadata_update_metadata_from_projectId(self):
        """
        This unit tests the ability of metadata object to update metadata from a given researchId.
        This is the handy way.
        Notice: Should be very similar to `test_metadata_get_metadata_from_connector`
        """
        md = Metadata(testing=testing_address)

        def test_metadata_response(updateMetadata):
            userId = 0
            researchIndex = 0
            researchId = 2
            projectId = 5

            metadata = {
                "Creators": [],
                "Identifiers": [],
                "PublicationYear": "",
                "Publisher": "",
                "ResourceType": "",
                "SchemaVersion": "http://datacite.org/schema/kernel-4",
                "Titles": []
            }

            metadata = dict(
                list(metadata.items()) + list(updateMetadata.items()))

            expected_pid = {"userId": userId, "researchIndex": researchIndex}

            expected_research = expected_pid.copy()
            expected_research["status"] = 1
            expected_research["researchId"] = researchId
            expected_research["portIn"] = [{
                "port":
                "port-zenodo",
                "properties": [{
                    "portType": "metadata",
                    "value": True
                }]
            }, {
                "port":
                "port-owncloud",
                "properties": [{
                    "portType": "fileStorage",
                    "value": True
                }]
            }]

            expected_research["portOut"] = [{
                "port":
                "port-zenodo",
                "properties": [{
                    "portType": "metadata",
                    "value": True
                }, {
                    "portType":
                    "customProperties",
                    "value": [{
                        "key": "projectId",
                        "value": str(projectId)
                    }]
                }]
            }]

            pact.given('The research manager.').upon_receiving(
                'A call to get the researchIndex and user.').with_request(
                    'GET', f"/research/id/{researchId}").will_respond_with(
                        200, body=expected_research)

            expected_metadata = []
            # add patch requests for all given example ports, which are portType `metadata`
            for port in expected_research["portOut"]:
                skip = True

                for prop in port["properties"]:
                    if prop["portType"] == "metadata":
                        skip = False

                if skip:
                    continue

                pact.given('An access token for userid.').upon_receiving(
                    f'A call to get the access token for user {userId} for project.'
                ).with_request(
                    'GET',
                    f"/user/{userId}/service/port-zenodo").will_respond_with(
                        200,
                        body=json.dumps(self.token1,
                                        cls=Util.get_json_encoder()))

                portname = port["port"]

                pact.given(
                    'A port with metadata informations.'
                ).upon_receiving(
                    f'A call to update the metadata from specific projectId {projectId} for port {portname} with update {updateMetadata.keys()}.'
                ).with_request(
                    'PATCH',
                    f"/metadata/project/{projectId}").will_respond_with(
                        200, body=updateMetadata)

                expected_metadata.append({
                    "port": portname,
                    "metadata": updateMetadata
                })

            with pact:
                result = md.updateMetadataForResearch(researchId,
                                                      updateMetadata)
            self.assertEqual(result, expected_metadata)

        updateMetadata = {}
        updateMetadata["Creators"] = [{
            "creatorName": "Max Mustermann",
            "nameType": "Personal",
            "familyName": "Mustermann",
            "givenName": "Max",
        }]
        test_metadata_response(updateMetadata)

        updateMetadata["PublicationYear"] = "2021"
        test_metadata_response(updateMetadata)
예제 #12
0
    def test_metadata_init(self):
        """
        This unit tests the metadata object constructor.
        """

        Metadata(testing=testing_address)