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 cda5991..fee231d 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" @@ -22,9 +25,15 @@ 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 +//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 @@ -133,6 +142,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 +247,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) @@ -157,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 7084228..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" @@ -230,9 +231,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{ @@ -528,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, @@ -544,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{}, } @@ -663,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/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 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