Skip to content

Commit

Permalink
Add MetadataURL to layer definition on GS
Browse files Browse the repository at this point in the history
  • Loading branch information
index-git committed May 24, 2023
1 parent 9245598 commit 831c88d
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
- [#528](https://github.com/LayerManager/layman/issues/528) Add new data type `enum_wfs_wms_status` and create new string column `wfs_wms_status` in `publications` table in prime DB schema.
#### Data migrations
- [#528](https://github.com/LayerManager/layman/issues/528) Fill column `wfs_wms_status` in `publications` table in prime DB schema. For layers set value `AVAILABLE` if fully available through WFS and WFS, otherwise `NOT_AVAILABLE`. Value is set to `null` for all existing maps.
- [#520](https://github.com/LayerManager/layman/issues/520) Set MetadataURL for each layer in WFS and WMS workspace in GeoServer.
### Changes
- [#528](https://github.com/LayerManager/layman/issues/528) Endpoints [GET Layers](doc/rest.md#get-layers) and [GET Workspace Layers](doc/rest.md#get-workspace-layers) returns new key `wfs_wms_status`.
- [#765](https://github.com/LayerManager/layman/issues/765) Remove Liferay from dev stack, use [Wagtail CRX](https://docs.coderedcorp.com/wagtail-crx/) + [Django OAuth Toolkit](https://django-oauth-toolkit.readthedocs.io/en/latest/) as new OAuth2 provider (authorization server).
Expand Down
82 changes: 82 additions & 0 deletions src/layman/upgrade/upgrade_v1_21.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import json
import logging
from urllib.parse import urljoin
import requests

from db import util as db_util
from geoserver import GS_REST_WORKSPACES, GS_REST_TIMEOUT, util as gs_common_util
from layman import settings
from layman.common.micka import util as micka_util
from layman.layer import LAYER_TYPE, util
from layman.layer.geoserver import wms, util as gs_util
from layman.map import MAP_TYPE

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -42,3 +48,79 @@ def adjust_publications_wfs_wms_status():
statement = f'alter table {DB_SCHEMA}.publications add constraint wfs_wms_status_with_type_check CHECK ' \
f'((wfs_wms_status IS NULL AND type = %s) OR (wfs_wms_status IS NOT NULL AND type = %s));'
db_util.run_statement(statement, (MAP_TYPE, LAYER_TYPE,))


def adjust_layer_metadata_url_on_gs():
logger.info(f' Adjust layer MetadataUrl on GeoServer')

headers_json = {
'Accept': 'application/json',
'Content-type': 'application/json',
}
auth = settings.LAYMAN_GS_AUTH

query = f'''select w.name, p.name, p.geodata_type, p.style_type, p.image_mosaic, p.uuid, PGP_SYM_DECRYPT(p.external_table_uri, p.uuid::text)::json external_table_uri
from {DB_SCHEMA}.publications p inner join
{DB_SCHEMA}.workspaces w on w.id = p.id_workspace
where p.type = %s
and p.wfs_wms_status = %s
;'''
layers = db_util.run_query(query, (LAYER_TYPE, settings.EnumWfsWmsStatus.AVAILABLE.value))

for workspace, layer, geodata_type, style_type, image_mosaic, uuid, external_table_uri in layers:
logger.info(f' Layer {workspace}:{layer}')
wms_workspace = wms.get_geoserver_workspace(workspace)

metadata_links = {
'metadataLinks':
{
"metadataLink": [
{
"type": "application/xml",
"metadataType": "ISO19115:2003",
"content": micka_util.get_metadata_url(uuid, url_type=micka_util.RecordUrlType.XML),
}
]
}
}

if geodata_type == settings.GEODATA_TYPE_RASTER:
wms_body = {"coverage": metadata_links}
store_name = wms.get_image_mosaic_store_name(layer) if image_mosaic else wms.get_geotiff_store_name(layer)
wms_url = urljoin(GS_REST_WORKSPACES, f'{wms_workspace}/coveragestores/{store_name}/coverages/{layer}')
elif geodata_type == settings.GEODATA_TYPE_VECTOR:
if style_type == 'sld':
wms_body = {"featureType": metadata_links}
store_name = gs_util.get_external_db_store_name(layer) if external_table_uri else gs_common_util.DEFAULT_DB_STORE_NAME
wms_url = urljoin(GS_REST_WORKSPACES, f'{wms_workspace}/datastores/{store_name}/featuretypes/{layer}')
elif style_type == 'qml':
wms_layer = gs_common_util.get_wms_layer(wms_workspace, layer, auth=auth)
wms_layer = {**wms_layer, **metadata_links}
wms_body = {"wmsLayer": wms_layer}
wms_url = urljoin(GS_REST_WORKSPACES, f'{wms_workspace}/wmslayers/{layer}')
else:
raise NotImplementedError(f"Unknown style type: {style_type}")

# WFS
wfs_body = {"featureType": metadata_links}
wfs_store = gs_util.get_external_db_store_name(layer) if external_table_uri else gs_common_util.DEFAULT_DB_STORE_NAME
response = requests.put(
urljoin(GS_REST_WORKSPACES, f'{workspace}/datastores/{wfs_store}/featuretypes/{layer}'),
data=json.dumps(wfs_body),
headers=headers_json,
auth=auth,
timeout=GS_REST_TIMEOUT,
)
response.raise_for_status()
else:
raise NotImplementedError(f"Unknown geodata type: {geodata_type}")

# WMS
response = requests.put(
wms_url,
data=json.dumps(wms_body),
headers=headers_json,
auth=auth,
timeout=GS_REST_TIMEOUT,
)
response.raise_for_status()
32 changes: 32 additions & 0 deletions src/layman/upgrade/upgrade_v1_21_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
from db import util as db_util
from layman import app, settings
from test_tools import process_client
from tests import Publication
from tests.asserts.final.publication import util as asserts_util
from tests.dynamic_data.publications import common_publications
from . import upgrade_v1_21

DB_SCHEMA = settings.LAYMAN_PRIME_SCHEMA
Expand Down Expand Up @@ -79,3 +82,32 @@ def test_wfs_wms_status(publ_type, publ_name, rest_args, exp_wfs_wms_status):
assert wfs_wms_status is None, f'publication={publ_type}:{workspace}.{publ_name}, wfs_wms_status={wfs_wms_status}'

process_client.delete_workspace_publication(publ_type, workspace, publ_name)


@pytest.mark.usefixtures('ensure_layman')
def test_adjust_layer_metadata_url_on_gs():
workspace = 'test_adjust_metadata_url_workspace'

layers = [
('vector_sld', common_publications.LAYER_VECTOR_SLD.definition),
('vector_qml', common_publications.LAYER_VECTOR_QML.definition),
('raster', common_publications.LAYER_RASTER.definition),
]

for layer, layer_def in layers:
process_client.publish_workspace_publication(process_client.LAYER_TYPE, workspace, layer, **layer_def)

for layer, _ in layers:
asserts_util.is_publication_valid_and_complete(Publication(workspace=workspace,
type=process_client.LAYER_TYPE,
name=layer))

with app.app_context():
upgrade_v1_21.adjust_layer_metadata_url_on_gs()

for layer, _ in layers:
asserts_util.is_publication_valid_and_complete(Publication(workspace=workspace,
type=process_client.LAYER_TYPE,
name=layer))

process_client.delete_workspace_layers(workspace)

0 comments on commit 831c88d

Please sign in to comment.