Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions geoserver_acceptance_tests/tests/test_cascaded_stores.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,99 @@ def test_cascaded_wmts(geoserver_factory):
)
assert content == ""
assert status == 200


def test_cascaded_wms_republish_keeps_the_layer(geoserver_factory):
"""Publishing a cascaded WMS layer that already exists updates it instead of replacing it."""
workspace = "test_cascaded_wms_republish"
wms_store = "test_cascaded_wms_republish_store"
wms_url = (
"https://wms.geo.admin.ch/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities"
)
wms_layer = "ch.swisstopo.swissboundaries3d-gemeinde-flaeche.fill"
title = "title set outside the publish payload"
geoserver: GeoServerCloud = geoserver_factory(workspace)

# Create WMS store
content, status = geoserver.create_wms_store(
workspace_name=workspace,
wms_store_name=wms_store,
capabilities_url=wms_url,
)
assert status == 201

# Publish layer
content, status = geoserver.create_wms_layer(
workspace_name=workspace,
wms_store_name=wms_store,
native_layer_name=wms_layer,
)
assert status == 201

# Set a title, a setting the publish payload never sends
geoserver.rest_service.rest_client.put(
f"/rest/workspaces/{workspace}/wmsstores/{wms_store}/wmslayers/{wms_layer}.json",
json={"wmsLayer": {"title": title}},
)

# Publish the same layer again
content, status = geoserver.create_wms_layer(
workspace_name=workspace,
wms_store_name=wms_store,
native_layer_name=wms_layer,
)
assert status == 200

# The title survives, which a replaced layer would not have
content, status = geoserver.get_wms_layer(
workspace_name=workspace, wms_store_name=wms_store, wms_layer_name=wms_layer
)
assert status == 200
assert content["title"] == title


def test_cascaded_wmts_republish_keeps_the_layer(geoserver_factory):
"""Publishing a cascaded WMTS layer that already exists updates it instead of replacing it."""
workspace = "test_cascaded_wmts_republish"
wmts_store = "test_cascaded_wmts_republish_store"
wmts_url = "https://wmts.geo.admin.ch/EPSG/4326/1.0.0/WMTSCapabilities.xml"
wmts_layer = "ch.swisstopo.pixelkarte-grau"
title = "title set outside the publish payload"
geoserver: GeoServerCloud = geoserver_factory(workspace)
layer_path = (
f"/rest/workspaces/{workspace}/wmtsstores/{wmts_store}/layers/{wmts_layer}.json"
)

# Create WMTS store
content, status = geoserver.create_wmts_store(
workspace_name=workspace,
name=wmts_store,
capabilities=wmts_url,
)
assert status == 201

# Publish layer
content, status = geoserver.create_wmts_layer(
workspace_name=workspace,
wmts_store=wmts_store,
native_layer=wmts_layer,
)
assert status == 201

# Set a title, a setting the publish payload never sends
geoserver.rest_service.rest_client.put(
layer_path, json={"wmtsLayer": {"title": title}}
)

# Publish the same layer again
content, status = geoserver.create_wmts_layer(
workspace_name=workspace,
wmts_store=wmts_store,
native_layer=wmts_layer,
)
assert status == 200

# The title survives, which a replaced layer would not have
response = geoserver.rest_service.rest_client.get(layer_path)
assert response.status_code == 200
assert response.json()["wmtsLayer"]["title"] == title
5 changes: 3 additions & 2 deletions geoservercloud/geoservercloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,7 @@ def create_wms_layer(
) -> tuple[str, int]:
"""
Publish a remote WMS layer.
If it already exists, delete and recreate it (update is not supported by GeoServer)
If it already exists, update it in place, keeping the fields absent from the payload.

:param workspace_name: Name of the workspace
:type workspace_name: str
Expand Down Expand Up @@ -1477,7 +1477,8 @@ def create_wmts_layer(
international_abstract: dict[str, str] | None = None,
) -> tuple[str, int]:
"""
Publish a remote WMTS layer (first delete it if it already exists)
Publish a remote WMTS layer.
If it already exists, update it in place, keeping the fields absent from the payload.

