view pkg/models/extservices.go @ 5601:1222b777f51f

Made golint finally happy.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sat, 06 Aug 2022 02:09:57 +0200
parents 5f47eeea988d
children
line wrap: on
line source

// This is Free Software under GNU Affero General Public License v >= 3.0
// without warranty, see README.md and license for details.
//
// SPDX-License-Identifier: AGPL-3.0-or-later
// License-Filename: LICENSES/AGPL-3.0.txt
//
// Copyright (C) 2018 by via donau
//   – Österreichische Wasserstraßen-Gesellschaft mbH
// Software engineering by Intevation GmbH
//
// Author(s):
//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>

package models

import (
	"context"
	"database/sql"
	"sort"
	"sync"

	"gemma.intevation.de/gemma/pkg/auth"
	"gemma.intevation.de/gemma/pkg/log"
)

// ExtEntry is an external WFS service.
type ExtEntry struct {
	Name string `json:"name"`
	URL  string `json:"url"`
	WFS  bool   `json:"wfs"`
}

// ExtServices is a list of the external services.
type ExtServices struct {
	mu      sync.Mutex
	entries []ExtEntry
}

// ExternalServices is the list of external services
// the Gemma server manages as proxies.
var ExternalServices = &ExtServices{}

const selectExternalServices = `SELECT local_name, remote_url, is_wfs
FROM sys_admin.external_services ORDER BY local_name`

// Find looks for a specific configures external service.
func (es *ExtServices) Find(name string) (string, bool) {
	es.mu.Lock()
	defer es.mu.Unlock()

	if es.entries == nil {
		if err := es.load(); err != nil {
			log.Errorf("%v\n", err)
			return "", false
		}
	}
	n := sort.Search(len(es.entries), func(i int) bool {
		return es.entries[i].Name >= name
	})
	if n == len(es.entries) || es.entries[n].Name != name {
		return "", false
	}
	return es.entries[n].URL, true
}

func (es *ExtServices) load() error {
	// make empty slice to prevent retry if slice is empty.
	es.entries = []ExtEntry{}
	return auth.RunAs(context.Background(), "sys_admin",
		func(conn *sql.Conn) error {
			rows, err := conn.QueryContext(
				context.Background(), selectExternalServices)
			if err != nil {
				return err
			}
			defer rows.Close()
			for rows.Next() {
				var entry ExtEntry
				if err := rows.Scan(
					&entry.Name,
					&entry.URL,
					&entry.WFS,
				); err != nil {
					return err
				}
				es.entries = append(es.entries, entry)
			}
			return rows.Err()
		})
}

// Invalidate invalidate the list of external services.
func (es *ExtServices) Invalidate() {
	es.mu.Lock()
	es.entries = nil
	es.mu.Unlock()
}

// ExternalAll passes all external entries as filter.
func ExternalAll(ExtEntry) bool { return true }

// ExternalWMS passes only external entries which are not WFSs.
func ExternalWMS(entry ExtEntry) bool { return !entry.WFS }

// ExternalWFS passes only external enteries which are WFS.
func ExternalWFS(entry ExtEntry) bool { return entry.WFS }

// Filter returns a list of external services which met
// the condition of the given accept filter.
func (es *ExtServices) Filter(accept func(ExtEntry) bool) []ExtEntry {
	es.mu.Lock()
	defer es.mu.Unlock()
	if es.entries == nil {
		if err := es.load(); err != nil {
			log.Errorf("%v\n", err)
			return nil
		}
	}
	ee := make([]ExtEntry, 0, len(es.entries))
	for _, e := range es.entries {
		if accept(e) {
			ee = append(ee, e)
		}
	}
	return ee
}