Mercurial > gemma
changeset 4935:c64dba002726 fairway-marks-import
Load and prepare data models for layer groups. TODO: Feed config to GeoServer.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Sun, 16 Feb 2020 15:16:22 +0100 |
parents | c6af373b0832 |
children | 21a48e2d2260 |
files | pkg/auth/opendb.go pkg/controllers/publish.go pkg/geoserver/boot.go pkg/models/intservices.go |
diffstat | 4 files changed, 145 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/pkg/auth/opendb.go Sat Feb 15 21:29:38 2020 +0100 +++ b/pkg/auth/opendb.go Sun Feb 16 15:16:22 2020 +0100 @@ -145,6 +145,24 @@ return fn(conn) } +// RunAllAs runs the given functions fns with a database connection impersonated +// as the given role. +// To make this work a metamorphic user has to be configured in +// the system configuration. +func RunAllAs(ctx context.Context, role string, fns ...func(*sql.Conn) error) error { + conn, err := metamorphConn(ctx, role) + if err != nil { + return err + } + defer conn.Close() + for _, fn := range fns { + if err := fn(conn); err != nil { + return err + } + } + return nil +} + // RunAsSessionUser is a convinience wrapper araound which extracts // the logged in user from a session and calls RunAs with it. func RunAsSessionUser(req *http.Request, fn func(*sql.Conn) error) error {
--- a/pkg/controllers/publish.go Sat Feb 15 21:29:38 2020 +0100 +++ b/pkg/controllers/publish.go Sun Feb 16 15:16:22 2020 +0100 @@ -24,11 +24,13 @@ func published(req *http.Request) (mw.JSONResult, error) { return mw.JSONResult{ Result: struct { - Internal []models.IntEntry `json:"internal"` - External []models.ExtEntry `json:"external"` + Internal []models.IntEntry `json:"internal"` + LayerGroups []models.LayerGroup `json:"layer-groups"` + External []models.ExtEntry `json:"external"` }{ - Internal: models.InternalServices.Filter(models.InternalAll), - External: models.ExternalServices.Filter(models.ExternalAll), + Internal: models.InternalServices.Filter(models.InternalAll), + LayerGroups: models.InternalServices.LayerGroups(), + External: models.ExternalServices.Filter(models.ExternalAll), }, }, nil }
--- a/pkg/geoserver/boot.go Sat Feb 15 21:29:38 2020 +0100 +++ b/pkg/geoserver/boot.go Sun Feb 16 15:16:22 2020 +0100 @@ -385,6 +385,29 @@ return nil } +func ensureLayerGroups() error { + + groups := models.InternalServices.LayerGroups() + if len(groups) == 0 { + log.Println("info: no groups layers to publish") + return nil + } + + log.Printf("info: number of layer groups to publish %d\n", len(groups)) + // TODO: Implement me! + + /* + for i := range groups { + log.Printf("info: layer group #%d: %s\n", i+1, groups[i].Name) + for _, layer := range groups[i].Layers { + log.Printf("info: layer: %s\n", layer) + } + } + */ + + return nil +} + func deleteWorkspace() error { // Should we delete our workspace first? @@ -689,6 +712,7 @@ ensureWorkspace, ensureDataStore, ensureFeatures, + ensureLayerGroups, ensureStyles, } { if err := ensure(); err != nil {
--- a/pkg/models/intservices.go Sat Feb 15 21:29:38 2020 +0100 +++ b/pkg/models/intservices.go Sun Feb 16 15:16:22 2020 +0100 @@ -27,21 +27,29 @@ const DatabaseScheme = "waterway" -type IntEntry struct { - Schema string `json:"schema"` - Name string `json:"name"` - SQL *string `json:"sql"` - KeyColumn *string `json:"keycolumn"` - SRS *string `json:"srs"` - Style bool `json:"style"` - WMS bool `json:"wms"` - WFS bool `json:"wfs"` -} +type ( + IntEntry struct { + Schema string `json:"schema"` + Name string `json:"name"` + SQL *string `json:"sql"` + KeyColumn *string `json:"keycolumn"` + SRS *string `json:"srs"` + Style bool `json:"style"` + WMS bool `json:"wms"` + WFS bool `json:"wfs"` + } -type IntServices struct { - entries []IntEntry - mu sync.Mutex -} + LayerGroup struct { + Name string `json:"name"` + Layers []string `json:"layers"` + } + + IntServices struct { + mu sync.Mutex + entries []IntEntry + layerGroups []LayerGroup + } +) const ( selectServicesSQL = ` @@ -53,6 +61,11 @@ WHERE schema = $1 ORDER by name` + selectGroupedLayersSQL = ` +SELECT group_name, name +FROM sys_admin.grouped_layers +ORDER BY group_name, ord` + selectStyleSQL = ` SELECT style FROM sys_admin.published_services @@ -91,6 +104,28 @@ }) } +func (ps *IntServices) LayerGroups() []LayerGroup { + ps.mu.Lock() + defer ps.mu.Unlock() + + if ps.entries == nil { + if err := ps.load(); err != nil { + log.Printf("error: %v\n", err) + return nil + } + } + + // To avoid races we simple make a deep copy. + // As we don't have such many of them it light weight enough for now. + groups := make([]LayerGroup, len(ps.layerGroups)) + for i := range groups { + layers := make([]string, len(ps.layerGroups[i].Layers)) + copy(layers, ps.layerGroups[i].Layers) + groups[i] = LayerGroup{Name: ps.layerGroups[i].Name, Layers: layers} + } + return groups +} + func (ps *IntServices) Find(name string) (string, bool) { ps.mu.Lock() defer ps.mu.Unlock() @@ -129,33 +164,63 @@ func (ps *IntServices) load() error { // make empty slice to prevent retry if slice is empty. ps.entries = []IntEntry{} + ps.layerGroups = []LayerGroup{} ctx := context.Background() - return auth.RunAs(ctx, "sys_admin", - func(conn *sql.Conn) error { - rows, err := conn.QueryContext( - ctx, selectServicesSQL, DatabaseScheme) - if err != nil { + + // Load the internal layers. + entries := func(conn *sql.Conn) error { + rows, err := conn.QueryContext( + ctx, selectServicesSQL, DatabaseScheme) + if err != nil { + return err + } + defer rows.Close() + for rows.Next() { + var entry IntEntry + if err := rows.Scan( + &entry.Schema, &entry.Name, + &entry.SQL, &entry.KeyColumn, &entry.SRS, &entry.Style, + &entry.WMS, &entry.WFS, + ); err != nil { return err } - defer rows.Close() - for rows.Next() { - var entry IntEntry - if err := rows.Scan( - &entry.Schema, &entry.Name, - &entry.SQL, &entry.KeyColumn, &entry.SRS, &entry.Style, - &entry.WMS, &entry.WFS, - ); err != nil { - return err - } - ps.entries = append(ps.entries, entry) + ps.entries = append(ps.entries, entry) + } + return rows.Err() + } + + // Load the layer groups. + groups := func(conn *sql.Conn) error { + rows, err := conn.QueryContext(ctx, selectGroupedLayersSQL) + if err != nil { + return err + } + defer rows.Close() + + for rows.Next() { + var group, layer string + if err := rows.Scan(&group, &layer); err != nil { + return err } - return rows.Err() - }) + if n := len(ps.layerGroups); n > 0 && ps.layerGroups[n-1].Name == group { + ps.layerGroups[n-1].Layers = append(ps.layerGroups[n-1].Layers, layer) + } else { + ps.layerGroups = append(ps.layerGroups, LayerGroup{ + Name: group, + Layers: []string{layer}, + }) + } + } + return rows.Err() + } + + return auth.RunAllAs(ctx, "sys_admin", entries, groups) } func (ps *IntServices) Invalidate() { ps.mu.Lock() ps.entries = nil + ps.layerGroups = nil ps.mu.Unlock() }