Load previously saved nodes.json

This commit is contained in:
Julian Kornberger 2016-03-20 18:30:44 +01:00
parent 53720c3c57
commit eb04fd0049
6 changed files with 80 additions and 41 deletions

View File

@ -15,9 +15,6 @@ nodes:
saveinterval: 5 saveinterval: 5
aliases_enable: false aliases_enable: false
aliases_path: /var/www/html/meshviewer/data/aliases.json aliases_path: /var/www/html/meshviewer/data/aliases.json
vpn_addresses:
- da:25:d6:5c:97:6f
- da:62:f2:70:c8:8d
influxdb: influxdb:
enable: false enable: false
database: ffhb database: ffhb

28
main.go
View File

@ -22,7 +22,7 @@ var (
wsserverForNodes *websocketserver.Server wsserverForNodes *websocketserver.Server
collector *respond.Collector collector *respond.Collector
statsDb *StatsDb statsDb *StatsDb
nodes = models.NewNodes() nodes *models.Nodes
//aliases = models.NewNodes() //aliases = models.NewNodes()
) )
@ -30,18 +30,7 @@ func main() {
flag.StringVar(&configFile, "config", "config.yml", "path of configuration file (default:config.yaml)") flag.StringVar(&configFile, "config", "config.yml", "path of configuration file (default:config.yaml)")
flag.Parse() flag.Parse()
config = models.ConfigReadFile(configFile) config = models.ConfigReadFile(configFile)
nodes = models.NewNodes(config)
if config.Nodes.Enable {
go nodes.Saver(config)
}
if config.Webserver.Enable {
if config.Webserver.WebsocketNode {
wsserverForNodes = websocketserver.NewServer("/nodes")
go wsserverForNodes.Listen()
}
http.Handle("/", http.FileServer(http.Dir(config.Webserver.Webroot)))
}
if config.Influxdb.Enable { if config.Influxdb.Enable {
statsDb = NewStatsDb() statsDb = NewStatsDb()
@ -52,9 +41,18 @@ func main() {
collector = respond.NewCollector("nodeinfo statistics neighbours", collectInterval, onReceive) collector = respond.NewCollector("nodeinfo statistics neighbours", collectInterval, onReceive)
} }
// TODO bad if config.Webserver.WebsocketNode {
wsserverForNodes = websocketserver.NewServer("/nodes")
go wsserverForNodes.Listen()
}
if config.Webserver.Enable { if config.Webserver.Enable {
log.Fatal(http.ListenAndServe(net.JoinHostPort(config.Webserver.Address, config.Webserver.Port), nil)) http.Handle("/", http.FileServer(http.Dir(config.Webserver.Webroot)))
address := net.JoinHostPort(config.Webserver.Address, config.Webserver.Port)
log.Println("starting webserver on", address)
// TODO bad
log.Fatal(http.ListenAndServe(address, nil))
} }
// Wait for INT/TERM // Wait for INT/TERM

View File

@ -26,18 +26,13 @@ type GraphBuilder struct {
vpn map[string]interface{} // IDs/addresses of VPN servers vpn map[string]interface{} // IDs/addresses of VPN servers
} }
func (nodes *Nodes) BuildGraph(vpnAddresses []string) *Graph { func (nodes *Nodes) BuildGraph() *Graph {
builder := &GraphBuilder{ builder := &GraphBuilder{
macToID: make(map[string]string), macToID: make(map[string]string),
links: make(map[string]*GraphLink), links: make(map[string]*GraphLink),
vpn: make(map[string]interface{}), vpn: make(map[string]interface{}),
} }
// read VPN addresses into map
for _, address := range vpnAddresses {
builder.vpn[address] = nil
}
builder.readNodes(nodes.List) builder.readNodes(nodes.List)
graph := &Graph{Version: 2} graph := &Graph{Version: 2}

View File

@ -30,16 +30,23 @@ type Nodes struct {
Version int `json:"version"` Version int `json:"version"`
Timestamp jsontime.Time `json:"timestamp"` Timestamp jsontime.Time `json:"timestamp"`
List map[string]*Node `json:"nodes"` // the current nodemap, indexed by node ID List map[string]*Node `json:"nodes"` // the current nodemap, indexed by node ID
config *Config
sync.Mutex sync.Mutex
} }
// NewNodes create Nodes structs (cache DB) // NewNodes create Nodes structs
func NewNodes() *Nodes { func NewNodes(config *Config) *Nodes {
nodes := &Nodes{ nodes := &Nodes{
Version: 2, List: make(map[string]*Node),
List: make(map[string]*Node), config: config,
} }
if config.Nodes.NodesPath != "" {
nodes.load()
}
go nodes.worker()
nodes.Version = 2
return nodes return nodes
} }
@ -76,39 +83,55 @@ func (nodes *Nodes) Update(nodeID string, res *data.ResponseData) {
} }
} }
// Saves the cached DB to json file periodically // Periodically saves the cached DB to json file
func (nodes *Nodes) Saver(config *Config) { func (nodes *Nodes) worker() {
c := time.Tick(time.Second * time.Duration(config.Nodes.SaveInterval)) c := time.Tick(time.Second * 5)
for range c { for range c {
log.Println("saving", len(nodes.List), "nodes") log.Println("saving", len(nodes.List), "nodes")
nodes.Timestamp = time.Now() nodes.Timestamp = jsontime.Now()
nodes.Lock() nodes.Lock()
if path := config.Nodes.NodesPath; path != "" {
// serialize nodes
save(nodes, nodes.config.Nodes.NodesPath)
if path := nodes.config.Nodes.GraphsPath; path != "" {
save(nodes, path) save(nodes, path)
} }
if path := config.Nodes.GraphsPath; path != "" {
save(nodes.BuildGraph(config.Nodes.VpnAddresses), path)
}
nodes.Unlock() nodes.Unlock()
} }
} }
func (nodes *Nodes) load() {
path := nodes.config.Nodes.NodesPath
log.Println("loading", path)
if data, err := ioutil.ReadFile(path); err == nil {
if err := json.Unmarshal(data, nodes); err == nil {
log.Println("loaded", len(nodes.List), "nodes")
} else {
log.Println("failed to unmarshal nodes:", err)
}
} else {
log.Println("failed loading cached nodes:", err)
}
}
func save(input interface{}, outputFile string) { func save(input interface{}, outputFile string) {
data, err := json.Marshal(input) data, err := json.Marshal(input)
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
} }
tmpFile := outputFile + ".tmp" tmpFile := outputFile + ".tmp"
err = ioutil.WriteFile(tmpFile, data, 0644) if err := ioutil.WriteFile(tmpFile, data, 0644); err != nil {
if err != nil {
log.Panic(err) log.Panic(err)
} }
err = os.Rename(tmpFile, outputFile)
if err != nil { if err := os.Rename(tmpFile, outputFile); err != nil {
log.Panic(err) log.Panic(err)
} }
} }

25
models/nodes_test.go Normal file
View File

@ -0,0 +1,25 @@
package models
import (
"io/ioutil"
"os"
"testing"
"github.com/stretchr/testify/assert"
)
func TestLoadAndSave(t *testing.T) {
assert := assert.New(t)
config := &Config{}
config.Nodes.NodesPath = "testdata/nodes.json"
nodes := &Nodes{config: config}
nodes.load()
tmpfile, _ := ioutil.TempFile("/tmp", "nodes")
save(nodes, tmpfile.Name())
os.Remove(tmpfile.Name())
assert.Equal(1, len(nodes.List))
}

1
models/testdata/nodes.json vendored Normal file
View File

@ -0,0 +1 @@
{"nodes": {"f4f26dd7a30a": {"firstseen": "2016-03-10T12:12:01"}}}