Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(PXP-6604) DRS endpoint to resolve regardless of prefix #291

Merged
merged 13 commits into from
Oct 20, 2020
2 changes: 1 addition & 1 deletion indexd/drs/blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def get_drs_object(object_id):
"""
expand = True if flask.request.args.get("expand") == "true" else False

ret = blueprint.index_driver.get(object_id)
ret = blueprint.index_driver.get_with_nonstrict_prefix(object_id)

data = indexd_to_drs(ret, expand=expand, list_drs=False)

Expand Down
4 changes: 2 additions & 2 deletions indexd/index/blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ def get_index_record(record):
Returns a record.
"""

ret = blueprint.index_driver.get(record)
ret = blueprint.index_driver.get_with_nonstrict_prefix(record)
olivarity marked this conversation as resolved.
Show resolved Hide resolved

return flask.jsonify(ret), 200

Expand Down Expand Up @@ -717,7 +717,7 @@ def get_bundle_record_with_id(bundle_id):

expand = True if flask.request.args.get("expand") == "true" else False

ret = blueprint.index_driver.get(bundle_id)
ret = blueprint.index_driver.get_with_nonstrict_prefix(bundle_id)

ret = bundle_to_drs(ret, expand=expand, is_content=False)

Expand Down
25 changes: 25 additions & 0 deletions indexd/index/drivers/alchemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,31 @@ def get(self, did, expand=True):

return record.to_document_dict()

def get_with_nonstrict_prefix(self, did, expand=True):
olivarity marked this conversation as resolved.
Show resolved Hide resolved
"""
Attempt to retrieve a record both with and without a prefix.
Proxies 'get' with provided id.
If not found but prefix matches default, attempt with prefix stripped.
If not found and id has no prefix, attempt with default prefix prepended.
"""
try:
record = self.get(did, expand=expand)
except NoRecordFound as e:
DEFAULT_PREFIX = self.config.get("DEFAULT_PREFIX")
if not DEFAULT_PREFIX:
raise e

if "/" in did:
prefix, uuid = did.rsplit("/", 1)
if prefix + "/" == DEFAULT_PREFIX:
record = self.get(uuid, expand=expand)
else:
raise e
else:
record = self.get(DEFAULT_PREFIX + did, expand=expand)

return record

def update(self, did, rev, changing_fields):
"""
Updates an existing record with new values.
Expand Down
155 changes: 155 additions & 0 deletions tests/test_driver_alchemy_crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,161 @@ def test_driver_get_fails_with_no_records():
driver.get("some_record_that_does_not_exist")


@util.removes("index.sq3")
def test_driver_nonstrict_get_without_prefix():
"""
Tests retrieval of a record when a default prefix is set, but no prefix is supplied by the request.
"""
with sqlite3.connect("index.sq3") as conn:

driver = SQLAlchemyIndexDriver(
"sqlite:///index.sq3",
index_config={
"DEFAULT_PREFIX": "testprefix/",
"PREPEND_PREFIX": True,
"ADD_PREFIX_ALIAS": False,
},
)

did = str(uuid.uuid4())
baseid = str(uuid.uuid4())
rev = str(uuid.uuid4())[:8]
size = 512
form = "object"
baseid = str(uuid.uuid4())
created_date = datetime.now()
updated_date = datetime.now()

conn.execute(
"""
INSERT INTO index_record(did, baseid, rev, form, size, created_date, updated_date) VALUES (?,?,?,?,?,?,?)
""",
("testprefix/" + did, baseid, rev, form, size, created_date, updated_date),
)

conn.commit()

record = driver.get_with_nonstrict_prefix(did)

assert record["did"] == "testprefix/" + did, "record id does not match"
assert record["baseid"] == baseid, "record id does not match"
olivarity marked this conversation as resolved.
Show resolved Hide resolved
assert record["rev"] == rev, "record revision does not match"
assert record["size"] == size, "record size does not match"
assert record["form"] == form, "record form does not match"
assert (
record["created_date"] == created_date.isoformat()
), "created date does not match"
assert (
record["updated_date"] == updated_date.isoformat()
), "updated date does not match"


@util.removes("index.sq3")
def test_driver_nonstrict_get_with_prefix():
"""
Tests retrieval of a record when a default prefix is set and supplied by the request,
but records are stored without prefixes.
"""
with sqlite3.connect("index.sq3") as conn:

driver = SQLAlchemyIndexDriver(
"sqlite:///index.sq3",
index_config={
"DEFAULT_PREFIX": "testprefix/",
"PREPEND_PREFIX": False,
"ADD_PREFIX_ALIAS": True,
},
)

did = str(uuid.uuid4())
baseid = str(uuid.uuid4())
rev = str(uuid.uuid4())[:8]
size = 512
form = "object"
baseid = str(uuid.uuid4())
created_date = datetime.now()
updated_date = datetime.now()

conn.execute(
"""
INSERT INTO index_record(did, baseid, rev, form, size, created_date, updated_date) VALUES (?,?,?,?,?,?,?)
""",
(did, baseid, rev, form, size, created_date, updated_date),
)

conn.commit()

record = driver.get_with_nonstrict_prefix("testprefix/" + did)

assert record["did"] == did, "record id does not match"
assert record["baseid"] == baseid, "record id does not match"
olivarity marked this conversation as resolved.
Show resolved Hide resolved
assert record["rev"] == rev, "record revision does not match"
assert record["size"] == size, "record size does not match"
assert record["form"] == form, "record form does not match"
assert (
record["created_date"] == created_date.isoformat()
), "created date does not match"
assert (
record["updated_date"] == updated_date.isoformat()
), "updated date does not match"


@util.removes("index.sq3")
def test_driver_nonstrict_get_with_incorrect_prefix():
"""
Tests retrieval of a record fails if default prefix is set and request uses a different prefix with same uuid
"""
with sqlite3.connect("index.sq3") as conn:

driver = SQLAlchemyIndexDriver(
"sqlite:///index.sq3",
index_config={
"DEFAULT_PREFIX": "testprefix/",
"PREPEND_PREFIX": True,
"ADD_PREFIX_ALIAS": False,
},
)

did = str(uuid.uuid4())
baseid = str(uuid.uuid4())
rev = str(uuid.uuid4())[:8]
size = 512
form = "object"
baseid = str(uuid.uuid4())
created_date = datetime.now()
updated_date = datetime.now()

conn.execute(
"""
INSERT INTO index_record(did, baseid, rev, form, size, created_date, updated_date) VALUES (?,?,?,?,?,?,?)
""",
("testprefix/" + did, baseid, rev, form, size, created_date, updated_date),
)

conn.commit()

with pytest.raises(NoRecordFound):
driver.get_with_nonstrict_prefix("wrongprefix/" + did)


@util.removes("index.sq3")
def test_driver_nonstrict_get_with_no_default_prefix():
"""
Tests retrieval of a record fails as expected if no default prefix is set
"""
driver = SQLAlchemyIndexDriver(
"sqlite:///index.sq3",
index_config={
"DEFAULT_PREFIX": None,
"PREPEND_PREFIX": False,
"ADD_PREFIX_ALIAS": False,
},
)

with pytest.raises(NoRecordFound):
driver.get_with_nonstrict_prefix("fake_id_without_prefix")


@util.removes("index.sq3")
def test_driver_get_latest_version():
"""
Expand Down