blob: b3cc3d91406333dfcf613d3638daf24bc77586b7 [file] [log] [blame]
Jiri Simsa5293dcb2014-05-10 09:56:38 -07001package impl
2
3import (
4 "errors"
5 "path"
6
7 "veyron/services/mgmt/profile"
8
9 "veyron2/ipc"
10 "veyron2/storage"
Tilak Sharmaa5e479f2014-05-11 22:27:43 -070011 "veyron2/storage/vstore/primitives"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070012 "veyron2/vlog"
13)
14
15// invoker holds the profile manager invocation.
16type invoker struct {
17 // store is the storage server used for storing profile data.
18 store storage.Store
19 // suffix is the suffix of the current invocation that is assumed to
20 // be used as a relative veyron name to identify a profile
21 // specification.
22 suffix string
23}
24
25var (
26 errNotFound = errors.New("not found")
27 errOperationFailed = errors.New("operation failed")
28)
29
30// NewInvoker is the invoker factory.
31func NewInvoker(store storage.Store, suffix string) *invoker {
32 return &invoker{store: store, suffix: suffix}
33}
34
35// STORE MANAGEMENT INTERFACE IMPLEMENTATION
36
37// dir is used to organize directory contents in the store.
38type dir struct{}
39
40// makeParentNodes creates the parent nodes if they do not already exist.
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070041func makeParentNodes(context ipc.ServerContext, store storage.Store, transaction storage.Transaction, path string) error {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070042 pathComponents := storage.ParsePath(path)
43 for i := 0; i < len(pathComponents); i++ {
44 name := pathComponents[:i].String()
45 object := store.Bind(name)
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070046 if _, err := object.Get(context, transaction); err != nil {
47 if _, err := object.Put(context, transaction, &dir{}); err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070048 return errOperationFailed
49 }
50 }
51 }
52 return nil
53}
54
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070055func (i *invoker) Put(context ipc.ServerContext, profile profile.Specification) error {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070056 vlog.VI(0).Infof("%v.Put(%v)", i.suffix, profile)
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070057 transaction := primitives.NewTransaction(context)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070058 path := path.Join("/profiles", i.suffix)
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070059 if err := makeParentNodes(context, i.store, transaction, path); err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070060 return err
61 }
62 object := i.store.Bind(path)
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070063 if _, err := object.Put(context, transaction, profile); err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070064 return errOperationFailed
65 }
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070066 if err := transaction.Commit(context); err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070067 return errOperationFailed
68 }
69 return nil
70}
71
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070072func (i *invoker) Remove(context ipc.ServerContext) error {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070073 vlog.VI(0).Infof("%v.Remove(%v)", i.suffix)
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070074 transaction := primitives.NewTransaction(context)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070075 path := path.Join("/profiles", i.suffix)
76 object := i.store.Bind(path)
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070077 found, err := object.Exists(context, transaction)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070078 if err != nil {
79 return errOperationFailed
80 }
81 if !found {
82 return errNotFound
83 }
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070084 if err := object.Remove(context, transaction); err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070085 return errOperationFailed
86 }
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070087 if err := transaction.Commit(context); err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070088 return errOperationFailed
89 }
90 return nil
91}
92
93// PROFILE INTERACE IMPLEMENTATION
94
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070095func (i *invoker) lookup(context ipc.ServerContext) (profile.Specification, error) {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070096 empty := profile.Specification{}
97 path := path.Join("/profiles", i.suffix)
98 object := i.store.Bind(path)
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070099 entry, err := object.Get(context, nil)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700100 if err != nil {
101 return empty, errNotFound
102 }
103 s, ok := entry.Value.(profile.Specification)
104 if !ok {
105 return empty, errOperationFailed
106 }
107 return s, nil
108}
109
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700110func (i *invoker) Label(context ipc.ServerContext) (string, error) {
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700111 vlog.VI(0).Infof("%v.Label()", i.suffix)
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700112 s, err := i.lookup(context)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700113 if err != nil {
114 return "", err
115 }
116 return s.Label, nil
117}
118
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700119func (i *invoker) Description(context ipc.ServerContext) (string, error) {
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700120 vlog.VI(0).Infof("%v.Description()", i.suffix)
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700121 s, err := i.lookup(context)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700122 if err != nil {
123 return "", err
124 }
125 return s.Description, nil
126}
127
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700128func (i *invoker) Specification(context ipc.ServerContext) (profile.Specification, error) {
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700129 vlog.VI(0).Infof("%v.Specification()", i.suffix)
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700130 return i.lookup(context)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700131}