Skip to content

Commit 23bf4a5

Browse files
authored
Merge pull request #85 from PDOK/wr/layer-validation
wms validation done
2 parents 53830b6 + 075855d commit 23bf4a5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1260
-837
lines changed

api/v2beta1/wfs_conversion.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func convertV2FeatureTypeToV3(src FeatureType) pdoknlv3.FeatureType {
177177
MetadataIdentifier: src.DatasetMetadataIdentifier,
178178
},
179179
},
180-
Data: pdoknlv3.Data{},
180+
Data: pdoknlv3.BaseData{},
181181
}
182182

183183
if src.Extent != nil {
@@ -186,7 +186,7 @@ func convertV2FeatureTypeToV3(src FeatureType) pdoknlv3.FeatureType {
186186
}
187187
}
188188

189-
featureTypeV3.Data = ConvertV2DataToV3(src.Data)
189+
featureTypeV3.Data = ConvertV2DataToV3(src.Data).BaseData
190190

191191
return featureTypeV3
192192
}
@@ -260,7 +260,7 @@ func (dst *WFS) ConvertFrom(srcRaw conversion.Hub) error {
260260
Keywords: featureType.Keywords,
261261
DatasetMetadataIdentifier: featureType.DatasetMetadataURL.CSW.MetadataIdentifier,
262262
SourceMetadataIdentifier: "",
263-
Data: ConvertV3DataToV2(featureType.Data),
263+
Data: ConvertV3DataToV2(pdoknlv3.Data{BaseData: featureType.Data}),
264264
}
265265

