blob: 38241e39eb56e2bf7b553a828f8b388c41191899 [file] [log] [blame]
Jiri Simsa5293dcb2014-05-10 09:56:38 -07001package impl
2
3import (
4 "errors"
Jiri Simsa5293dcb2014-05-10 09:56:38 -07005
6 "veyron/services/mgmt/profile"
7
8 "veyron2/ipc"
Adam Sadovsky04c5eef2014-07-30 17:33:27 -07009 "veyron2/naming"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070010 "veyron2/storage"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070011 "veyron2/vlog"
12)
13
Jiri Simsaddbfebb2014-06-20 15:56:06 -070014// invoker holds the profile repository invocation.
Jiri Simsa5293dcb2014-05-10 09:56:38 -070015type invoker struct {
16 // store is the storage server used for storing profile data.
17 store storage.Store
18 // suffix is the suffix of the current invocation that is assumed to
Bogdan Capritad9281a32014-07-02 14:40:39 -070019 // be used as a relative object name to identify a profile
Jiri Simsa5293dcb2014-05-10 09:56:38 -070020 // specification.
21 suffix string
22}
23
24var (
25 errNotFound = errors.New("not found")
26 errOperationFailed = errors.New("operation failed")
27)
28
29// NewInvoker is the invoker factory.
30func NewInvoker(store storage.Store, suffix string) *invoker {
31 return &invoker{store: store, suffix: suffix}
32}
33
34// STORE MANAGEMENT INTERFACE IMPLEMENTATION
35
36// dir is used to organize directory contents in the store.
37type dir struct{}
38
39// makeParentNodes creates the parent nodes if they do not already exist.
Adam Sadovsky04c5eef2014-07-30 17:33:27 -070040func makeParentNodes(context ipc.ServerContext, store storage.Store, path string) error {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070041 pathComponents := storage.ParsePath(path)
42 for i := 0; i < len(pathComponents); i++ {
43 name := pathComponents[:i].String()
Adam Sadovsky04c5eef2014-07-30 17:33:27 -070044 object := store.BindObject(name)
45 if _, err := object.Get(context); err != nil {
46 if _, err := object.Put(context, &dir{}); err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070047 return errOperationFailed
48 }
49 }
50 }
51 return nil
52}
53
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070054func (i *invoker) Put(context ipc.ServerContext, profile profile.Specification) error {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070055 vlog.VI(0).Infof("%v.Put(%v)", i.suffix, profile)
Adam Sadovsky04c5eef2014-07-30 17:33:27 -070056 // Transaction is rooted at "", so tname == tid.
57 tname, err := i.store.BindTransactionRoot("").CreateTransaction(context)
58 if err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070059 return err
60 }
Ken Ashcraft7ca37d92014-08-12 17:46:43 -070061 path := naming.Join(tname, "/profiles", i.suffix)
Adam Sadovsky04c5eef2014-07-30 17:33:27 -070062 if err := makeParentNodes(context, i.store, path); err != nil {
63 return err
64 }
65 object := i.store.BindObject(path)
66 if _, err := object.Put(context, profile); err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070067 return errOperationFailed
68 }
Adam Sadovsky04c5eef2014-07-30 17:33:27 -070069 if err := i.store.BindTransaction(tname).Commit(context); err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070070 return errOperationFailed
71 }
72 return nil
73}
74
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070075func (i *invoker) Remove(context ipc.ServerContext) error {
Cosmos Nicolaouef43dc42014-06-13 14:38:51 -070076 vlog.VI(0).Infof("%v.Remove()", i.suffix)
Adam Sadovsky04c5eef2014-07-30 17:33:27 -070077 // Transaction is rooted at "", so tname == tid.
78 tname, err := i.store.BindTransactionRoot("").CreateTransaction(context)
79 if err != nil {
80 return err
81 }
Ken Ashcraft7ca37d92014-08-12 17:46:43 -070082 path := naming.Join(tname, "/profiles", i.suffix)
Adam Sadovsky04c5eef2014-07-30 17:33:27 -070083 object := i.store.BindObject(path)
84 found, err := object.Exists(context)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070085 if err != nil {
86 return errOperationFailed
87 }
88 if !found {
89 return errNotFound
90 }
Adam Sadovsky04c5eef2014-07-30 17:33:27 -070091 if err := object.Remove(context); err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070092 return errOperationFailed
93 }
Adam Sadovsky04c5eef2014-07-30 17:33:27 -070094 if err := i.store.BindTransaction(tname).Commit(context); err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070095 return errOperationFailed
96 }
97 return nil
98}
99
100// PROFILE INTERACE IMPLEMENTATION
101
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700102func (i *invoker) lookup(context ipc.ServerContext) (profile.Specification, error) {
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700103 empty := profile.Specification{}
Ken Ashcraft7ca37d92014-08-12 17:46:43 -0700104 path := naming.Join("/profiles", i.suffix)
Adam Sadovsky04c5eef2014-07-30 17:33:27 -0700105 entry, err := i.store.BindObject(path).Get(context)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700106 if err != nil {
107 return empty, errNotFound
108 }
109 s, ok := entry.Value.(profile.Specification)
110 if !ok {
111 return empty, errOperationFailed
112 }
113 return s, nil
114}
115
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700116func (i *invoker) Label(context ipc.ServerContext) (string, error) {
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700117 vlog.VI(0).Infof("%v.Label()", i.suffix)
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700118 s, err := i.lookup(context)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700119 if err != nil {
120 return "", err
121 }
122 return s.Label, nil
123}
124
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700125func (i *invoker) Description(context ipc.ServerContext) (string, error) {
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700126 vlog.VI(0).Infof("%v.Description()", i.suffix)
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700127 s, err := i.lookup(context)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700128 if err != nil {
129 return "", err
130 }
131 return s.Description, nil
132}
133
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700134func (i *invoker) Specification(context ipc.ServerContext) (profile.Specification, error) {
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700135 vlog.VI(0).Infof("%v.Specification()", i.suffix)
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700136 return i.lookup(context)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700137}