changeset 2036:74e24ae3205a unify_imports

Imports: Added a persistent model for the extra attributes.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 25 Jan 2019 11:52:54 +0100
parents 2f6cadcb3558
children 11cb57f85c60
files pkg/common/attributes.go pkg/controllers/manualimports.go pkg/models/importbase.go pkg/models/imports.go
diffstat 4 files changed, 213 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/common/attributes.go	Fri Jan 25 11:26:20 2019 +0100
+++ b/pkg/common/attributes.go	Fri Jan 25 11:52:54 2019 +0100
@@ -20,9 +20,31 @@
 	"time"
 )
 
-// Attributes is a map of optional key/value attributes
-// of a configuration.
-type Attributes map[string]string
+type (
+
+	// Attributes is a map of optional key/value attributes
+	// of a configuration.
+	Attributes map[string]string
+
+	AttributesMarshaler interface {
+		MarshalAttributes(Attributes) error
+	}
+
+	AttributesUnmarshaler interface {
+		UnmarshalAttributes(Attributes) error
+	}
+)
+
+func (ca Attributes) Delete(key string) bool {
+	if ca == nil {
+		return false
+	}
+	if _, found := ca[key]; !found {
+		return false
+	}
+	delete(ca, key)
+	return true
+}
 
 // Get fetches a value for given key out of the configuration.
 // If the key was not found the bool component of the return value
@@ -35,19 +57,39 @@
 	return value, found
 }
 
+func (ca Attributes) Set(key, value string) bool {
+	if ca == nil {
+		return false
+	}
+	ca[key] = value
+	return true
+}
+
 // Bool returns a bool value for a given key.
 func (ca Attributes) Bool(key string) bool {
 	s, found := ca.Get(key)
 	return found && strings.ToLower(s) == "true"
 }
 
+func (ca Attributes) SetBool(key string, value bool) bool {
+	var v string
+	if value {
+		v = "true"
+	} else {
+		v = "false"
+	}
+	return ca.Set(key, v)
+}
+
+const TimeFormat = "2006-01-02T15:04:05"
+
 // Time gives a time.Time for a given key.
 func (ca Attributes) Time(key string) (time.Time, bool) {
 	s, found := ca.Get(key)
 	if !found {
 		return time.Time{}, false
 	}
-	t, err := time.Parse("2006-01-02T15:04:05", s)
+	t, err := time.Parse(TimeFormat, s)
 	if err != nil {
 		log.Printf("error: %v\n", err)
 		return time.Time{}, false
@@ -55,6 +97,12 @@
 	return t, true
 }
 
+func (ca Attributes) SetTime(key string, t time.Time) bool {
+	value := t.Format(TimeFormat)
+	return ca.Set(key, value)
+
+}
+
 func (ca Attributes) Int(key string) (int, bool) {
 	s, found := ca.Get(key)
 	if !found {
@@ -68,6 +116,11 @@
 	return i, true
 }
 
+func (ca Attributes) SetInt(key string, value int) bool {
+	v := strconv.Itoa(value)
+	return ca.Set(key, v)
+}
+
 func (ca Attributes) Duration(key string) (time.Duration, bool) {
 	s, found := ca.Get(key)
 	if !found {
@@ -80,3 +133,8 @@
 	}
 	return d, true
 }
+
+func (ca Attributes) SetDuration(key string, value time.Duration) bool {
+	v := value.String()
+	return ca.Set(key, v)
+}
--- a/pkg/controllers/manualimports.go	Fri Jan 25 11:26:20 2019 +0100
+++ b/pkg/controllers/manualimports.go	Fri Jan 25 11:52:54 2019 +0100
@@ -55,7 +55,7 @@
 	return &imports.WaterwayAxis{
 		URL:         wxi.URL,
 		FeatureType: wxi.FeatureType,
-		SortBy:      wxi.SortBy,
+		SortBy:      nilString(wxi.SortBy),
 	}
 }
 
@@ -64,7 +64,7 @@
 	return &imports.WaterwayArea{
 		URL:         wai.URL,
 		FeatureType: wai.FeatureType,
-		SortBy:      wai.SortBy,
+		SortBy:      nilString(wai.SortBy),
 	}
 }
 
