From 6eff703700c1462e886231bcfede786ababfddea Mon Sep 17 00:00:00 2001 From: rahmab Date: Fri, 12 Jun 2026 14:43:42 +0200 Subject: [PATCH 1/3] pdok-19209 NPE wegens gebrek aan DatasetMetadataURL --- .../capabilities_generator_test.go | 99 ++++++++++++++++++- .../capabilitiesgenerator/mapper.go | 9 +- .../wfs_input_no_dataset_metadata_rec.yaml | 80 +++++++++++++++ 3 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 internal/controller/capabilitiesgenerator/test_data/wfs_input_no_dataset_metadata_rec.yaml diff --git a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go index cda5991..95431c6 100644 --- a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go +++ b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go @@ -22,6 +22,9 @@ import ( //go:embed test_data/wfs_input.yaml var WFSInput string +//go:embed test_data/wfs_input_no_dataset_metadata_rec.yaml +var WFSInputNoDatasetMetadataRecord string + //go:embed test_data/wms_input.yaml var WMSInput string @@ -133,6 +136,100 @@ func TestGetInputForWFS(t *testing.T) { wantInput: WFSInput, wantErr: false, }, + { + name: "GetInputForWFSNoDatasetMetadata", + args: args{ + WFS: &pdoknlv3.WFS{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "dataset": "dataset", + "dataset-owner": "datasetOwner", + "theme": "theme", + "service-version": "v1_0", + }, + }, + Spec: pdoknlv3.WFSSpec{ + Service: pdoknlv3.WFSService{BaseService: pdoknlv3.BaseService{ + URL: smoothoperatormodel.URL{URL: url}, + Prefix: "prefix", + Title: "some Service title", + Abstract: "some \"Service\" abstract", + Keywords: []string{"service-keyword-1", "service-keyword-2", "infoFeatureAccessService"}, + AccessConstraints: smoothoperatormodel.URL{URL: accessConstraints}}, + Inspire: &pdoknlv3.WFSInspire{Inspire: pdoknlv3.Inspire{ + ServiceMetadataURL: pdoknlv3.MetadataURL{ + CSW: &pdoknlv3.Metadata{ + MetadataIdentifier: "metameta-meta-meta-meta-metametameta", + }, + }, + Language: "dut"}, + SpatialDatasetIdentifier: "datadata-data-data-data-datadatadata", + }, + DefaultCrs: "EPSG:28992", + OtherCrs: []string{ + "EPSG:28992", + "EPSG:25831", + "EPSG:25832", + "EPSG:3034", + "EPSG:3035", + "EPSG:3857", + "EPSG:4258", + "EPSG:4326", + }, + FeatureTypes: []pdoknlv3.FeatureType{ + { + Name: "featuretype-1-name", + Title: "featuretype-1-title", + Abstract: "feature \"1\" abstract", + Keywords: []string{"featuretype-1-keyword-1", "featuretype-1-keyword-2"}, + //DatasetMetadataURL: &pdoknlv3.MetadataURL{ + // CSW: &pdoknlv3.Metadata{ + // MetadataIdentifier: "datadata-data-data-data-datadatadata", + // }, + //}, + Bbox: &pdoknlv3.FeatureBbox{ + WGS84: &smoothoperatormodel.BBox{ + MinX: "-180", + MaxX: "180", + MinY: "-90", + MaxY: "90", + }, + }, + }, + { + Name: "featuretype-2-name", + Title: "featuretype-2-title", + Abstract: "feature \"2\" abstract", + Keywords: []string{"featuretype-2-keyword-1", "featuretype-2-keyword-2"}, + //DatasetMetadataURL: &pdoknlv3.MetadataURL{ + // CSW: &pdoknlv3.Metadata{ + // MetadataIdentifier: "datadata-data-data-data-datadatadata", + // }, + //}, + }, + }, + }, + }, + }, + ownerInfo: &smoothoperatorv1.OwnerInfo{ + Spec: smoothoperatorv1.OwnerInfoSpec{ + NamespaceTemplate: smoothoperatorutils.Pointer("http://{{prefix}}.geonovum.nl"), + MetadataUrls: &smoothoperatorv1.MetadataUrls{ + CSW: &smoothoperatorv1.MetadataURL{ + HrefTemplate: "https://www.nationaalgeoregister.nl/geonetwork/srv/dut/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&elementsetname=full&id={{identifier}}", + }, + }, + WFS: &smoothoperatorv1.WFS{ + ServiceProvider: smoothoperatorv1.ServiceProvider{ + ProviderName: smoothoperatorutils.Pointer("PDOK"), + }, + }, + }, + }, + }, + wantInput: WFSInputNoDatasetMetadataRecord, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -144,7 +241,7 @@ func TestGetInputForWFS(t *testing.T) { wantMap := capabilitiesgenerator.Config{} gotMap := capabilitiesgenerator.Config{} - err = yamlv3.Unmarshal([]byte(WFSInput), &wantMap) + err = yamlv3.Unmarshal([]byte(tt.wantInput), &wantMap) assert.NoError(t, err) err = yamlv3.Unmarshal([]byte(gotInput), &gotMap) assert.NoError(t, err) diff --git a/internal/controller/capabilitiesgenerator/mapper.go b/internal/controller/capabilitiesgenerator/mapper.go index 7084228..a28d16e 100644 --- a/internal/controller/capabilitiesgenerator/mapper.go +++ b/internal/controller/capabilitiesgenerator/mapper.go @@ -230,9 +230,12 @@ func getFeatureTypeList(wfs *pdoknlv3.WFS, ownerInfo *smoothoperatorv1.OwnerInfo } } - metadataURL, err := replaceMustacheTemplate(ownerInfo.Spec.MetadataUrls.CSW.HrefTemplate, fType.DatasetMetadataURL.CSW.MetadataIdentifier) - if err != nil { - return nil, err + var metadataURL string + if fType.DatasetMetadataURL != nil && fType.DatasetMetadataURL.CSW != nil { + metadataURL, err = replaceMustacheTemplate(ownerInfo.Spec.MetadataUrls.CSW.HrefTemplate, fType.DatasetMetadataURL.CSW.MetadataIdentifier) + if err != nil { + return nil, err + } } featureType := wfs200.FeatureType{ diff --git a/internal/controller/capabilitiesgenerator/test_data/wfs_input_no_dataset_metadata_rec.yaml b/internal/controller/capabilitiesgenerator/test_data/wfs_input_no_dataset_metadata_rec.yaml new file mode 100644 index 0000000..66b6f7c --- /dev/null +++ b/internal/controller/capabilitiesgenerator/test_data/wfs_input_no_dataset_metadata_rec.yaml @@ -0,0 +1,80 @@ +global: + prefix: prefix + namespace: http://prefix.geonovum.nl + onlineResourceUrl: http://localhost + path: /datasetOwner/dataset/theme/wfs/v1_0 + additionalSchemaLocations: http://inspire.ec.europa.eu/schemas/inspire_dls/1.0 http://inspire.ec.europa.eu/schemas/inspire_dls/1.0/inspire_dls.xsd +services: + wfs200: + filename: /var/www/config/capabilities_wfs_200.xml + definition: + serviceIdentification: + title: some Service title + abstract: 'some "Service" abstract' + keywords: + keyword: + - service-keyword-1 + - service-keyword-2 + - infoFeatureAccessService + accessConstraints: http://creativecommons.org/publicdomain/zero/1.0/deed.nl + serviceProvider: + providerName: PDOK + capabilities: + operationsMetadata: + extendedCapabilities: + extendedCapabilities: + metadataUrl: + url: https://www.nationaalgeoregister.nl/geonetwork/srv/dut/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&elementsetname=full&id=metameta-meta-meta-meta-metametameta + mediaType: application/vnd.ogc.csw.GetRecordByIdResponse_xml + supportedLanguages: + defaultLanguage: + language: dut + responseLanguage: + language: dut + spatialDataSetIdentifier: + code: datadata-data-data-data-datadatadata + featureTypeList: + featureType: + - name: prefix:featuretype-1-name + title: featuretype-1-title + abstract: 'feature "1" abstract' + keywords: + - keyword: + - featuretype-1-keyword-1 + - featuretype-1-keyword-2 + defaultCrs: urn:ogc:def:crs:EPSG::28992 + otherCrs: + - urn:ogc:def:crs:EPSG::28992 + - urn:ogc:def:crs:EPSG::25831 + - urn:ogc:def:crs:EPSG::25832 + - urn:ogc:def:crs:EPSG::3034 + - urn:ogc:def:crs:EPSG::3035 + - urn:ogc:def:crs:EPSG::3857 + - urn:ogc:def:crs:EPSG::4258 + - urn:ogc:def:crs:EPSG::4326 + wgs84BoundingBox: + lowerCorner: "-180 -90" + upperCorner: "180 90" +# Geen DatasetMetadataURL +# metadataUrl: +# href: https://www.nationaalgeoregister.nl/geonetwork/srv/dut/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&elementsetname=full&id=datadata-data-data-data-datadatadata + - name: prefix:featuretype-2-name + title: featuretype-2-title + abstract: 'feature "2" abstract' + keywords: + - keyword: + - featuretype-2-keyword-1 + - featuretype-2-keyword-2 + defaultCrs: urn:ogc:def:crs:EPSG::28992 + otherCrs: + - urn:ogc:def:crs:EPSG::28992 + - urn:ogc:def:crs:EPSG::25831 + - urn:ogc:def:crs:EPSG::25832 + - urn:ogc:def:crs:EPSG::3034 + - urn:ogc:def:crs:EPSG::3035 + - urn:ogc:def:crs:EPSG::3857 + - urn:ogc:def:crs:EPSG::4258 + - urn:ogc:def:crs:EPSG::4326 +# Geen DatasetMetadataURL +# metadataUrl: +# href: https://www.nationaalgeoregister.nl/geonetwork/srv/dut/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&elementsetname=full&id=datadata-data-data-data-datadatadata From 4bf54814566f1765167a33d96ea2ec3b6629a7c6 Mon Sep 17 00:00:00 2001 From: rahmab Date: Mon, 15 Jun 2026 15:04:34 +0200 Subject: [PATCH 2/3] pdok-19209 NPE omdat de grouplaag (zonder naam) even een style heeft gehad. --- .../capabilities_generator_test.go | 330 ++++++++++++++++++ .../capabilitiesgenerator/mapper.go | 13 +- ...wms_layer_without_name_input_expected.yaml | 152 ++++++++ 3 files changed, 493 insertions(+), 2 deletions(-) create mode 100644 internal/controller/capabilitiesgenerator/test_data/wms_layer_without_name_input_expected.yaml diff --git a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go index 95431c6..49b4d04 100644 --- a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go +++ b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go @@ -1,6 +1,8 @@ package capabilitiesgenerator import ( + "errors" + "github.com/google/go-cmp/cmp" "github.com/pdok/mapserver-operator/api/v2beta1" pdoknlv3 "github.com/pdok/mapserver-operator/api/v3" @@ -9,6 +11,7 @@ import ( smoothoperatormodel "github.com/pdok/smooth-operator/model" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" "sigs.k8s.io/yaml" yamlv3 "sigs.k8s.io/yaml/goyaml.v3" @@ -28,6 +31,9 @@ var WFSInputNoDatasetMetadataRecord string //go:embed test_data/wms_input.yaml var WMSInput string +//go:embed test_data/wms_layer_without_name_input_expected.yaml +var WMSLayerWithoutNameExpectedInput string + func TestGetInputForWFS(t *testing.T) { type args struct { WFS *pdoknlv3.WFS @@ -254,6 +260,330 @@ func TestGetInputForWFS(t *testing.T) { } } +func TestGetInputForWMSLayerWithoutName(t *testing.T) { + type args struct { + WMS *pdoknlv3.WMS + ownerInfo *smoothoperatorv1.OwnerInfo + } + url, _ := smoothoperatormodel.ParseURL("http://localhost/datasetOwner/dataset/theme/wms/v1_0") + pdoknlv3.SetHost("http://localhost") + accessConstraints, _ := smoothoperatormodel.ParseURL("http://creativecommons.org/publicdomain/zero/1.0/deed.nl") + tests := []struct { + name string + args args + wantInput string + isExpectingError bool + expectedError error + }{ + { + name: "GetInputForWMSLayerWithoutStylesWithoutName", + args: args{ + WMS: &pdoknlv3.WMS{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "pdok.nl/v3", + Kind: "WMS", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "tno-bro-geologisch-booron2861f-v2-0", + Namespace: "services", + }, + Spec: pdoknlv3.WMSSpec{ + + Service: pdoknlv3.WMSService{ + BaseService: pdoknlv3.BaseService{ + Title: "BRO - Geologisch booronderzoek (BHR-G) - Geologie (INSPIRE geharmoniseerd) WMS", + URL: smoothoperatormodel.URL{URL: url}, + AccessConstraints: smoothoperatormodel.URL{URL: accessConstraints}, + }, + DataEPSG: "EPSG:4258", + StylingAssets: &pdoknlv3.StylingAssets{ + BlobKeys: []string{ + "resources/fonts/bzk/geologie-bro-bhrp/wingdng2.ttf", + }, + ConfigMapRefs: []pdoknlv3.ConfigMapRef{ + { + Name: "tno-bro-geologisch-booron2861f-v2-0-styles-2cm978b5c8", + Keys: []string{ + "default_circle.symbol", + "default_line.style", + "default_point.style", + "default_polygon.style", + "geologicalSurvey.style", + "geologicalSurvey.symbol", + }, + }, + }, + }, + + Layer: pdoknlv3.Layer{ + Title: ptr.To("BRO - Geologisch booronderzoek (...) WMS"), + Abstract: ptr.To("Deze dataset bevat de gegevens over Geologische booronderzoeken..."), + Keywords: []string{ + "BHR-G", + "Geologie", + "Hydrologie", + "Bodemonderzoek", + "Bodemprofiel", + "Booronderzoek", + "Grondonderzoek", + "Nationaal", + }, + Visible: true, + + BoundingBoxes: []pdoknlv3.WMSBoundingBox{ + { + CRS: "EPSG:4258", + BBox: smoothoperatormodel.BBox{ + MinX: "2.35417303", + MinY: "50.71447164", + MaxX: "7.5553525", + MaxY: "55.66948102", + }, + }, + }, + + Layers: []pdoknlv3.Layer{ + { + Name: ptr.To("GE.Borehole"), + Title: ptr.To("Boorgaten"), + Abstract: ptr.To("Een boorgat is de algemene term..."), + Keywords: []string{"Boorgat"}, + Visible: true, + + Styles: []pdoknlv3.Style{ + { + Name: "GE.Borehole", + Title: ptr.To("Boreholes - geologicalSurvey"), + Visualization: ptr.To("geologicalSurvey.style"), + }, + }, + + Data: &pdoknlv3.Data{BaseData: pdoknlv3.BaseData{ + Postgis: &pdoknlv3.Postgis{ + Columns: []pdoknlv3.Column{ + {Name: "column-1"}, + {Name: "column-2"}, + }, + }}, + }, + }, + }, + }, + }, + }, + }, + ownerInfo: &smoothoperatorv1.OwnerInfo{ + Spec: smoothoperatorv1.OwnerInfoSpec{ + NamespaceTemplate: smoothoperatorutils.Pointer("http://{{prefix}}.geonovum.nl"), + MetadataUrls: &smoothoperatorv1.MetadataUrls{ + CSW: &smoothoperatorv1.MetadataURL{ + HrefTemplate: "https://www.nationaalgeoregister.nl/geonetwork/srv/dut/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&elementsetname=full&id={{identifier}}", + }, + }, + + ProviderSite: &smoothoperatorv1.ProviderSite{ + Type: "simple", + Href: "https://www.pdok.nl", + }, + WMS: &smoothoperatorv1.WMS{ + ContactInformation: smoothoperatorv1.ContactInformation{ + ContactPersonPrimary: &smoothoperatorv1.ContactPersonPrimary{ + ContactPerson: smoothoperatorutils.Pointer("KlantContactCenter PDOK"), + ContactOrganization: smoothoperatorutils.Pointer("PDOK"), + }, + ContactPosition: smoothoperatorutils.Pointer("pointOfContact"), + ContactAddress: &smoothoperatorv1.ContactAddress{ + AddressType: smoothoperatorutils.Pointer("Work"), + Address: nil, + City: smoothoperatorutils.Pointer("Apeldoorn"), + StateOrProvince: nil, + PostCode: nil, + Country: smoothoperatorutils.Pointer("The Netherlands"), + }, + ContactVoiceTelephone: nil, + ContactFacsimileTelephone: nil, + ContactElectronicMailAddress: smoothoperatorutils.Pointer("BeheerPDOK@kadaster.nl"), + }, + }, + }, + }, + }, + wantInput: WMSLayerWithoutNameExpectedInput, + isExpectingError: false, + expectedError: nil, + }, + { + name: "GetInputForWMSLayerWithStylesWithoutName", + args: args{ + WMS: &pdoknlv3.WMS{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "pdok.nl/v3", + Kind: "WMS", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "tno-bro-geologisch-booron2861f-v2-0", + Namespace: "services", + }, + Spec: pdoknlv3.WMSSpec{ + + Service: pdoknlv3.WMSService{ + BaseService: pdoknlv3.BaseService{ + Title: "BRO - Geologisch booronderzoek (BHR-G) - Geologie (INSPIRE geharmoniseerd) WMS", + URL: smoothoperatormodel.URL{URL: url}, + AccessConstraints: smoothoperatormodel.URL{URL: accessConstraints}, + }, + DataEPSG: "EPSG:4258", + StylingAssets: &pdoknlv3.StylingAssets{ + BlobKeys: []string{ + "resources/fonts/bzk/geologie-bro-bhrp/wingdng2.ttf", + }, + ConfigMapRefs: []pdoknlv3.ConfigMapRef{ + { + Name: "tno-bro-geologisch-booron2861f-v2-0-styles-2cm978b5c8", + Keys: []string{ + "default_circle.symbol", + "default_line.style", + "default_point.style", + "default_polygon.style", + "geologicalSurvey.style", + "geologicalSurvey.symbol", + }, + }, + }, + }, + + Layer: pdoknlv3.Layer{ + Title: ptr.To("BRO - Geologisch booronderzoek (...) WMS"), + Abstract: ptr.To("Deze dataset bevat de gegevens over Geologische booronderzoeken..."), + Keywords: []string{ + "BHR-G", + "Geologie", + "Hydrologie", + "Bodemonderzoek", + "Bodemprofiel", + "Booronderzoek", + "Grondonderzoek", + "Nationaal", + }, + Visible: true, + + BoundingBoxes: []pdoknlv3.WMSBoundingBox{ + { + CRS: "EPSG:4258", + BBox: smoothoperatormodel.BBox{ + MinX: "2.35417303", + MinY: "50.71447164", + MaxX: "7.5553525", + MaxY: "55.66948102", + }, + }, + }, + + Layers: []pdoknlv3.Layer{ + { + Name: ptr.To("GE.Borehole"), + Title: ptr.To("Boorgaten"), + Abstract: ptr.To("Een boorgat is de algemene term..."), + Keywords: []string{"Boorgat"}, + Visible: true, + + Styles: []pdoknlv3.Style{ + { + Name: "GE.Borehole", + Title: ptr.To("Boreholes - geologicalSurvey"), + Visualization: ptr.To("geologicalSurvey.style"), + }, + }, + + Data: &pdoknlv3.Data{BaseData: pdoknlv3.BaseData{ + Postgis: &pdoknlv3.Postgis{ + Columns: []pdoknlv3.Column{ + {Name: "column-1"}, + {Name: "column-2"}, + }, + }}, + }, + }, + }, + Styles: []pdoknlv3.Style{ + { + Name: "GE.Borehole", + Title: ptr.To("Boreholes - geologicalSurvey"), + Visualization: ptr.To("geologicalSurvey.style"), + }, + }, + }, + }, + }, + }, + ownerInfo: &smoothoperatorv1.OwnerInfo{ + Spec: smoothoperatorv1.OwnerInfoSpec{ + NamespaceTemplate: smoothoperatorutils.Pointer("http://{{prefix}}.geonovum.nl"), + MetadataUrls: &smoothoperatorv1.MetadataUrls{ + CSW: &smoothoperatorv1.MetadataURL{ + HrefTemplate: "https://www.nationaalgeoregister.nl/geonetwork/srv/dut/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&elementsetname=full&id={{identifier}}", + }, + }, + + ProviderSite: &smoothoperatorv1.ProviderSite{ + Type: "simple", + Href: "https://www.pdok.nl", + }, + WMS: &smoothoperatorv1.WMS{ + ContactInformation: smoothoperatorv1.ContactInformation{ + ContactPersonPrimary: &smoothoperatorv1.ContactPersonPrimary{ + ContactPerson: smoothoperatorutils.Pointer("KlantContactCenter PDOK"), + ContactOrganization: smoothoperatorutils.Pointer("PDOK"), + }, + ContactPosition: smoothoperatorutils.Pointer("pointOfContact"), + ContactAddress: &smoothoperatorv1.ContactAddress{ + AddressType: smoothoperatorutils.Pointer("Work"), + Address: nil, + City: smoothoperatorutils.Pointer("Apeldoorn"), + StateOrProvince: nil, + PostCode: nil, + Country: smoothoperatorutils.Pointer("The Netherlands"), + }, + ContactVoiceTelephone: nil, + ContactFacsimileTelephone: nil, + ContactElectronicMailAddress: smoothoperatorutils.Pointer("BeheerPDOK@kadaster.nl"), + }, + }, + }, + }, + }, + wantInput: "", + isExpectingError: true, + expectedError: errors.New("layer with styles and without name is not allowed"), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotInput, err := GetInput(tt.args.WMS, tt.args.ownerInfo) + + if !tt.isExpectingError { + if err != nil { + t.Errorf("GetInput() error = %v, wantErr %v", err, tt.isExpectingError) + return + } + wantMap := capabilitiesgenerator.Config{} + gotMap := capabilitiesgenerator.Config{} + err = yamlv3.Unmarshal([]byte(tt.wantInput), &wantMap) + assert.NoError(t, err) + err = yamlv3.Unmarshal([]byte(gotInput), &gotMap) + assert.NoError(t, err) + + diff := cmp.Diff(wantMap, gotMap) + if diff != "" { + t.Errorf("GetInput() mismatch (-want +got):\n%s", diff) + } + } else { + assert.Equal(t, err, tt.expectedError) + } + + }) + } +} func TestInputForWMS(t *testing.T) { //nolint:misspell v2wmsstring := "apiVersion: pdok.nl/v2beta1\nkind: WMS\nmetadata:\n name: rws-nwbwegen-v1-0\n labels:\n dataset-owner: rws\n dataset: nwbwegen\n service-version: v1_0\n service-type: wms\n annotations:\n lifecycle-phase: prod\n service-bundle-id: b39c152b-393b-52f5-a50c-e1ffe904b6fb\nspec:\n general:\n datasetOwner: rws\n dataset: nwbwegen\n serviceVersion: v1_0\n kubernetes:\n healthCheck:\n boundingbox: 135134.89,457152.55,135416.03,457187.82\n resources:\n limits:\n ephemeralStorage: 1535Mi\n memory: 4G\n requests:\n cpu: 2000m\n ephemeralStorage: 1535Mi\n memory: 4G\n options:\n automaticCasing: true\n disableWebserviceProxy: false\n includeIngress: true\n validateRequests: true\n service:\n title: NWB - Wegen WMS\n abstract:\n Dit is de web map service van het Nationaal Wegen Bestand (NWB) - wegen.\n Deze dataset bevat alleen de wegvakken en hectometerpunten. Het Nationaal Wegen\n Bestand - Wegen is een digitaal geografisch bestand van alle wegen in Nederland.\n Opgenomen zijn alle wegen die worden beheerd door wegbeheerders als het Rijk,\n provincies, gemeenten en waterschappen, echter alleen voor zover deze zijn voorzien\n van een straatnaam of nummer.\n authority:\n name: rws\n url: https://www.rijkswaterstaat.nl\n dataEPSG: EPSG:28992\n extent: -59188.44333693248 304984.64144318487 308126.88473339565 858328.516489961\n inspire: true\n keywords:\n - Vervoersnetwerken\n - Menselijke gezondheid en veiligheid\n - Geluidsbelasting hoofdwegen (Richtlijn Omgevingslawaai)\n - Nationaal\n - Voertuigen\n - Verkeer\n - Wegvakken\n - Hectometerpunten\n - HVD\n - Mobiliteit\n stylingAssets:\n configMapRefs:\n - name: includes\n keys:\n - nwb_wegen_hectopunten.symbol\n - hectopunten.style\n - wegvakken.style\n blobKeys:\n - resources/fonts/liberation-sans.ttf\n layers:\n - abstract:\n Deze laag bevat de wegvakken uit het Nationaal Wegen bestand (NWB)\n en geeft gedetailleerde informatie per wegvak zoals straatnaam, wegnummer,\n routenummer, wegbeheerder, huisnummers, enz. weer.\n data:\n gpkg:\n columns:\n - objectid\n - wvk_id\n - wvk_begdat\n - jte_id_beg\n - jte_id_end\n - wegbehsrt\n - wegnummer\n - wegdeelltr\n - hecto_lttr\n - bst_code\n - rpe_code\n - admrichtng\n - rijrichtng\n - stt_naam\n - stt_bron\n - wpsnaam\n - gme_id\n - gme_naam\n - hnrstrlnks\n - hnrstrrhts\n - e_hnr_lnks\n - e_hnr_rhts\n - l_hnr_lnks\n - l_hnr_rhts\n - begafstand\n - endafstand\n - beginkm\n - eindkm\n - pos_tv_wol\n - wegbehcode\n - wegbehnaam\n - distrcode\n - distrnaam\n - dienstcode\n - dienstnaam\n - wegtype\n - wgtype_oms\n - routeltr\n - routenr\n - routeltr2\n - routenr2\n - routeltr3\n - routenr3\n - routeltr4\n - routenr4\n - wegnr_aw\n - wegnr_hmp\n - geobron_id\n - geobron_nm\n - bronjaar\n - openlr\n - bag_orl\n - frc\n - fow\n - alt_naam\n - alt_nr\n - rel_hoogte\n - st_lengthshape\n geometryType: MultiLineString\n blobKey: geopackages/rws/nwbwegen/410a6d1e-e767-41b4-ba8d-9e1e955dd013/1/nwb_wegen.gpkg\n table: wegvakken\n datasetMetadataIdentifier: a9b7026e-0a81-4813-93bd-ba49e6f28502\n keywords:\n - Vervoersnetwerken\n - Menselijke gezondheid en veiligheid\n - Geluidsbelasting hoofdwegen (Richtlijn Omgevingslawaai)\n - Nationaal\n - Voertuigen\n - Verkeer\n - Wegvakken\n maxScale: 50000.0\n minScale: 1.0\n name: wegvakken\n sourceMetadataIdentifier: 8f0497f0-dbd7-4bee-b85a-5fdec484a7ff\n styles:\n - name: wegvakken\n title: NWB - Wegvakken\n visualization: wegvakken.style\n title: Wegvakken\n visible: true\n - abstract:\n Deze laag bevat de hectopunten uit het Nationaal Wegen Bestand (NWB)\n en geeft gedetailleerde informatie per hectopunt zoals hectometrering, afstand,\n zijde en hectoletter weer.\n data:\n gpkg:\n columns:\n - objectid\n - hectomtrng\n - afstand\n - wvk_id\n - wvk_begdat\n - zijde\n - hecto_lttr\n geometryType: MultiPoint\n blobKey: geopackages/rws/nwbwegen/410a6d1e-e767-41b4-ba8d-9e1e955dd013/1/nwb_wegen.gpkg\n table: hectopunten\n datasetMetadataIdentifier: a9b7026e-0a81-4813-93bd-ba49e6f28502\n keywords:\n - Vervoersnetwerken\n - Menselijke gezondheid en veiligheid\n - Geluidsbelasting hoofdwegen (Richtlijn Omgevingslawaai)\n - Nationaal\n - Voertuigen\n - Verkeer\n - Hectometerpunten\n maxScale: 50000.0\n minScale: 1.0\n name: hectopunten\n sourceMetadataIdentifier: 8f0497f0-dbd7-4bee-b85a-5fdec484a7ff\n styles:\n - name: hectopunten\n title: NWB - Hectopunten\n visualization: hectopunten.style\n title: Hectopunten\n visible: true\n metadataIdentifier: f2437a92-ddd3-4777-a1bc-fdf4b4a7fcb8\n" diff --git a/internal/controller/capabilitiesgenerator/mapper.go b/internal/controller/capabilitiesgenerator/mapper.go index a28d16e..b181a7e 100644 --- a/internal/controller/capabilitiesgenerator/mapper.go +++ b/internal/controller/capabilitiesgenerator/mapper.go @@ -1,6 +1,7 @@ package capabilitiesgenerator import ( + "errors" "fmt" "slices" "strconv" @@ -531,6 +532,11 @@ func mapLayer(layer pdoknlv3.Layer, canonicalURL string, authorityURL *wms130.Au return nil, err } + styles, err := getLayerStyles(layer, canonicalURL, parentStyleNames) + if err != nil { + return nil, err + } + l := wms130.Layer{ Queryable: smoothoperatorutils.Pointer(1), Opaque: nil, @@ -547,7 +553,7 @@ func mapLayer(layer pdoknlv3.Layer, canonicalURL string, authorityURL *wms130.Au Identifier: identifier, DataURL: nil, FeatureListURL: nil, - Style: getLayerStyles(layer, canonicalURL, parentStyleNames), + Style: styles, Layer: []*wms130.Layer{}, } @@ -666,8 +672,11 @@ func mapBBoxes(layerBBoxes []pdoknlv3.WMSBoundingBox, parentBBoxes []*wms130.Lay return crsses, exBbox, bboxes, nil } -func getLayerStyles(layer pdoknlv3.Layer, canonicalURL string, parentStyleNames []string) (styles []*wms130.Style) { +func getLayerStyles(layer pdoknlv3.Layer, canonicalURL string, parentStyleNames []string) (styles []*wms130.Style, err error) { for _, style := range layer.Styles { + if layer.Name == nil { + return nil, errors.New("layer with styles and without name is not allowed") + } if slices.Contains(parentStyleNames, style.Name) { continue } diff --git a/internal/controller/capabilitiesgenerator/test_data/wms_layer_without_name_input_expected.yaml b/internal/controller/capabilitiesgenerator/test_data/wms_layer_without_name_input_expected.yaml new file mode 100644 index 0000000..246980c --- /dev/null +++ b/internal/controller/capabilitiesgenerator/test_data/wms_layer_without_name_input_expected.yaml @@ -0,0 +1,152 @@ +global: + prefix: "" + namespace: http://.geonovum.nl + onlineResourceUrl: http://localhost + path: /datasetOwner/dataset/theme/wms/v1_0 + version: "" + additionalSchemaLocations: "" +services: + wms130: + filename: /var/www/config/capabilities_wms_130.xml + definition: + wmsCapabilities: + space: "" + local: "" + service: + name: WMS + title: BRO - Geologisch booronderzoek (BHR-G) - Geologie (INSPIRE geharmoniseerd) WMS + abstract: "" + keywordList: + keyword: [] + onlineResource: + xlink: null + type: null + href: https://www.pdok.nl + contactInformation: + contactPersonPrimary: + contactPerson: KlantContactCenter PDOK + contactOrganization: PDOK + contactPosition: pointOfContact + contactAddress: + addressType: Work + address: "" + city: Apeldoorn + stateOrProvince: "" + postalCode: "" + country: The Netherlands + contactVoiceTelephone: null + contactFacsimileTelephone: null + contactElectronicMailAddress: BeheerPDOK@kadaster.nl + fees: null + accessConstraints: http://creativecommons.org/publicdomain/zero/1.0/deed.nl + optionalConstraints: + maxWidth: 4000 + maxHeight: 4000 + capability: + wmsCapabilities: + request: + getCapabilities: + format: + - text/xml + dcpType: + http: + get: + onlineResource: + xlink: http://www.w3.org/1999/xlink + type: null + href: http://localhost/datasetOwner/dataset/theme/wms/v1_0? + post: null + getMap: + format: + - image/png + - image/jpeg + - image/png; mode=8bit + - image/vnd.jpeg-png + - image/vnd.jpeg-png8 + dcpType: + http: + get: + onlineResource: + xlink: http://www.w3.org/1999/xlink + type: null + href: http://localhost/datasetOwner/dataset/theme/wms/v1_0? + post: + onlineResource: + xlink: http://www.w3.org/1999/xlink + type: null + href: http://localhost/datasetOwner/dataset/theme/wms/v1_0 + getFeatureInfo: + format: + - application/json + - application/json; subtype=geojson + - application/vnd.ogc.gml + - text/html + - text/plain + - text/xml + - text/xml; subtype=gml/3.1.1 + dcpType: + http: + get: + onlineResource: + xlink: http://www.w3.org/1999/xlink + type: null + href: http://localhost/datasetOwner/dataset/theme/wms/v1_0? + post: + onlineResource: + xlink: http://www.w3.org/1999/xlink + type: null + href: http://localhost/datasetOwner/dataset/theme/wms/v1_0 + exception: + format: + - XML + - INIMAGE + - BLANK + layer: + - queryable: 1 + title: BRO - Geologisch booronderzoek (...) WMS + abstract: Deze dataset bevat de gegevens over Geologische booronderzoeken... + keywordList: + keyword: + - BHR-G + - Geologie + - Hydrologie + - Bodemonderzoek + - Bodemprofiel + - Booronderzoek + - Grondonderzoek + - Nationaal + crs: + - EPSG:4258 + boundingBox: + - crs: EPSG:4258 + minx: 2.35417303 + miny: 50.71447164 + maxx: 7.5553525 + maxy: 55.66948102 + layer: + - queryable: 1 + name: GE.Borehole + title: Boorgaten + abstract: Een boorgat is de algemene term... + keywordList: + keyword: + - Boorgat + crs: + - EPSG:4258 + boundingBox: + - crs: EPSG:4258 + minx: 2.35417303 + miny: 50.71447164 + maxx: 7.5553525 + maxy: 55.66948102 + style: + - name: GE.Borehole + title: Boreholes - geologicalSurvey + legendUrl: + width: 78 + height: 20 + format: image/png + onlineResource: + xlink: http://www.w3.org/1999/xlink + type: simple + href: http://localhost/datasetOwner/dataset/theme/wms/v1_0/legend/GE.Borehole/GE.Borehole.png From 3dbcac72852c83067baf21d25bd2cceab1956ed0 Mon Sep 17 00:00:00 2001 From: rahmab Date: Mon, 15 Jun 2026 17:02:29 +0200 Subject: [PATCH 3/3] pdok-19209 Linting fix --- .golangci.yml | 1 + .../capabilities_generator_test.go | 20 +++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index b18c0e4..e33271c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -102,6 +102,7 @@ linters: - cyclop - goconst - nolintlint + - misspell path: (.+)_test\.go paths: - third_party$ diff --git a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go index 49b4d04..fee231d 100644 --- a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go +++ b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go @@ -188,11 +188,11 @@ func TestGetInputForWFS(t *testing.T) { Title: "featuretype-1-title", Abstract: "feature \"1\" abstract", Keywords: []string{"featuretype-1-keyword-1", "featuretype-1-keyword-2"}, - //DatasetMetadataURL: &pdoknlv3.MetadataURL{ - // CSW: &pdoknlv3.Metadata{ - // MetadataIdentifier: "datadata-data-data-data-datadatadata", - // }, - //}, + // DatasetMetadataURL: &pdoknlv3.MetadataURL{ + // CSW: &pdoknlv3.Metadata{ + // MetadataIdentifier: "datadata-data-data-data-datadatadata", + // }, + // }, Bbox: &pdoknlv3.FeatureBbox{ WGS84: &smoothoperatormodel.BBox{ MinX: "-180", @@ -207,11 +207,11 @@ func TestGetInputForWFS(t *testing.T) { Title: "featuretype-2-title", Abstract: "feature \"2\" abstract", Keywords: []string{"featuretype-2-keyword-1", "featuretype-2-keyword-2"}, - //DatasetMetadataURL: &pdoknlv3.MetadataURL{ - // CSW: &pdoknlv3.Metadata{ - // MetadataIdentifier: "datadata-data-data-data-datadatadata", - // }, - //}, + // DatasetMetadataURL: &pdoknlv3.MetadataURL{ + // CSW: &pdoknlv3.Metadata{ + // MetadataIdentifier: "datadata-data-data-data-datadatadata", + // }, + // }, }, }, },