177 lines
4.3 KiB
Go
177 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Config struct {
|
|
IncludeBNodes bool
|
|
|
|
CorsOrigins string
|
|
|
|
DefaultNodeLimit int
|
|
DefaultEdgeLimit int
|
|
MaxNodeLimit int
|
|
MaxEdgeLimit int
|
|
|
|
SparqlHost string
|
|
SparqlEndpoint string
|
|
SparqlUser string
|
|
SparqlPass string
|
|
SparqlInsecureTLS bool
|
|
SparqlDataFile string
|
|
SparqlGraphIRI string
|
|
SparqlLoadOnStart bool
|
|
SparqlClearOnStart bool
|
|
|
|
SparqlTimeout time.Duration
|
|
SparqlReadyRetries int
|
|
SparqlReadyDelay time.Duration
|
|
SparqlReadyTimeout time.Duration
|
|
|
|
ListenAddr string
|
|
}
|
|
|
|
func LoadConfig() (Config, error) {
|
|
cfg := Config{
|
|
IncludeBNodes: envBool("INCLUDE_BNODES", false),
|
|
CorsOrigins: envString("CORS_ORIGINS", "*"),
|
|
|
|
DefaultNodeLimit: envInt("DEFAULT_NODE_LIMIT", 800_000),
|
|
DefaultEdgeLimit: envInt("DEFAULT_EDGE_LIMIT", 2_000_000),
|
|
MaxNodeLimit: envInt("MAX_NODE_LIMIT", 10_000_000),
|
|
MaxEdgeLimit: envInt("MAX_EDGE_LIMIT", 20_000_000),
|
|
|
|
SparqlHost: envString("SPARQL_HOST", "http://anzograph:8080"),
|
|
SparqlEndpoint: envString("SPARQL_ENDPOINT", ""),
|
|
SparqlUser: envString("SPARQL_USER", ""),
|
|
SparqlPass: envString("SPARQL_PASS", ""),
|
|
SparqlInsecureTLS: envBool("SPARQL_INSECURE_TLS", false),
|
|
SparqlDataFile: envString("SPARQL_DATA_FILE", ""),
|
|
SparqlGraphIRI: envString("SPARQL_GRAPH_IRI", ""),
|
|
SparqlLoadOnStart: envBool("SPARQL_LOAD_ON_START", false),
|
|
SparqlClearOnStart: envBool("SPARQL_CLEAR_ON_START", false),
|
|
|
|
SparqlReadyRetries: envInt("SPARQL_READY_RETRIES", 30),
|
|
ListenAddr: envString("LISTEN_ADDR", ":8000"),
|
|
}
|
|
|
|
var err error
|
|
cfg.SparqlTimeout, err = envSeconds("SPARQL_TIMEOUT_S", 300)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
cfg.SparqlReadyDelay, err = envSeconds("SPARQL_READY_DELAY_S", 4)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
cfg.SparqlReadyTimeout, err = envSeconds("SPARQL_READY_TIMEOUT_S", 10)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
|
|
if cfg.SparqlLoadOnStart && strings.TrimSpace(cfg.SparqlDataFile) == "" {
|
|
return Config{}, fmt.Errorf("SPARQL_LOAD_ON_START=true but SPARQL_DATA_FILE is not set")
|
|
}
|
|
|
|
if cfg.DefaultNodeLimit < 1 {
|
|
return Config{}, fmt.Errorf("DEFAULT_NODE_LIMIT must be >= 1")
|
|
}
|
|
if cfg.DefaultEdgeLimit < 1 {
|
|
return Config{}, fmt.Errorf("DEFAULT_EDGE_LIMIT must be >= 1")
|
|
}
|
|
if cfg.MaxNodeLimit < 1 {
|
|
return Config{}, fmt.Errorf("MAX_NODE_LIMIT must be >= 1")
|
|
}
|
|
if cfg.MaxEdgeLimit < 1 {
|
|
return Config{}, fmt.Errorf("MAX_EDGE_LIMIT must be >= 1")
|
|
}
|
|
if cfg.DefaultNodeLimit > cfg.MaxNodeLimit {
|
|
return Config{}, fmt.Errorf("DEFAULT_NODE_LIMIT must be <= MAX_NODE_LIMIT")
|
|
}
|
|
if cfg.DefaultEdgeLimit > cfg.MaxEdgeLimit {
|
|
return Config{}, fmt.Errorf("DEFAULT_EDGE_LIMIT must be <= MAX_EDGE_LIMIT")
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
func (c Config) EffectiveSparqlEndpoint() string {
|
|
if strings.TrimSpace(c.SparqlEndpoint) != "" {
|
|
return strings.TrimSpace(c.SparqlEndpoint)
|
|
}
|
|
return strings.TrimRight(c.SparqlHost, "/") + "/sparql"
|
|
}
|
|
|
|
func (c Config) corsOriginList() []string {
|
|
raw := strings.TrimSpace(c.CorsOrigins)
|
|
if raw == "" || raw == "*" {
|
|
return []string{"*"}
|
|
}
|
|
parts := strings.Split(raw, ",")
|
|
out := make([]string, 0, len(parts))
|
|
for _, p := range parts {
|
|
p = strings.TrimSpace(p)
|
|
if p == "" {
|
|
continue
|
|
}
|
|
out = append(out, p)
|
|
}
|
|
if len(out) == 0 {
|
|
return []string{"*"}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func envString(name, def string) string {
|
|
v := os.Getenv(name)
|
|
if strings.TrimSpace(v) == "" {
|
|
return def
|
|
}
|
|
return v
|
|
}
|
|
|
|
func envBool(name string, def bool) bool {
|
|
v := strings.TrimSpace(os.Getenv(name))
|
|
if v == "" {
|
|
return def
|
|
}
|
|
switch strings.ToLower(v) {
|
|
case "1", "true", "yes", "y", "on":
|
|
return true
|
|
case "0", "false", "no", "n", "off":
|
|
return false
|
|
default:
|
|
return def
|
|
}
|
|
}
|
|
|
|
func envInt(name string, def int) int {
|
|
v := strings.TrimSpace(os.Getenv(name))
|
|
if v == "" {
|
|
return def
|
|
}
|
|
v = strings.ReplaceAll(v, "_", "")
|
|
n, err := strconv.Atoi(v)
|
|
if err != nil {
|
|
return def
|
|
}
|
|
return n
|
|
}
|
|
|
|
func envSeconds(name string, def float64) (time.Duration, error) {
|
|
v := strings.TrimSpace(os.Getenv(name))
|
|
if v == "" {
|
|
return time.Duration(def * float64(time.Second)), nil
|
|
}
|
|
f, err := strconv.ParseFloat(v, 64)
|
|
if err != nil {
|
|
return 0, fmt.Errorf("%s must be a number (seconds): %w", name, err)
|
|
}
|
|
return time.Duration(f * float64(time.Second)), nil
|
|
}
|