:param workspace_name: Name of the workspace
:type workspace_name: str
Expand Down
38 changes: 19 additions & 19 deletions geoservercloud/services/restservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,17 @@ def get_wms_layer(
def create_wms_layer(
self, workspace_name: str, wms_store_name: str, wms_layer: WmsLayer
) -> tuple[str, int]:
if self.resource_exists(
self.rest_endpoints.wmslayer(workspace_name, wms_store_name, wms_layer.name)
):
self.delete_wms_layer(workspace_name, wms_store_name, wms_layer.name)
response: Response = self.rest_client.post(
self.rest_endpoints.wmslayers(workspace_name, wms_store_name),
json=wms_layer.post_payload(),
resource_path: str = self.rest_endpoints.wmslayer(
workspace_name, wms_store_name, wms_layer.name
)
response: Response
if not self.resource_exists(resource_path):
response = self.rest_client.post(
self.rest_endpoints.wmslayers(workspace_name, wms_store_name),
json=wms_layer.post_payload(),
)
else:
response = self.rest_client.put(resource_path, json=wms_layer.put_payload())
return response.content.decode(), response.status_code

def delete_wms_layer(
Expand Down Expand Up @@ -252,16 +255,6 @@ def create_wmts_layer(
international_title: dict[str, str] | None = None,
international_abstract: dict[str, str] | None = None,
) -> tuple[str, int]:
resource_path: str = self.rest_endpoints.wmtslayer(
workspace_name, wmts_store, published_layer
)
if self.resource_exists(resource_path):
self.rest_client.delete(
resource_path,
params={"recurse": "true"},
)
# Also delete the corresponding GWC layer (delete is not cascaded when using REST API)
self.delete_gwc_layer(workspace_name, published_layer)
capabilities_url: str = (
self.rest_client.get(
self.rest_endpoints.wmtsstore(workspace_name, wmts_store)
Expand All @@ -283,9 +276,16 @@ def create_wmts_layer(
international_abstract=international_abstract,
)

response: Response = self.rest_client.post(
self.rest_endpoints.wmtslayers(workspace_name, wmts_store), json=payload
resource_path: str = self.rest_endpoints.wmtslayer(
workspace_name, wmts_store, published_layer
)
response: Response
if not self.resource_exists(resource_path):
response = self.rest_client.post(
self.rest_endpoints.wmtslayers(workspace_name, wmts_store), json=payload
)
else:
response = self.rest_client.put(resource_path, json=payload)
return response.content.decode(), response.status_code

def get_gwc_layer(
Expand Down
13 changes: 2 additions & 11 deletions tests/test_cascaded_wmts.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,6 @@ def test_create_wmts_layer_already_exists(
f"{geoserver.url}/rest/workspaces/{WORKSPACE}/wmtsstores/{STORE}/layers/{LAYER}.json",
status=200,
)
rsps.delete(
f"{geoserver.url}/rest/workspaces/{WORKSPACE}/wmtsstores/{STORE}/layers/{LAYER}.json",
status=200,
match=[responses.matchers.query_param_matcher({"recurse": "true"})],
)
rsps.delete(
url=f"{geoserver.url}/gwc/rest/layers/{WORKSPACE}:{LAYER}.json",
status=200,
)
rsps.get(
f"{geoserver.url}/rest/workspaces/{WORKSPACE}/wmtsstores/{STORE}.json",
status=200,
Expand All @@ -196,8 +187,8 @@ def test_create_wmts_layer_already_exists(
body=CAPABILITIES,
headers={"Content-Type": "application/xml"},
)
rsps.post(
f"{geoserver.url}/rest/workspaces/{WORKSPACE}/wmtsstores/{STORE}/layers.json",
rsps.put(
f"{geoserver.url}/rest/workspaces/{WORKSPACE}/wmtsstores/{STORE}/layers/{LAYER}.json",
match=[responses.matchers.json_params_matcher(wmts_layer_payload)],
status=201,
body=b"test_layer",
Expand Down
12 changes: 3 additions & 9 deletions tests/test_wms_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,10 @@ def test_update_wms_layer(
f"{geoserver.url}/rest/workspaces/{WORKSPACE}/wmsstores/{STORE}/wmslayers/{LAYER}.json",
status=200,
)
rsps.delete(
rsps.put(
f"{geoserver.url}/rest/workspaces/{WORKSPACE}/wmsstores/{STORE}/wmslayers/{LAYER}.json",
status=200,
body=b"",
match=[responses.matchers.query_param_matcher({"recurse": "true"})],
)
rsps.post(
f"{geoserver.url}/rest/workspaces/{WORKSPACE}/wmsstores/{STORE}/wmslayers.json",
match=[responses.matchers.json_params_matcher(wms_layer_post_payload)],
status=201,
status=200,
body=b"",
)
content, code = geoserver.create_wms_layer(
Expand All @@ -145,7 +139,7 @@ def test_update_wms_layer(
)

assert content == ""
assert code == 201
assert code == 200


def test_delete_wms_layer(geoserver: GeoServerCloud) -> None:
Expand Down
Loading