Skip to content

Commit d20d835

Browse files
committed
Merge branch 'master' into PDOK-17793-wfs-molecule-tests
# Conflicts: # api/v2beta1/wfs_conversion.go # api/v2beta1/wms_conversion.go # api/v2beta1/wms_conversion_test.go # internal/controller/capabilitiesgenerator/capabilities_generator_test.go # internal/controller/legendgenerator/legend_generator_test.go # internal/controller/mapfilegenerator/mapfile_generator_test.go
2 parents 452b762 + 66d2f85 commit d20d835

31 files changed

+434
-211
lines changed

api/v2beta1/wfs_conversion.go

Lines changed: 80 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,86 @@ func (src *WFS) ConvertTo(dstRaw conversion.Hub) error {
3939
dst := dstRaw.(*pdoknlv3.WFS)
4040
log.Printf("ConvertTo: Converting WFS from Spoke version v2beta1 to Hub version v3;"+
4141
"source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name)
42-
V3WFSHubFromV2(src, dst)
42+
43+
return src.ToV3(dst)
44+
}
45+
46+
func (src *WFS) ToV3(dst *pdoknlv3.WFS) error {
47+
dst.ObjectMeta = src.ObjectMeta
48+
49+
// Set LifeCycle if defined
50+
if src.Spec.Kubernetes.Lifecycle != nil && src.Spec.Kubernetes.Lifecycle.TTLInDays != nil {
51+
dst.Spec.Lifecycle = &sharedModel.Lifecycle{
52+
TTLInDays: Pointer(int32(*src.Spec.Kubernetes.Lifecycle.TTLInDays)),
53+
}
54+
}
55+
56+
if src.Spec.Kubernetes.Autoscaling != nil {
57+
dst.Spec.HorizontalPodAutoscalerPatch = ConvertAutoscaling(*src.Spec.Kubernetes.Autoscaling)
58+
}
59+
60+
// TODO converse src.Spec.Kubernetes.HealthCheck when we know what the implementation in v3 will be
61+
if src.Spec.Kubernetes.Resources != nil {
62+
dst.Spec.PodSpecPatch = ConvertResources(*src.Spec.Kubernetes.Resources)
63+
}
64+
65+
dst.Spec.Options = *ConvertOptionsV2ToV3(src.Spec.Options)
66+
67+
service := pdoknlv3.WFSService{
68+
// TODO what is prefix, Geonovum subdomain?
69+
Prefix: "prefix",
70+
URL: CreateBaseURL("https://service.pdok.nl", "wfs", src.Spec.General),
71+
OwnerInfoRef: "pdok",
72+
Title: src.Spec.Service.Title,
73+
Abstract: src.Spec.Service.Abstract,
74+
Keywords: src.Spec.Service.Keywords,
75+
Fees: nil,
76+
AccessConstraints: src.Spec.Service.AccessConstraints,
77+
DefaultCrs: src.Spec.Service.DataEPSG,
78+
OtherCrs: []string{},
79+
CountDefault: src.Spec.Service.Maxfeatures,
80+
FeatureTypes: make([]pdoknlv3.FeatureType, 0),
81+
}
82+
83+
if src.Spec.Service.Mapfile != nil {
84+
service.Mapfile = &pdoknlv3.Mapfile{
85+
ConfigMapKeyRef: src.Spec.Service.Mapfile.ConfigMapKeyRef,
86+
}
87+
}
88+
89+
if src.Spec.Service.Extent != nil && *src.Spec.Service.Extent != "" {
90+
service.Bbox = &pdoknlv3.Bbox{
91+
DefaultCRS: sharedModel.ExtentToBBox(*src.Spec.Service.Extent),
92+
}
93+
} else {
94+
service.Bbox = &pdoknlv3.Bbox{
95+
DefaultCRS: sharedModel.BBox{
96+
MinX: "-25000",
97+
MaxX: "280000",
98+
MinY: "250000",
99+
MaxY: "860000",
100+
},
101+
}
102+
}
103+
104+
// TODO - where to place the MetadataIdentifier and FeatureTypes[0].SourceMetadataIdentifier if the service is not inspire?
105+
if src.Spec.Service.Inspire {
106+
service.Inspire = &pdoknlv3.Inspire{
107+
ServiceMetadataURL: pdoknlv3.MetadataURL{
108+
CSW: &pdoknlv3.Metadata{
109+
MetadataIdentifier: src.Spec.Service.MetadataIdentifier,
110+
},
111+
},
112+
SpatialDatasetIdentifier: src.Spec.Service.FeatureTypes[0].SourceMetadataIdentifier,
113+
Language: "dut",
114+
}
115+
}
116+
117+
for _, featureType := range src.Spec.Service.FeatureTypes {
118+
service.FeatureTypes = append(service.FeatureTypes, convertV2FeatureTypeToV3(featureType))
119+
}
120+
121+
dst.Spec.Service = service
43122

44123
return nil
45124
}
@@ -144,81 +223,3 @@ func (dst *WFS) ConvertFrom(srcRaw conversion.Hub) error {
144223

145224
return nil
146225
}
147-
148-
func V3WFSHubFromV2(src *WFS, target *pdoknlv3.WFS) {
149-
target.ObjectMeta = src.ObjectMeta
150-
151-
// Set LifeCycle if defined
152-
if src.Spec.Kubernetes.Lifecycle != nil && src.Spec.Kubernetes.Lifecycle.TTLInDays != nil {
153-
target.Spec.Lifecycle = &sharedModel.Lifecycle{
154-
TTLInDays: Pointer(int32(*src.Spec.Kubernetes.Lifecycle.TTLInDays)),
155-
}
156-
}
157-
158-
if src.Spec.Kubernetes.Autoscaling != nil {
159-
target.Spec.HorizontalPodAutoscalerPatch = ConvertAutoscaling(*src.Spec.Kubernetes.Autoscaling)
160-
}
161-
162-
// TODO converse src.Spec.Kubernetes.HealthCheck when we know what the implementation in v3 will be
163-
if src.Spec.Kubernetes.Resources != nil {
164-
target.Spec.PodSpecPatch = ConvertResources(*src.Spec.Kubernetes.Resources)
165-
}
166-
167-
target.Spec.Options = *ConvertOptionsV2ToV3(src.Spec.Options)
168-
169-
service := pdoknlv3.WFSService{
170-
// TODO what is prefix, Geonovum subdomain?
171-
Prefix: "prefix",
172-
URL: CreateBaseURL("https://service.pdok.nl", "wfs", src.Spec.General),
173-
OwnerInfoRef: "pdok",
174-
Title: src.Spec.Service.Title,
175-
Abstract: src.Spec.Service.Abstract,
176-
Keywords: src.Spec.Service.Keywords,
177-
Fees: nil,
178-
AccessConstraints: src.Spec.Service.AccessConstraints,
179-
DefaultCrs: src.Spec.Service.DataEPSG,
180-
OtherCrs: []string{},
181-
CountDefault: src.Spec.Service.Maxfeatures,
182-
FeatureTypes: make([]pdoknlv3.FeatureType, 0),
183-
}
184-
185-
if src.Spec.Service.Mapfile != nil {
186-
service.Mapfile = &pdoknlv3.Mapfile{
187-
ConfigMapKeyRef: src.Spec.Service.Mapfile.ConfigMapKeyRef,
188-
}
189-
}
190-
191-
if src.Spec.Service.Extent != nil && *src.Spec.Service.Extent != "" {
192-
service.Bbox = &pdoknlv3.Bbox{
193-
DefaultCRS: sharedModel.ExtentToBBox(*src.Spec.Service.Extent),
194-
}
195-
} else {
196-
service.Bbox = &pdoknlv3.Bbox{
197-
DefaultCRS: sharedModel.BBox{
198-
MinX: "-25000",
199-
MaxX: "280000",
200-
MinY: "250000",
201-
MaxY: "860000",
202-
},
203-
}
204-
}
205-
206-
// TODO - where to place the MetadataIdentifier and FeatureTypes[0].SourceMetadataIdentifier if the service is not inspire?
207-
if src.Spec.Service.Inspire {
208-
service.Inspire = &pdoknlv3.Inspire{
209-
ServiceMetadataURL: pdoknlv3.MetadataURL{
210-
CSW: &pdoknlv3.Metadata{
211-
MetadataIdentifier: src.Spec.Service.MetadataIdentifier,
212-
},
213-
},
214-
SpatialDatasetIdentifier: src.Spec.Service.FeatureTypes[0].SourceMetadataIdentifier,
215-
Language: "dut",
216-
}
217-
}
218-
219-
for _, featureType := range src.Spec.Service.FeatureTypes {
220-
service.FeatureTypes = append(service.FeatureTypes, convertV2FeatureTypeToV3(featureType))
221-
}
222-
223-
target.Spec.Service = service
224-
}

api/v2beta1/wms_conversion.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ func (src *WMS) ConvertTo(dstRaw conversion.Hub) error {
4343
dst := dstRaw.(*pdoknlv3.WMS)
4444
log.Printf("ConvertTo: Converting WMS from Spoke version v2beta1 to Hub version v3;"+
4545
"source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name)
46-
V3WMSHubFromV2(src, dst)
46+
src.ToV3(dst)
4747

4848
return nil
4949
}
5050

51-
func V3WMSHubFromV2(src *WMS, target *pdoknlv3.WMS) {
51+
func (src *WMS) ToV3(target *pdoknlv3.WMS) {
5252
dst := target
5353

5454
dst.ObjectMeta = src.ObjectMeta
@@ -319,15 +319,15 @@ func (v2Service WMSService) MapLayersToV3() pdoknlv3.Layer {
319319
Title: &v2Service.Title,
320320
Abstract: &v2Service.Abstract,
321321
Keywords: v2Service.Keywords,
322-
Layers: &[]pdoknlv3.Layer{},
322+
Layers: []pdoknlv3.Layer{},
323323
BoundingBoxes: boundingBoxes,
324324
Visible: smoothoperatorutils.Pointer(true),
325325
}
326326

327327
// adding the bottom layers to the middle layers they are grouped by
328328
for _, layer := range notGroupedLayers {
329329
bottomLayers := groupedLayers[*layer.Name]
330-
layer.Layers = &bottomLayers
330+
layer.Layers = bottomLayers
331331
middleLayers = append(middleLayers, layer)
332332
}
333333
}
@@ -339,11 +339,11 @@ func (v2Service WMSService) MapLayersToV3() pdoknlv3.Layer {
339339
if topLayer.Name != nil {
340340
for _, layer := range groupedLayers[*topLayer.Name] {
341341
bottomLayers := groupedLayers[*layer.Name]
342-
layer.Layers = &bottomLayers
342+
layer.Layers = bottomLayers
343343
middleLayers = append(middleLayers, layer)
344344
}
345345
}
346-
topLayer.Layers = &middleLayers
346+
topLayer.Layers = middleLayers
347347

348348
return *topLayer
349349
}
@@ -356,7 +356,7 @@ func (v2Layer WMSLayer) MapToV3(v2Service WMSService) pdoknlv3.Layer {
356356
Keywords: v2Layer.Keywords,
357357
LabelNoClip: v2Layer.LabelNoClip,
358358
Styles: []pdoknlv3.Style{},
359-
Layers: &[]pdoknlv3.Layer{},
359+
Layers: []pdoknlv3.Layer{},
360360
BoundingBoxes: []pdoknlv3.WMSBoundingBox{},
361361
MinScaleDenominator: nil,
362362
MaxScaleDenominator: nil,
@@ -429,7 +429,7 @@ func mapV3LayerToV2Layers(v3Layer pdoknlv3.Layer, parent *pdoknlv3.Layer, servic
429429
if parent == nil && v3Layer.Name == nil {
430430
// Default top layer, do not include in v2 layers
431431
if v3Layer.Layers != nil {
432-
for _, childLayer := range *v3Layer.Layers {
432+
for _, childLayer := range v3Layer.Layers {
433433
layers = append(layers, mapV3LayerToV2Layers(childLayer, nil, serviceEPSG)...)
434434
}
435435
}
@@ -503,7 +503,7 @@ func mapV3LayerToV2Layers(v3Layer pdoknlv3.Layer, parent *pdoknlv3.Layer, servic
503503
layers = append(layers, v2Layer)
504504

505505
if v3Layer.Layers != nil {
506-
for _, childLayer := range *v3Layer.Layers {
506+
for _, childLayer := range v3Layer.Layers {
507507
layers = append(layers, mapV3LayerToV2Layers(childLayer, &v3Layer, serviceEPSG)...)
508508
}
509509
}

api/v2beta1/wms_conversion_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ import (
1010
func TestV2ToV3(t *testing.T) {
1111
//nolint:misspell
1212
input := "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"
13-
var v2wms WMS
14-
err := yaml.Unmarshal([]byte(input), &v2wms)
13+
v2wms := &WMS{}
14+
err := yaml.Unmarshal([]byte(input), v2wms)
1515
assert.NoError(t, err)
1616
var target pdoknlv3.WMS
17-
V3WMSHubFromV2(&v2wms, &target)
17+
v2wms.ToV3(&target)
1818
assert.Equal(t, "NWB - Wegen WMS", target.Spec.Service.Title)
1919
a := 0
2020
_ = a

api/v3/wfs_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ type WFSService struct {
120120
// AccessConstraints URL
121121
// +kubebuilder:validation:Pattern:="https?://"
122122
// +kubebuilder:default="https://creativecommons.org/publicdomain/zero/1.0/deed.nl"
123+
123124
// +kubebuilder:validation:MinLength:=1
124125
AccessConstraints string `json:"accessConstraints"`
125126

@@ -244,3 +245,7 @@ func (wfs *WFS) GeoPackages() []*Gpkg {
244245

245246
return gpkgs
246247
}
248+
249+
func (wfs *WFS) GetBaseUrl() string {
250+
return wfs.Spec.Service.URL
251+
}

api/v3/wfs_validation.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func (wfs *WFS) ValidateCreate() ([]string, error) {
1616
reasons = append(reasons, fmt.Sprintf("%v", err))
1717
}
1818

19-
validateWFS(wfs, &warnings, &reasons)
19+
ValidateWFS(wfs, &warnings, &reasons)
2020

2121
if len(reasons) > 0 {
2222
return warnings, fmt.Errorf("%s", strings.Join(reasons, ". "))
@@ -35,16 +35,13 @@ func (wfs *WFS) ValidateUpdate(wfsOld *WFS) ([]string, error) {
3535
reasons = append(reasons, fmt.Sprintf("%v", err))
3636
}
3737

38-
// Check service.baseURL did not change
39-
if wfs.Spec.Service.URL != wfsOld.Spec.Service.URL {
40-
reasons = append(reasons, "service.baseURL is immutable")
41-
}
38+
sharedValidation.CheckBaseUrlImmutability(wfsOld, wfs, &reasons)
4239

4340
if (wfs.Spec.Service.Inspire == nil && wfsOld.Spec.Service.Inspire != nil) || (wfs.Spec.Service.Inspire != nil && wfsOld.Spec.Service.Inspire == nil) {
4441
reasons = append(reasons, "services cannot change from inspire to not inspire or the other way around")
4542
}
4643

47-
validateWFS(wfs, &warnings, &reasons)
44+
ValidateWFS(wfs, &warnings, &reasons)
4845

4946
if len(reasons) > 0 {
5047
return warnings, fmt.Errorf("%s", strings.Join(reasons, ". "))
@@ -53,7 +50,7 @@ func (wfs *WFS) ValidateUpdate(wfsOld *WFS) ([]string, error) {
5350
return warnings, nil
5451
}
5552

56-
func validateWFS(wfs *WFS, warnings *[]string, reasons *[]string) {
53+
func ValidateWFS(wfs *WFS, warnings *[]string, reasons *[]string) {
5754
if strings.Contains(wfs.GetName(), "wfs") {
5855
*warnings = append(*warnings, sharedValidation.FormatValidationWarning("name should not contain wfs", wfs.GroupVersionKind(), wfs.GetName()))
5956
}

0 commit comments

Comments
 (0)