266266
if src.Spec.Service.Inspire != nil {

api/v3/shared_types.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,19 @@ type Custom struct {
182182
Type string `json:"type"`
183183
}
184184

185-
// Data holds the data source configuration
186-
// +kubebuilder:validation:XValidation:rule="has(self.gpkg) || has(self.tif) || has(self.postgis)", message="Atleast one of the datasource should be provided (postgis, gpkg, tif)"
187-
type Data struct {
185+
// BaseData holds the data source configuration for gpkg and postgis
186+
type BaseData struct {
188187
// Gpkg configures a GeoPackage file source
189188
Gpkg *Gpkg `json:"gpkg,omitempty"`
190189

191190
// Postgis configures a Postgis table source
192191
Postgis *Postgis `json:"postgis,omitempty"`
192+
}
193+
194+
// Data holds the data source configuration
195+
// +kubebuilder:validation:XValidation:rule="has(self.gpkg) || has(self.tif) || has(self.postgis)", message="Atleast one of the datasource should be provided (postgis, gpkg, tif)"
196+
type Data struct {
197+
BaseData `json:",inline"`
193198

194199
// TIF configures a GeoTIF raster source
195200
TIF *TIF `json:"tif,omitempty"`
@@ -276,7 +281,7 @@ func GetHost(includeProtocol bool) string {
276281
return host
277282
}
278283

279-
func (d *Data) GetColumns() *[]Column {
284+
func (d *BaseData) GetColumns() *[]Column {
280285
switch {
281286
case d.Gpkg != nil:
282287
return &d.Gpkg.Columns
@@ -287,7 +292,7 @@ func (d *Data) GetColumns() *[]Column {
287292
}
288293
}
289294

290-
func (d *Data) GetTableName() *string {
295+
func (d *BaseData) GetTableName() *string {
291296
switch {
292297
case d.Gpkg != nil:
293298
return &d.Gpkg.TableName
@@ -298,7 +303,7 @@ func (d *Data) GetTableName() *string {
298303
}
299304
}
300305

301-
func (d *Data) GetGeometryType() *string {
306+
func (d *BaseData) GetGeometryType() *string {
302307
switch {
303308
case d.Gpkg != nil:
304309
return &d.Gpkg.GeometryType

api/v3/shared_validation.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func ValidateUpdate[W WMSWFS](c client.Client, newW, oldW W, validate func(W, *[
4646
allErrs := field.ErrorList{}
4747

4848
// Make sure no ingressRouteURLs have been removed
49-
sharedValidation.ValidateIngressRouteURLsNotRemoved(oldW.IngressRouteURLs(true), newW.IngressRouteURLs(true), &allErrs, nil)
49+
sharedValidation.ValidateIngressRouteURLsNotRemoved(oldW.IngressRouteURLs(false), newW.IngressRouteURLs(true), &allErrs, nil)
5050

5151
if len(newW.IngressRouteURLs(false)) == 0 {
5252
// There are no ingressRouteURLs given, spec.service.url is immutable is that case.

api/v3/wfs_types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,8 @@ type FeatureType struct {
187187

188188
// FeatureType data connection
189189
// +kubebuilder:validation:Type=object
190-
Data Data `json:"data"`
190+
// +kubebuilder:validation:XValidation:rule="has(self.gpkg) || has(self.postgis)", message="At least one of the datasource should be provided (postgis, gpkg)"
191+
Data BaseData `json:"data"`
191192
}
192193

193194
// FeatureBbox is the optional featureType bounding box, if provided it overrides the default extent

api/v3/wfs_validation.go

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,20 @@ func ValidateWFS(wfs *WFS, warnings *[]string, allErrs *field.ErrorList) {
3434
path := field.NewPath("spec").Child("service")
3535

3636
if service.Mapfile == nil && service.DefaultCrs != "EPSG:28992" && service.Bbox == nil {
37-
*allErrs = append(*allErrs, field.Required(path.Child("bbox").Child("defaultCRS"), "when service.defaultCRS is not 'EPSG:28992'"))
37+
*allErrs = append(*allErrs, field.Required(
38+
path.Child("bbox").Child("defaultCRS"),
39+
"when service.defaultCRS is not 'EPSG:28992'",
40+
))
3841
}
3942

4043
if service.Mapfile != nil && service.Bbox != nil {
41-
sharedValidation.AddWarning(warnings, *path.Child("bbox"), "is not used when service.mapfile is configured", wfs.GroupVersionKind(), wfs.GetName())
44+
sharedValidation.AddWarning(
45+
warnings,
46+
*path.Child("bbox"),
47+
"is not used when service.mapfile is configured",
48+
wfs.GroupVersionKind(),
49+
wfs.GetName(),
50+
)
4251
}
4352

4453
ValidateInspire(wfs, allErrs)
@@ -76,37 +85,5 @@ func ValidateFeatureTypes(wfs *WFS, warnings *[]string, allErrs *field.ErrorList
7685
)
7786
}
7887

79-
if tif := featureType.Data.TIF; tif != nil {
80-
if tif.Resample != "NEAREST" {
81-
sharedValidation.AddWarning(
82-
warnings,
83-
*path.Index(index).Child("data").Child("tif").Child("resample"),
84-
"is not used when service.mapfile is configured",
85-
wfs.GroupVersionKind(),
86-
wfs.GetName(),
87-
)
88-
}
89-
90-
if tif.Offsite != nil {
91-
sharedValidation.AddWarning(
92-
warnings,
93-
*path.Index(index).Child("data").Child("tif").Child("offsite"),
94-
"is not used when service.mapfile is configured",
95-
wfs.GroupVersionKind(),
96-
wfs.GetName(),
97-
)
98-
}
99-
100-
if tif.GetFeatureInfoIncludesClass {
101-
sharedValidation.AddWarning(
102-
warnings,
103-
*path.Index(index).Child("data").Child("tif").Child("getFeatureInfoIncludesClass"),
104-
"is not used when service.mapfile is configured",
105-
wfs.GroupVersionKind(),
106-
wfs.GetName(),
107-
)
108-
}
109-
}
110-
11188
}
11289
}

api/v3/wms_types.go

Lines changed: 37 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ type WMSSpec struct {
108108
Service WMSService `json:"service"`
109109
}
110110

111+
// +kubebuilder:validation:XValidation:message="service requires styling, either through service.mapfile, or stylingAssets.configMapRefs",rule=has(self.mapfile) || (has(self.stylingAssets) && has(self.stylingAssets.configMapRefs))
112+
// +kubebuilder:validation:XValidation:message="when using service.mapfile, don't include stylingAssets.configMapRefs",rule=!has(self.mapfile) || (!has(self.stylingAssets) || !has(self.stylingAssets.configMapRefs))
111113
type WMSService struct {
112114
BaseService `json:",inline"`
113115

@@ -187,9 +189,9 @@ type ConfigMapRef struct {
187189

188190
// +kubebuilder:validation:XValidation:message="A layer should have exactly one of sublayers or data", rule="(has(self.data) || has(self.layers)) && !(has(self.data) && has(self.layers))"
189191
// +kubebuilder:validation:XValidation:message="A layer with data attribute should have styling", rule="!has(self.data) || has(self.styles)"
190-
// +kubebuilder:validation:XValidation:message="A layer should have keywords when visible", rule="!self.visible || has(self.keywords)"
191192
// +kubebuilder:validation:XValidation:message="A layer should have a title when visible", rule="!self.visible || has(self.title)"
192193
// +kubebuilder:validation:XValidation:message="A layer should have an abstract when visible", rule="!self.visible || has(self.abstract)"
194+
// +kubebuilder:validation:XValidation:message="A layer should have keywords when visible", rule="!self.visible || has(self.keywords)"
193195
type Layer struct {
194196
// Name of the layer, required for layers on the 2nd or 3rd level
195197
// +kubebuilder:validation:MinLength:=1
@@ -326,7 +328,7 @@ type WMSOptions struct {
326328
func (wmsService *WMSService) GetBoundingBox() WMSBoundingBox {
327329
var boundingBox *WMSBoundingBox
328330

329-
allLayers := wmsService.GetAllLayers()
331+
allLayers := wmsService.GetAnnotatedLayers()
330332
for _, layer := range allLayers {
331333
if len(layer.BoundingBoxes) > 0 {
332334
for _, bbox := range wmsService.Layer.BoundingBoxes {
@@ -354,6 +356,16 @@ func (wmsService *WMSService) GetBoundingBox() WMSBoundingBox {
354356
}
355357
}
356358

359+
func (stylingAssets *StylingAssets) GetAllConfigMapRefKeys() []string {
360+
keys := []string{}
361+
if stylingAssets != nil {
362+
for _, cmRef := range stylingAssets.ConfigMapRefs {
363+
keys = append(keys, cmRef.Keys...)
364+
}
365+
}
366+
return keys
367+
}
368+
357369
type AnnotatedLayer struct {
358370
// The name of the group that this layer belongs to, nil if it is not a member of a group. Groups can be a member of the toplayer as a group
359371
GroupName *string
@@ -363,62 +375,43 @@ type AnnotatedLayer struct {
363375
IsGroupLayer bool
364376
// Contains actual data
365377
IsDataLayer bool
366-
Layer Layer
378+
Layer
367379
}
368380

369381
func (wmsService *WMSService) GetAnnotatedLayers() []AnnotatedLayer {
370382
result := make([]AnnotatedLayer, 0)
371383

372-
if wmsService.Layer.Name != nil && len(*wmsService.Layer.Name) > 0 {
373-
firstLayer := AnnotatedLayer{
374-
GroupName: nil,
375-
IsTopLayer: wmsService.Layer.IsTopLayer(),
376-
IsGroupLayer: wmsService.Layer.IsGroupLayer(),
377-
IsDataLayer: wmsService.Layer.IsDataLayer(),
378-
Layer: wmsService.Layer,
379-
}
380-
result = append(result, firstLayer)
381-
}
384+
result = append(result, AnnotatedLayer{
385+
GroupName: nil,
386+
IsTopLayer: true,
387+
IsGroupLayer: true,
388+
IsDataLayer: false,
389+
Layer: wmsService.Layer,
390+
})
382391

383-
for _, subLayer := range wmsService.Layer.Layers {
384-
groupName := wmsService.Layer.Name
385-
isGroupLayer := subLayer.IsGroupLayer()
386-
isDataLayer := !isGroupLayer
392+
for _, middleLayer := range wmsService.Layer.Layers {
387393
result = append(result, AnnotatedLayer{
388-
GroupName: groupName,
394+
GroupName: wmsService.Layer.Name,
389395
IsTopLayer: false,
390-
IsGroupLayer: isGroupLayer,
391-
IsDataLayer: isDataLayer,
392-
Layer: subLayer,
396+
IsGroupLayer: middleLayer.IsGroupLayer(),
397+
IsDataLayer: middleLayer.IsDataLayer(),
398+
Layer: middleLayer,
393399
})
394400

395-
for _, subSubLayer := range subLayer.Layers {
401+
for _, bottomLayer := range middleLayer.Layers {
396402
result = append(result, AnnotatedLayer{
397-
GroupName: subLayer.Name,
403+
GroupName: middleLayer.Name,
398404
IsTopLayer: false,
399405
IsGroupLayer: false,
400406
IsDataLayer: true,
401-
Layer: subSubLayer,
407+
Layer: bottomLayer,
402408
})
403409
}
404410
}
405411

406412
return result
407413
}
408414

409-
func (wmsService *WMSService) GetAllLayers() (layers []Layer) {
410-
return wmsService.Layer.FlattenLayers()
411-
}
412-
413-
// FlattenLayers - flattens the layer and its sublayers into one array
414-
func (layer *Layer) FlattenLayers() []Layer {
415-
layers := []Layer{*layer}
416-
for _, childLayer := range layer.Layers {
417-
layers = append(layers, childLayer.FlattenLayers()...)
418-
}
419-
return layers
420-
}
421-
422415
// GetAllSublayers - get all sublayers of a layer, the result does not include the layer itself
423416
func (layer *Layer) GetAllSublayers() []Layer {
424417
layers := layer.Layers
@@ -469,17 +462,6 @@ func (layer *Layer) hasTIFData() bool {
469462
return layer.Data.TIF != nil && layer.Data.TIF.BlobKey != ""
470463
}
471464

472-
func (layer *Layer) GetLayerType(service *WMSService) (layerType string) {
473-
switch {
474-
case layer.IsDataLayer():
475-
return DataLayer
476-
case layer.Name == service.Layer.Name:
477-
return TopLayer
478-
default:
479-
return GroupLayer
480-
}
481-
}
482-
483465
func (layer *Layer) IsDataLayer() bool {
484466
return layer.hasData() && len(layer.Layers) == 0
485467
}
@@ -530,8 +512,8 @@ func (layer *Layer) setInheritedBoundingBoxes() {
530512
layer.Layers = updatedLayers
531513
}
532514

533-
func (wms *WMS) GetAllLayersWithLegend() (layers []Layer) {
534-
for _, layer := range wms.Spec.Service.GetAllLayers() {
515+
func (wms *WMS) GetAllLayersWithLegend() (layers []AnnotatedLayer) {
516+
for _, layer := range wms.Spec.Service.GetAnnotatedLayers() {
535517
if !layer.hasData() || len(layer.Styles) == 0 {
536518
continue
537519
}
@@ -547,7 +529,7 @@ func (wms *WMS) GetAllLayersWithLegend() (layers []Layer) {
547529

548530
func (wms *WMS) GetUniqueTiffBlobKeys() []string {
549531
blobKeys := map[string]bool{}
550-
for _, layer := range wms.Spec.Service.GetAllLayers() {
532+
for _, layer := range wms.Spec.Service.GetAnnotatedLayers() {
551533
if layer.hasTIFData() {
552534
blobKeys[layer.Data.TIF.BlobKey] = true
553535
}
@@ -578,7 +560,7 @@ func (wms *WMS) GetAuthority() *Authority {
578560
}
579561

580562
func (wms *WMS) HasPostgisData() bool {
581-
for _, layer := range wms.Spec.Service.GetAllLayers() {
563+
for _, layer := range wms.Spec.Service.GetAnnotatedLayers() {
582564
if layer.Data != nil && layer.Data.Postgis != nil {
583565
return true
584566
}
@@ -639,7 +621,7 @@ func (wms *WMS) URL() smoothoperatormodel.URL {
639621
func (wms *WMS) DatasetMetadataIDs() []string {
640622
ids := []string{}
641623

642-
for _, layer := range wms.Spec.Service.GetAllLayers() {
624+
for _, layer := range wms.Spec.Service.GetAnnotatedLayers() {
643625
if layer.DatasetMetadataURL != nil && layer.DatasetMetadataURL.CSW != nil {
644626
if id := layer.DatasetMetadataURL.CSW.MetadataIdentifier; !slices.Contains(ids, id) {
645627
ids = append(ids, id)
@@ -684,8 +666,8 @@ func (wms *WMS) ReadinessQueryString() (string, string, error) {
684666
}
685667

686668
firstDataLayerName := ""
687-
for _, layer := range wms.Spec.Service.GetAllLayers() {
688-
if layer.IsDataLayer() {
669+
for _, layer := range wms.Spec.Service.GetAnnotatedLayers() {
670+
if layer.IsDataLayer {
689671
firstDataLayerName = *layer.Name
690672
break
691673
}

0 commit comments

Comments
 (0)