@@ -92,7 +92,7 @@
 	return &imports.FairwayDimension{
 		URL:                fdi.URL,
 		FeatureType:        fdi.FeatureType,
-		SortBy:             fdi.SortBy,
+		SortBy:             nilString(fdi.SortBy),
 		LOS:                fdi.LOS,
 		MinWidth:           fdi.MinWidth,
 		MaxWidth:           fdi.MaxWidth,
@@ -106,7 +106,7 @@
 	return &imports.DistanceMarksAshore{
 		URL:         dmai.URL,
 		FeatureType: dmai.FeatureType,
-		SortBy:      dmai.SortBy,
+		SortBy:      nilString(dmai.SortBy),
 	}
 }
 
--- a/pkg/models/importbase.go	Fri Jan 25 11:26:20 2019 +0100
+++ b/pkg/models/importbase.go	Fri Jan 25 11:52:54 2019 +0100
@@ -15,8 +15,10 @@
 
 import (
 	"encoding/json"
+	"errors"
 	"time"
 
+	"gemma.intevation.de/gemma/pkg/common"
 	"github.com/robfig/cron"
 )
 
@@ -80,3 +82,32 @@
 	*cs = CronSpec(spec)
 	return nil
 }
+
+func (ut *URLType) MarshalAttributes(attrs common.Attributes) error {
+	attrs.Set("url", ut.URL)
+	if ut.Insecure {
+		attrs.SetBool("insecure", ut.Insecure)
+	}
+	if ut.User != nil {
+		attrs.Set("user", *ut.User)
+	}
+	if ut.Password != nil {
+		attrs.Set("password", *ut.Password)
+	}
+	return nil
+}
+
+func (ut *URLType) UnmarshalAttributes(attrs common.Attributes) error {
+	url, found := attrs.Get("url")
+	if !found {
+		return errors.New("missing 'url' attribute")
+	}
+	ut.URL = url
+	if user, found := attrs.Get("user"); found {
+		ut.User = &user
+	}
+	if password, found := attrs.Get("password"); found {
+		ut.Password = &password
+	}
+	return nil
+}
--- a/pkg/models/imports.go	Fri Jan 25 11:26:20 2019 +0100
+++ b/pkg/models/imports.go	Fri Jan 25 11:52:54 2019 +0100
@@ -12,67 +12,70 @@
 //  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
 package models
 
