view pkg/models/extservices.go @ 448:25dd96101aeb

Fixed ordering in external proxied services.
author Sascha L. Teichmann <teichmann@intevation.de>
date Tue, 21 Aug 2018 20:05:45 +0200
parents 659c04feb2dc
children b2dea4e56ff1
line wrap: on
line source

package models

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

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

type ExtEntry struct {
	Name string
	URL  string
	WFS  bool
}

type ExtServices struct {
	mu      sync.Mutex
	entries []ExtEntry
}

var ExternalServices = &ExtServices{}

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

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.Printf("error: %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("sys_admin", func(db *sql.DB) error {
		rows, err := db.Query(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()
	})
}

func (es *ExtServices) Invalidate() {
	es.mu.Lock()
	es.entries = nil
	es.mu.Unlock()
}

func ExternalWMS(entry PubEntry) bool { return !entry.WFS }
func ExternalWFS(entry PubEntry) bool { return entry.WFS }

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.Printf("error: %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
}