Skip to content

Commit

Permalink
Issue #78 Implementing remove_service
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanKJSchreurs committed Nov 8, 2022
1 parent 584d7dd commit 4097e0b
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 34 deletions.
36 changes: 34 additions & 2 deletions src/openeo_aggregator/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ def merge(services, to_add):
try:
services_json = con.get("/services").json()
except Exception as e:
_log.warning("Failed to get services from {con.id}: {e!r}", exc_info=True)
_log.warning(f"Failed to get services from {con.id}: {e!r}", exc_info=True)
continue

if services_json:
Expand All @@ -843,7 +843,7 @@ def service_info(self, user_id: str, service_id: str) -> ServiceMetadata:
try:
service_json = con.get(f"/services/{service_id}").json()
except Exception as e:
_log.debug("No service with ID={service_id} in backend with ID={con.id}: {e!r}", exc_info=True)
_log.debug(f"No service with ID={service_id} in backend with ID={con.id}: {e!r}", exc_info=True)
continue
else:
return ServiceMetadata.from_dict(service_json)
Expand Down Expand Up @@ -877,6 +877,34 @@ def create_service(self, user_id: str, process_graph: dict, service_type: str, a

return service.service_id

def remove_service(self, user_id: str, service_id: str) -> None:
"""https://openeo.org/documentation/1.0/developers/api/reference.html#operation/delete-service"""
# Search all services on the backends.
for con in self._backends:
try:
_ = con.get(f"/services/{service_id}")
except OpenEoApiError as e:
if e.http_status_code == 404:
_log.debug(f"No service with ID={service_id} in backend with ID={con.id}: {e!r}", exc_info=True)
continue
else:
_log.warning(f"Failed to get service {service_id!r} from {con.id}: {e!r}", exc_info=True)
raise e
except Exception as e:
_log.warning(f"Failed to get service {service_id!r} from {con.id}: {e!r}", exc_info=True)
raise e

try:
response_del = con.delete(f"/services/{service_id}")
except Exception as e:
_log.warning(f"Failed to delete service {service_id!r} from {con.id}: {e!r}", exc_info=True)
raise OpenEOApiException(
f"Failed to delete secondary service with id {service_id!r} on backend {con.id!r}: {e!r}"
) from e

if response_del.status_code != 204:
raise OpenEOApiException(f"Failed to delete secondary service with id {service_id!r} on backend {con.id!r}: {e!r}")


class AggregatorBackendImplementation(OpenEoBackendImplementation):
# No basic auth: OIDC auth is required (to get EGI Check-in eduperson_entitlement data)
Expand Down Expand Up @@ -1076,3 +1104,7 @@ def create_service(self, user_id: str, process_graph: dict, service_type: str, a
configuration: dict) -> Tuple[str, str]:
return self.secondary_services.create_service(user_id=user_id, process_graph=process_graph,
service_type=service_type, api_version=api_version, configuration=configuration)

def remove_service(self, user_id: str, service_id: str) -> None:
"""https://openeo.org/documentation/1.0/developers/api/reference.html#operation/delete-service"""
return self.secondary_services.remove_service(user_id=user_id, service_id=service_id)
105 changes: 73 additions & 32 deletions tests/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,10 +358,10 @@ def test_service_info_wrong_id(
)

with pytest.raises(ServiceNotFoundException):
_ = abe_implementation.service_info(user_id=TEST_USER, service_id="doesnotexist")
abe_implementation.service_info(user_id=TEST_USER, service_id="doesnotexist")

def test_create_service(self, api, multi_backend_connection, config, backend1, requests_mock):
"""When it gets a correct params for a new service, it succesfully creates it."""
"""When it gets a correct params for a new service, it successfully creates it."""

# Set up responses for creating the service in backend 1
expected_openeo_id = "wmts-foo"
Expand All @@ -373,22 +373,9 @@ def test_create_service(self, api, multi_backend_connection, config, backend1, r
"OpenEO-Identifier": expected_openeo_id,
"Location": location_backend_1
},
status_code=201)
service1 = ServiceMetadata(
id="wmts-foo",
process=process_graph,
url=location_backend_1,
type="WMTS",
enabled=True,
configuration={"version": "0.5.8"},
attributes={},
title="Test WMTS service",
)
requests_mock.get(
location_backend_1,
json=service1.prepare_for_json(),
status_code=200
status_code=201
)

