~rogpeppe/juju-core/457-configstore-server-cmdline

« back to all changes in this revision

Viewing changes to cmd/configstore/main.go

  • Committer: Roger Peppe
  • Date: 2013-10-22 22:17:50 UTC
  • Revision ID: roger.peppe@canonical.com-20131022221750-v7435px1u0gfr9cr
cmd/configstore: new command
environs/configstore: use JUJU_CONFIGSTORE env var for store server address

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package main
 
2
 
 
3
import (
 
4
        "encoding/json"
 
5
        "flag"
 
6
        "fmt"
 
7
        "net"
 
8
        "net/http"
 
9
        "os"
 
10
        "sync"
 
11
 
 
12
        "launchpad.net/loggo"
 
13
 
 
14
        "launchpad.net/juju-core/environs/configstore"
 
15
        "launchpad.net/juju-core/errors"
 
16
)
 
17
 
 
18
var logger = loggo.GetLogger("juju.cmd.configstore")
 
19
 
 
20
var httpAddr = flag.String("http", ":17018", "HTTP server address")
 
21
 
 
22
func main() {
 
23
        flag.Parse()
 
24
        listener, err := net.Listen("tcp", *httpAddr)
 
25
        if err != nil {
 
26
                logger.Errorf("cannot listen on %q: %v", *httpAddr, err)
 
27
                os.Exit(1)
 
28
        }
 
29
        fmt.Printf("listening on %s\n", listener.Addr())
 
30
        err = http.Serve(listener, configstore.NetworkHandler(newMemServerBacking()))
 
31
        logger.Errorf("http server failed: %v", err)
 
32
}
 
33
 
 
34
type backingEntry struct {
 
35
        data      []byte
 
36
        creatorId string
 
37
}
 
38
 
 
39
type memServerBacking struct {
 
40
        mu           sync.Mutex
 
41
        data         map[string]*backingEntry
 
42
        maxCreatorId int
 
43
}
 
44
 
 
45
func newMemServerBacking() *memServerBacking {
 
46
        return &memServerBacking{
 
47
                data: make(map[string]*backingEntry),
 
48
        }
 
49
}
 
50
 
 
51
func (b *memServerBacking) Create(name string) (string, error) {
 
52
        logger.Infof("memServerBacking.Create %q", name)
 
53
        b.mu.Lock()
 
54
        defer b.mu.Unlock()
 
55
        if b.data[name] != nil {
 
56
                return "", configstore.ErrEnvironInfoAlreadyExists
 
57
        }
 
58
        b.maxCreatorId++
 
59
        id := fmt.Sprint(b.maxCreatorId)
 
60
        b.data[name] = &backingEntry{
 
61
                creatorId: id,
 
62
        }
 
63
        logger.Infof("%d entries", len(b.data))
 
64
        return id, nil
 
65
}
 
66
 
 
67
func (b *memServerBacking) Read(name string, dataPtr interface{}) error {
 
68
        logger.Infof("memServerBacking.Read %q", name)
 
69
        b.mu.Lock()
 
70
        defer b.mu.Unlock()
 
71
        entry := b.data[name]
 
72
        if entry == nil {
 
73
                return errors.NotFoundf("environment %q", name)
 
74
        }
 
75
        if entry.data == nil {
 
76
                return nil
 
77
        }
 
78
        if err := json.Unmarshal(entry.data, dataPtr); err != nil {
 
79
                return fmt.Errorf("cannot unmarshal %q into %T", entry.data, dataPtr)
 
80
        }
 
81
        return nil
 
82
}
 
83
 
 
84
func (b *memServerBacking) Write(name string, creatorId string, v interface{}) error {
 
85
        logger.Infof("memServerBacking.Write %q %q %#v", name, creatorId, v)
 
86
        b.mu.Lock()
 
87
        defer b.mu.Unlock()
 
88
        entry := b.data[name]
 
89
        if entry == nil {
 
90
                return errors.NotFoundf("environment %q", name)
 
91
        }
 
92
        if creatorId != "" && creatorId != entry.creatorId {
 
93
                return fmt.Errorf("cannot write environment %q you did not create", name)
 
94
        }
 
95
        data, err := json.Marshal(v)
 
96
        if err != nil {
 
97
                return fmt.Errorf("cannot marshal %#v: %v", v, err)
 
98
        }
 
99
        entry.data = data
 
100
        return nil
 
101
}
 
102
 
 
103
func (b *memServerBacking) Destroy(name string) error {
 
104
        logger.Infof("memServerBacking.Destroy %q", name)
 
105
        logger.Infof("%d entries", len(b.data))
 
106
        b.mu.Lock()
 
107
        defer b.mu.Unlock()
 
108
        if b.data[name] == nil {
 
109
                return errors.NotFoundf("exnvironment %q", name)
 
110
        }
 
111
        delete(b.data, name)
 
112
        return nil
 
113
}