+import (
+	"errors"
+
+	"gemma.intevation.de/gemma/pkg/common"
+)
+
 type (
-	BottleneckImport struct {
+	ConfigurableURLImport struct {
 		URLType
 		QueueConfigurationType
 	}
 
+	BottleneckImport struct {
+		ConfigurableURLImport
+	}
+
 	// GaugeMeasurementImport contains data used to define the endpoint
 	GaugeMeasurementImport struct {
-		URLType
-		QueueConfigurationType
+		ConfigurableURLImport
 	}
 
 	// FairwayAvailabilityImport contains data used to define the endpoint
 	FairwayAvailabilityImport struct {
-		URLType
-		QueueConfigurationType
+		ConfigurableURLImport
+	}
+
+	// WaterwayAxisImport specifies an import of waterway gauges.
+	WaterwayGaugeImport struct {
+		ConfigurableURLImport
+	}
+
+	// DistanceMarksVirtualImport specifies an import of distance marks virtual.
+	DistanceMarksVirtualImport struct {
+		ConfigurableURLImport
+	}
+
+	WFSImport struct {
+		ConfigurableURLImport
+
+		// FeatureType is the layer to use.
+		FeatureType string `json:"feature-type"`
+		// SortBy sorts the feature by this key.
+		SortBy *string `json:"sort-by"`
 	}
 
 	// WaterwayAxisImport specifies an import of the waterway axis.
 	WaterwayAxisImport struct {
-		URLType
-		QueueConfigurationType
-
-		// FeatureType is the layer to use.
-		FeatureType string `json:"feature-type"`
-		// SortBy sorts the feature by this key.
-		SortBy string `json:"sort-by"`
+		WFSImport
 	}
 
 	// WaterwayAreaImport specifies an import of the waterway area.
 	WaterwayAreaImport struct {
-		URLType
-		QueueConfigurationType
-
-		// FeatureType is the layer to use.
-		FeatureType string `json:"feature-type"`
-		// SortBy sorts the feature by this key.
-		SortBy string `json:"sort-by"`
+		WFSImport
 	}
 
-	// WaterwayAxisImport specifies an import of waterway gauges.
-	WaterwayGaugeImport struct {
-		URLType
-		QueueConfigurationType
-	}
-
-	// DistanceMarksVirtualImport specifies an import of distance marks virtual.
-	DistanceMarksVirtualImport struct {
-		URLType
-		QueueConfigurationType
+	// DistanceMarksAshoreImport specifies an import of the distance marks.
+	DistanceMarksAshoreImport struct {
+		WFSImport
 	}
 
 	// FairwayDimensionImport specifies an import of the waterway axis.
 	FairwayDimensionImport struct {
-		URLType
-		QueueConfigurationType
+		WFSImport
 
-		// FeatureType is the layer to use.
-		FeatureType string `json:"feature-type"`
-		// SortBy sorts the feature by this key.
-		SortBy string `json:"sort-by"`
 		// LOS is the level of service provided by the wfs
 		LOS int `json:"los"`
 		// MinWidth is the minimum width of the fairway for the specified LOS
@@ -85,17 +88,6 @@
 		SourceOrganization string `json:"source-organization"`
 	}
 
-	// DistanceMarksAshoreImport specifies an import of the distance marks.
-	DistanceMarksAshoreImport struct {
-		URLType
-		QueueConfigurationType
-
-		// FeatureType is the layer to use.
-		FeatureType string `json:"feature-type"`
-		// SortBy sorts the feature by this key.
-		SortBy string `json:"sort-by"`
-	}
-
 	StretchImport struct {
 		EmailType
 
@@ -109,3 +101,81 @@
 		Countries UniqueCountries `json:"countries"`
 	}
 )
+
+func (cui *ConfigurableURLImport) MarshalAttributes(attrs common.Attributes) error {
+	return cui.URLType.MarshalAttributes(attrs)
+}
+
+func (cui *ConfigurableURLImport) UnmarshalAttributes(attrs common.Attributes) error {
+	return cui.URLType.UnmarshalAttributes(attrs)
+}
+
+func (wi *WFSImport) MarshalAttributes(attrs common.Attributes) error {
+	if err := wi.ConfigurableURLImport.MarshalAttributes(attrs); err != nil {
+		return err
+	}
+	attrs.Set("feature-type", wi.FeatureType)
+	if wi.SortBy != nil {
+		attrs.Set("sort-by", *wi.SortBy)
+	}
+	return nil
+}
+
+func (wi *WFSImport) UnmarshalAttributes(attrs common.Attributes) error {
+	if err := wi.URLType.UnmarshalAttributes(attrs); err != nil {
+		return err
+	}
+	ft, found := attrs.Get("feature-type")
+	if !found {
+		return errors.New("missing 'feature-type' attribute")
+	}
+	wi.FeatureType = ft
+	if sb, found := attrs.Get("sort-by"); found {
+		wi.SortBy = &sb
+	}
+	return nil
+}
+
+func (fdi *FairwayDimensionImport) MarshalAttributes(attrs common.Attributes) error {
+	if err := fdi.WFSImport.MarshalAttributes(attrs); err != nil {
+		return err
+	}
+	attrs.SetInt("los", fdi.LOS)
+	attrs.SetInt("min-width", fdi.MinWidth)
+	attrs.SetInt("max-width", fdi.MaxWidth)
+	attrs.SetInt("depth", fdi.Depth)
+	attrs.Set("source-organization", fdi.SourceOrganization)
+	return nil
+}
+
+func (fdi *FairwayDimensionImport) UnmarshalAttributes(attrs common.Attributes) error {
+	if err := fdi.WFSImport.UnmarshalAttributes(attrs); err != nil {
+		return err
+	}
+	los, found := attrs.Int("los")
+	if !found {
+		return errors.New("missing 'los' attribute")
+	}
+	fdi.LOS = los
+	minWidth, found := attrs.Int("min-width")
+	if !found {
+		return errors.New("missing 'min-width' attribute")
+	}
+	fdi.MinWidth = minWidth
+	maxWidth, found := attrs.Int("max-width")
+	if !found {
+		return errors.New("missing 'max-width' attribute")
+	}
+	fdi.MaxWidth = maxWidth
+	depth, found := attrs.Int("depth")
+	if !found {
+		return errors.New("missing 'depth' attribute")
+	}
+	fdi.Depth = depth
+	source, found := attrs.Get("source-organization")
+	if !found {
+		return errors.New("missing 'source-organization' attribute")
+	}
+	fdi.SourceOrganization = source
+	return nil
+}