abe_implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)

actual_openeo_id = abe_implementation.create_service(
Expand All @@ -405,6 +392,8 @@ def test_create_service(self, api, multi_backend_connection, config, backend1, r
def test_create_service_backend_raises_openeoapiexception(
self, multi_backend_connection, config, backend1, requests_mock, api_version, exception_class
):
"""When the backend raises a general exception the aggregator raises an OpenEOApiException."""

# Set up responses for creating the service in backend 1:
# This time the backend raises an error, one that will be reported as a OpenEOApiException.
process_graph = {"foo": {"process_id": "foo", "arguments": {}}}
Expand All @@ -415,13 +404,13 @@ def test_create_service_backend_raises_openeoapiexception(
abe_implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)

with pytest.raises(OpenEOApiException):
_ = abe_implementation.create_service(
user_id=TEST_USER,
process_graph=process_graph,
service_type="WMTS",
api_version=api_version,
configuration={}
)
abe_implementation.create_service(
user_id=TEST_USER,
process_graph=process_graph,
service_type="WMTS",
api_version=api_version,
configuration={}
)

@pytest.mark.parametrize("api_version", ["0.4.0", "1.0.0", "1.1.0"])
@pytest.mark.parametrize("exception_class",
Expand All @@ -430,24 +419,76 @@ def test_create_service_backend_raises_openeoapiexception(
def test_create_service_backend_reraises(
self, multi_backend_connection, config, backend1, requests_mock, api_version, exception_class
):
"""When the backend raises exception types that indicate client error / bad input data,
the aggregator raises and OpenEOApiException.
"""

# Set up responses for creating the service in backend 1
# This time the backend raises an error, one that will simply be re-raised/passed on as it is.
process_graph = {"foo": {"process_id": "foo", "arguments": {}}}
requests_mock.post(
backend1 + "/services",
exc=exception_class("Some server error"),
exc=exception_class("Some server error")
)
abe_implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)

# These exception types should be re-raised, not become an OpenEOApiException.
with pytest.raises(exception_class):
_ = abe_implementation.create_service(
user_id=TEST_USER,
process_graph=process_graph,
service_type="WMTS",
api_version=api_version,
configuration={}
)
abe_implementation.create_service(
user_id=TEST_USER,
process_graph=process_graph,
service_type="WMTS",
api_version=api_version,
configuration={}
)

def test_remove_service(self, multi_backend_connection, config, backend1, backend2, requests_mock, service_metadata_wmts_foo):
"""When it gets a correct service ID, it returns the expected ServiceMetadata."""
requests_mock.get(backend1 + "/services/wmts-foo", json=service_metadata_wmts_foo.prepare_for_json())
abe_implementation = AggregatorBackendImplementation(
backends=multi_backend_connection, config=config
)

requests_mock.get(
backend1 + "/services/wmts-foo",
json=service_metadata_wmts_foo.prepare_for_json(),
status_code=200
)
requests_mock.get(
backend2 + "/services/wmts-foo",
status_code=404
)
requests_mock.delete(backend1 + "/services/wmts-foo", status_code=204)
abe_implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)

# Should not raise any exceptions.
abe_implementation.remove_service(user_id=TEST_USER, service_id="wmts-foo")

@pytest.mark.parametrize("backend_status_code", [400, 500])
def test_remove_service_backend_response_is_an_error_status(
self, multi_backend_connection, config, backend1, backend2, requests_mock,
service_metadata_wmts_foo, backend_status_code
):
"""When it gets a correct service ID, it returns the expected ServiceMetadata."""
requests_mock.get(backend1 + "/services/wmts-foo", json=service_metadata_wmts_foo.prepare_for_json())
abe_implementation = AggregatorBackendImplementation(
backends=multi_backend_connection, config=config
)

requests_mock.get(
backend1 + "/services/wmts-foo",
json=service_metadata_wmts_foo.prepare_for_json(),
status_code=200
)
requests_mock.get(
backend2 + "/services/wmts-foo",
status_code=404
)
requests_mock.delete(backend1 + "/services/wmts-foo", status_code=backend_status_code)
abe_implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)

with pytest.raises(OpenEOApiException):
abe_implementation.remove_service(user_id=TEST_USER, service_id="wmts-foo")


class TestInternalCollectionMetadata:
Expand Down

0 comments on commit 4097e0b

Please sign in to comment.