blob: 741954b5e04413f0a74d3331cb5f0d8814203bc5 [file] [log] [blame]
Jiri Simsa5293dcb2014-05-10 09:56:38 -07001package server
2
3import (
4 "errors"
5
6 "veyron/services/store/service"
7
Jiri Simsa5293dcb2014-05-10 09:56:38 -07008 "veyron2/ipc"
Matt Rosencrantz4b868862014-05-15 15:16:10 -07009 "veyron2/query"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070010 "veyron2/services/mounttable"
11 "veyron2/services/store"
Tilak Sharma79cfb412014-05-27 18:34:57 -070012 "veyron2/services/watch"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070013 "veyron2/storage"
Todd Wange5d67b42014-05-27 10:48:07 -070014 "veyron2/vdl"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070015)
16
17type object struct {
18 name string
19 obj service.Object
20 server *Server
21}
22
23var (
24 errNotAValue = errors.New("not a storage.Value")
25 errNotAnAttribute = errors.New("not a storage.Attr")
26
27 _ store.ObjectService = (*object)(nil)
28
29 nullEntry store.Entry
30 nullStat store.Stat
31)
32
33func fillServiceStat(result *store.Stat, stat *storage.Stat) {
34 result.ID = stat.ID
35 result.MTimeNS = stat.MTime.UnixNano()
36 result.Attrs = attrsToAnyData(stat.Attrs)
37}
38
39func makeServiceStat(stat *storage.Stat) store.Stat {
40 if stat == nil {
41 return nullStat
42 }
43 var result store.Stat
44 fillServiceStat(&result, stat)
45 return result
46}
47
48func makeServiceEntry(e *storage.Entry) store.Entry {
49 if e == nil {
50 return nullEntry
51 }
52 result := store.Entry{Value: e.Value}
53 fillServiceStat(&result.Stat, &e.Stat)
54 return result
55}
56
57func (o *object) String() string {
58 return o.name
59}
60
61func (o *object) Attributes(arg string) map[string]string {
62 return map[string]string{
63 "health": "ok",
64 "servertype": o.String(),
65 }
66}
67
Todd Wange5d67b42014-05-27 10:48:07 -070068func attrsFromAnyData(attrs []vdl.Any) ([]storage.Attr, error) {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070069 typedAttrs := make([]storage.Attr, len(attrs))
70 for i, x := range attrs {
71 a, ok := x.(storage.Attr)
72 if !ok {
73 return nil, errNotAnAttribute
74 }
75 typedAttrs[i] = a
76 }
77 return typedAttrs, nil
78}
79
Todd Wange5d67b42014-05-27 10:48:07 -070080func attrsToAnyData(attrs []storage.Attr) []vdl.Any {
81 uattrs := make([]vdl.Any, len(attrs))
Jiri Simsa5293dcb2014-05-10 09:56:38 -070082 for i, x := range attrs {
83 uattrs[i] = x
84 }
85 return uattrs
86}
87
88// Exists returns true iff the Entry has a value.
89func (o *object) Exists(ctx ipc.Context, tid store.TransactionID) (bool, error) {
90 t, ok := o.server.findTransaction(tid)
91 if !ok {
92 return false, errTransactionDoesNotExist
93 }
94 return o.obj.Exists(ctx.RemoteID(), t)
95}
96
97// Get returns the value for the Object. The value returned is from the
98// most recent mutation of the entry in the Transaction, or from the
99// Transaction's snapshot if there is no mutation.
100func (o *object) Get(ctx ipc.Context, tid store.TransactionID) (store.Entry, error) {
101 t, ok := o.server.findTransaction(tid)
102 if !ok {
103 return nullEntry, errTransactionDoesNotExist
104 }
105 entry, err := o.obj.Get(ctx.RemoteID(), t)
106 if err != nil {
107 return nullEntry, err
108 }
109 return makeServiceEntry(entry), err
110}
111
112// Put modifies the value of the Object.
Todd Wange5d67b42014-05-27 10:48:07 -0700113func (o *object) Put(ctx ipc.Context, tid store.TransactionID, val vdl.Any) (store.Stat, error) {
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700114 t, ok := o.server.findTransaction(tid)
115 if !ok {
116 return nullStat, errTransactionDoesNotExist
117 }
118 stat, err := o.obj.Put(ctx.RemoteID(), t, interface{}(val))
119 if err != nil {
120 return nullStat, err
121 }
122 return makeServiceStat(stat), nil
123}
124
125// Remove removes the Object.
126func (o *object) Remove(ctx ipc.Context, tid store.TransactionID) error {
127 t, ok := o.server.findTransaction(tid)
128 if !ok {
129 return errTransactionDoesNotExist
130 }
131 return o.obj.Remove(ctx.RemoteID(), t)
132}
133
134// SetAttr changes the attributes of the entry, such as permissions and
135// replication groups. Attributes are associated with the value, not the
136// path.
Todd Wange5d67b42014-05-27 10:48:07 -0700137func (o *object) SetAttr(ctx ipc.Context, tid store.TransactionID, attrs []vdl.Any) error {
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700138 t, ok := o.server.findTransaction(tid)
139 if !ok {
140 return errTransactionDoesNotExist
141 }
142 typedAttrs, err := attrsFromAnyData(attrs)
143 if err != nil {
144 return err
145 }
146 return o.obj.SetAttr(ctx.RemoteID(), t, typedAttrs...)
147}
148
149// Stat returns entry info.
150func (o *object) Stat(ctx ipc.Context, tid store.TransactionID) (store.Stat, error) {
151 t, ok := o.server.findTransaction(tid)
152 if !ok {
153 return nullStat, errTransactionDoesNotExist
154 }
155 stat, err := o.obj.Stat(ctx.RemoteID(), t)
156 if err != nil {
157 return nullStat, err
158 }
159 return makeServiceStat(stat), nil
160}
161
Matt Rosencrantz4b868862014-05-15 15:16:10 -0700162// Query returns a sequence of objects that match the given query.
Matt Rosencrantz90c2feb2014-05-23 11:13:48 -0700163func (o *object) Query(ctx ipc.Context, tid store.TransactionID, q query.Query, stream store.ObjectServiceQueryStream) error {
164 t, ok := o.server.findTransaction(tid)
165 if !ok {
166 return errTransactionDoesNotExist
167 }
168 it, err := o.obj.Query(ctx.RemoteID(), t, q)
169 if err != nil {
170 return err
171 }
172 for it.Next() {
173 if err := stream.Send(*it.Get()); err != nil {
174 it.Abort()
175 return err
176 }
177 }
178 return it.Err()
Matt Rosencrantz4b868862014-05-15 15:16:10 -0700179}
180
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700181type globStreamAdapter struct {
182 stream mounttable.GlobableServiceGlobStream
183}
184
185func (a *globStreamAdapter) Send(item string) error {
186 return a.stream.Send(mounttable.MountEntry{
187 Name: item,
188 })
189}
190
191// Glob streams a series of names that match the given pattern.
192func (o *object) Glob(ctx ipc.Context, pattern string, stream mounttable.GlobableServiceGlobStream) error {
193 return o.GlobT(ctx, nullTransactionID, pattern, &globStreamAdapter{stream})
194}
195
196// Glob streams a series of names that match the given pattern.
197func (o *object) GlobT(ctx ipc.Context, tid store.TransactionID, pattern string, stream store.ObjectServiceGlobTStream) error {
198 t, ok := o.server.findTransaction(tid)
199 if !ok {
200 return errTransactionDoesNotExist
201 }
202 it, err := o.obj.Glob(ctx.RemoteID(), t, pattern)
203 if err != nil {
204 return err
205 }
206 for ; it.IsValid(); it.Next() {
207 if ctx.IsClosed() {
208 break
209 }
210 if err := stream.Send(it.Name()); err != nil {
211 return err
212 }
213 }
214 return nil
215}
Tilak Sharma79cfb412014-05-27 18:34:57 -0700216
217// Watch returns a stream of changes.
218func (o *object) Watch(ctx ipc.Context, req watch.Request, stream watch.WatcherServiceWatchStream) error {
219 panic("not implemented")
220}