syncbase: implement various mojo stubs
as part of this, adds all the glue needed to synthesize
ctx and call, etc.
Change-Id: I273e3bdcdfa9a0bd59379e4889631616777d321a
diff --git a/services/syncbase/server/mojo_call.go b/services/syncbase/server/mojo_call.go
new file mode 100644
index 0000000..d0b9dac
--- /dev/null
+++ b/services/syncbase/server/mojo_call.go
@@ -0,0 +1,68 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build mojo
+
+package server
+
+import (
+ "v.io/v23"
+ "v.io/v23/context"
+ "v.io/v23/naming"
+ "v.io/v23/rpc"
+ "v.io/v23/security"
+)
+
+type mojoServerCall struct {
+ sec security.Call
+ srv rpc.Server
+ suffix string
+}
+
+// TODO(sadovsky): Synthesize endpoints and discharges as needed.
+func newMojoServerCall(ctx *context.T, srv rpc.Server, suffix string, method rpc.MethodDesc) rpc.ServerCall {
+ p := v23.GetPrincipal(ctx)
+ // HACK: For now, we set the remote (client, i.e. Mojo app) blessing to be the
+ // same as the local (server, i.e. Syncbase Mojo service) blessing.
+ // TODO(sadovsky): Eliminate this hack.
+ blessings := p.BlessingStore().Default()
+ return &mojoServerCall{
+ sec: security.NewCall(&security.CallParams{
+ Method: method.Name,
+ MethodTags: method.Tags,
+ Suffix: suffix,
+ LocalPrincipal: p,
+ LocalBlessings: blessings,
+ RemoteBlessings: blessings,
+ }),
+ srv: srv,
+ suffix: suffix,
+ }
+}
+
+var _ rpc.ServerCall = (*mojoServerCall)(nil)
+
+func (call *mojoServerCall) Security() security.Call {
+ return call.sec
+}
+
+func (call *mojoServerCall) Suffix() string {
+ return call.suffix
+}
+
+func (call *mojoServerCall) LocalEndpoint() naming.Endpoint {
+ return call.sec.LocalEndpoint()
+}
+
+func (call *mojoServerCall) RemoteEndpoint() naming.Endpoint {
+ return call.sec.RemoteEndpoint()
+}
+
+func (call *mojoServerCall) GrantedBlessings() security.Blessings {
+ return security.Blessings{}
+}
+
+func (call *mojoServerCall) Server() rpc.Server {
+ return call.srv
+}
diff --git a/services/syncbase/server/mojo_impl.go b/services/syncbase/server/mojo_impl.go
index bc7d0d7..8787d0f 100644
--- a/services/syncbase/server/mojo_impl.go
+++ b/services/syncbase/server/mojo_impl.go
@@ -4,190 +4,480 @@
// +build mojo
+// Implementation of Syncbase Mojo stubs. Our strategy is to translate Mojo stub
+// requests into Vanadium stub requests, and Vanadium stub responses into Mojo
+// stub responses. As part of this procedure, we synthesize "fake" ctx and call
+// objects to pass to the Vanadium stubs.
+
package server
import (
- wire "mojom/syncbase"
+ "bytes"
+ "fmt"
+ "strings"
+
+ mojom "mojom/syncbase"
+ wire "v.io/syncbase/v23/services/syncbase"
+ nosqlwire "v.io/syncbase/v23/services/syncbase/nosql"
+ "v.io/v23/context"
+ "v.io/v23/rpc"
+ "v.io/v23/security/access"
+ "v.io/v23/services/permissions"
+ "v.io/v23/verror"
+ "v.io/v23/vtrace"
)
+const NoSchema int32 = -1
+
type mojoImpl struct {
- s *service
+ ctx *context.T
+ srv rpc.Server
+ disp rpc.Dispatcher
}
-func NewMojoImpl(s interface{}) *mojoImpl {
- return &mojoImpl{s: s.(*service)}
+func NewMojoImpl(ctx *context.T, srv rpc.Server, disp rpc.Dispatcher) *mojoImpl {
+ return &mojoImpl{ctx: ctx, srv: srv, disp: disp}
}
-// TODO(sadovsky): Implement all stubs. The high-level plan is to translate Mojo
-// requests into Vanadium requests by constructing suitable ctx and call objects
-// and then performing the same work that server.Dispatcher and nosql.Dispatcher
-// do (perhaps with some refactoring to share dispatcher code).
+func methodDesc(desc rpc.InterfaceDesc, name string) rpc.MethodDesc {
+ for _, method := range desc.Methods {
+ if method.Name == name {
+ return method
+ }
+ }
+ panic(fmt.Sprintf("unknown method: %s.%s", desc.Name, name))
+}
-// TODO(sadovsky): Implement security hack, where we derive a client blessing
-// from the Syncbase server's blessing.
+func (m *mojoImpl) newCtxCall(suffix string, method rpc.MethodDesc) (*context.T, rpc.ServerCall) {
+ ctx, _ := vtrace.WithNewTrace(m.ctx)
+ return ctx, newMojoServerCall(m.ctx, m.srv, suffix, method)
+}
+
+////////////////////////////////////////
+// Struct converters
+
+func toMojoError(err error) mojom.Error {
+ if err == nil {
+ return mojom.Error{}
+ }
+ return mojom.Error{
+ Id: string(verror.ErrorID(err)),
+ ActionCode: uint32(verror.Action(err)),
+ Msg: err.Error(),
+ }
+}
+
+func toV23Perms(mPerms mojom.Perms) (access.Permissions, error) {
+ return access.ReadPermissions(strings.NewReader(mPerms.Json))
+}
+
+func toMojoPerms(vPerms access.Permissions) (mojom.Perms, error) {
+ b := new(bytes.Buffer)
+ if err := vPerms.WriteTo(b); err != nil {
+ return mojom.Perms{}, err
+ }
+ return mojom.Perms{Json: b.String()}, nil
+}
+
+////////////////////////////////////////
+// Stub getters
+
+func (m *mojoImpl) lookupAndAuthorize(ctx *context.T, call rpc.ServerCall, suffix string) (interface{}, error) {
+ resInt, auth, err := m.disp.Lookup(ctx, suffix)
+ if err != nil {
+ return nil, err
+ }
+ if err := auth.Authorize(ctx, call.Security()); err != nil {
+ return nil, verror.New(verror.ErrNoAccess, ctx, err)
+ }
+ return resInt, nil
+}
+
+func (m *mojoImpl) getService(ctx *context.T, call rpc.ServerCall) (wire.ServiceServerStubMethods, error) {
+ resInt, err := m.lookupAndAuthorize(ctx, call, "")
+ if err != nil {
+ return nil, err
+ }
+ if res, ok := resInt.(wire.ServiceServerStubMethods); !ok {
+ return nil, verror.NewErrInternal(ctx)
+ } else {
+ return res, nil
+ }
+}
+
+func (m *mojoImpl) getApp(ctx *context.T, call rpc.ServerCall, name string) (wire.AppServerStubMethods, error) {
+ resInt, err := m.lookupAndAuthorize(ctx, call, name)
+ if err != nil {
+ return nil, err
+ }
+ if res, ok := resInt.(wire.AppServerStubMethods); !ok {
+ return nil, verror.NewErrInternal(ctx)
+ } else {
+ return res, nil
+ }
+}
+
+func (m *mojoImpl) getDb(ctx *context.T, call rpc.ServerCall, name string) (nosqlwire.DatabaseServerStubMethods, error) {
+ resInt, err := m.lookupAndAuthorize(ctx, call, name)
+ if err != nil {
+ return nil, err
+ }
+ if res, ok := resInt.(nosqlwire.DatabaseServerStubMethods); !ok {
+ return nil, verror.NewErrInternal(ctx)
+ } else {
+ return res, nil
+ }
+}
+
+func (m *mojoImpl) getTable(ctx *context.T, call rpc.ServerCall, name string) (nosqlwire.TableServerStubMethods, error) {
+ resInt, err := m.lookupAndAuthorize(ctx, call, name)
+ if err != nil {
+ return nil, err
+ }
+ if res, ok := resInt.(nosqlwire.TableServerStubMethods); !ok {
+ return nil, verror.NewErrInternal(ctx)
+ } else {
+ return res, nil
+ }
+}
+
+func (m *mojoImpl) getRow(ctx *context.T, call rpc.ServerCall, name string) (nosqlwire.RowServerStubMethods, error) {
+ resInt, err := m.lookupAndAuthorize(ctx, call, name)
+ if err != nil {
+ return nil, err
+ }
+ if res, ok := resInt.(nosqlwire.RowServerStubMethods); !ok {
+ return nil, verror.NewErrInternal(ctx)
+ } else {
+ return res, nil
+ }
+}
////////////////////////////////////////
// Service
-func (m *mojoImpl) ServiceGetPermissions() (wire.Error, wire.Perms, string, error) {
- return wire.Error{}, wire.Perms{}, "", nil
+// TODO(sadovsky): All stub implementations return a nil error (the last return
+// value), since that error doesn't make it back to the IPC client. Chat with
+// rogulenko@ about whether we should change the Go Mojo stub generator to drop
+// these errors.
+func (m *mojoImpl) ServiceGetPermissions() (mojom.Error, mojom.Perms, string, error) {
+ ctx, call := m.newCtxCall("", methodDesc(permissions.ObjectDesc, "GetPermissions"))
+ stub, err := m.getService(ctx, call)
+ if err != nil {
+ return toMojoError(err), mojom.Perms{}, "", nil
+ }
+ vPerms, version, err := stub.GetPermissions(ctx, call)
+ if err != nil {
+ return toMojoError(err), mojom.Perms{}, "", nil
+ }
+ mPerms, err := toMojoPerms(vPerms)
+ if err != nil {
+ return toMojoError(err), mojom.Perms{}, "", nil
+ }
+ return toMojoError(err), mPerms, version, nil
}
-func (m *mojoImpl) ServiceSetPermissions(perms wire.Perms, version string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) ServiceSetPermissions(mPerms mojom.Perms, version string) (mojom.Error, error) {
+ ctx, call := m.newCtxCall("", methodDesc(permissions.ObjectDesc, "SetPermissions"))
+ stub, err := m.getService(ctx, call)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ vPerms, err := toV23Perms(mPerms)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ err = stub.SetPermissions(ctx, call, vPerms, version)
+ return toMojoError(err), nil
}
////////////////////////////////////////
// App
-func (m *mojoImpl) AppCreate(name string, perms wire.Perms) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) AppCreate(name string, mPerms mojom.Perms) (mojom.Error, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(wire.AppDesc, "Create"))
+ stub, err := m.getApp(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ vPerms, err := toV23Perms(mPerms)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ err = stub.Create(ctx, call, vPerms)
+ return toMojoError(err), nil
}
-func (m *mojoImpl) AppDelete(name string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) AppDelete(name string) (mojom.Error, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(wire.AppDesc, "Delete"))
+ stub, err := m.getApp(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ err = stub.Delete(ctx, call)
+ return toMojoError(err), nil
}
-func (m *mojoImpl) AppExists(name string) (wire.Error, bool, error) {
- return wire.Error{}, false, nil
+func (m *mojoImpl) AppExists(name string) (mojom.Error, bool, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(wire.AppDesc, "Exists"))
+ stub, err := m.getApp(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), false, nil
+ }
+ exists, err := stub.Exists(ctx, call)
+ return toMojoError(err), exists, nil
}
-func (m *mojoImpl) AppGetPermissions(name string) (wire.Error, wire.Perms, string, error) {
- return wire.Error{}, wire.Perms{}, "", nil
+func (m *mojoImpl) AppGetPermissions(name string) (mojom.Error, mojom.Perms, string, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(permissions.ObjectDesc, "GetPermissions"))
+ stub, err := m.getApp(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), mojom.Perms{}, "", nil
+ }
+ vPerms, version, err := stub.GetPermissions(ctx, call)
+ if err != nil {
+ return toMojoError(err), mojom.Perms{}, "", nil
+ }
+ mPerms, err := toMojoPerms(vPerms)
+ if err != nil {
+ return toMojoError(err), mojom.Perms{}, "", nil
+ }
+ return toMojoError(err), mPerms, version, nil
}
-func (m *mojoImpl) AppSetPermissions(name string, perms wire.Perms, version string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) AppSetPermissions(name string, mPerms mojom.Perms, version string) (mojom.Error, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(permissions.ObjectDesc, "SetPermissions"))
+ stub, err := m.getApp(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ vPerms, err := toV23Perms(mPerms)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ err = stub.SetPermissions(ctx, call, vPerms, version)
+ return toMojoError(err), nil
}
////////////////////////////////////////
// nosql.Database
-func (m *mojoImpl) DbCreate(name string, perms wire.Perms) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) DbCreate(name string, mPerms mojom.Perms) (mojom.Error, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(nosqlwire.DatabaseDesc, "Create"))
+ stub, err := m.getDb(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ vPerms, err := toV23Perms(mPerms)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ err = stub.Create(ctx, call, nil, vPerms)
+ return toMojoError(err), nil
}
-func (m *mojoImpl) DbDelete(name string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) DbDelete(name string) (mojom.Error, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(nosqlwire.DatabaseDesc, "Delete"))
+ stub, err := m.getDb(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ err = stub.Delete(ctx, call, NoSchema)
+ return toMojoError(err), nil
}
-func (m *mojoImpl) DbExists(name string) (wire.Error, bool, error) {
- return wire.Error{}, false, nil
+func (m *mojoImpl) DbExists(name string) (mojom.Error, bool, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(nosqlwire.DatabaseDesc, "Exists"))
+ stub, err := m.getDb(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), false, nil
+ }
+ exists, err := stub.Exists(ctx, call, NoSchema)
+ return toMojoError(err), exists, nil
}
-func (m *mojoImpl) DbExec(name string, query string, stream wire.ExecStream_Request) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) DbExec(name string, query string, stream mojom.ExecStream_Request) (mojom.Error, error) {
+ return mojom.Error{}, nil
}
-func (m *mojoImpl) DbBeginBatch(name string, bo *wire.BatchOptions) (wire.Error, string, error) {
- return wire.Error{}, "", nil
+func (m *mojoImpl) DbBeginBatch(name string, bo *mojom.BatchOptions) (mojom.Error, string, error) {
+ return mojom.Error{}, "", nil
}
-func (m *mojoImpl) DbCommit(name string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) DbCommit(name string) (mojom.Error, error) {
+ return mojom.Error{}, nil
}
-func (m *mojoImpl) DbAbort(name string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) DbAbort(name string) (mojom.Error, error) {
+ return mojom.Error{}, nil
}
-func (m *mojoImpl) DbGetPermissions(name string) (wire.Error, wire.Perms, string, error) {
- return wire.Error{}, wire.Perms{}, "", nil
+func (m *mojoImpl) DbGetPermissions(name string) (mojom.Error, mojom.Perms, string, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(permissions.ObjectDesc, "GetPermissions"))
+ stub, err := m.getDb(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), mojom.Perms{}, "", nil
+ }
+ vPerms, version, err := stub.GetPermissions(ctx, call)
+ if err != nil {
+ return toMojoError(err), mojom.Perms{}, "", nil
+ }
+ mPerms, err := toMojoPerms(vPerms)
+ if err != nil {
+ return toMojoError(err), mojom.Perms{}, "", nil
+ }
+ return toMojoError(err), mPerms, version, nil
}
-func (m *mojoImpl) DbSetPermissions(name string, perms wire.Perms, version string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) DbSetPermissions(name string, mPerms mojom.Perms, version string) (mojom.Error, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(permissions.ObjectDesc, "SetPermissions"))
+ stub, err := m.getDb(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ vPerms, err := toV23Perms(mPerms)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ err = stub.SetPermissions(ctx, call, vPerms, version)
+ return toMojoError(err), nil
}
////////////////////////////////////////
// nosql.Database:SyncGroupManager
-func (m *mojoImpl) DbGetSyncGroupNames(name string) (wire.Error, []string, error) {
- return wire.Error{}, nil, nil
+func (m *mojoImpl) DbGetSyncGroupNames(name string) (mojom.Error, []string, error) {
+ return mojom.Error{}, nil, nil
}
-func (m *mojoImpl) DbCreateSyncGroup(name, sgName string, spec wire.SyncGroupSpec, myInfo wire.SyncGroupMemberInfo) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) DbCreateSyncGroup(name, sgName string, spec mojom.SyncGroupSpec, myInfo mojom.SyncGroupMemberInfo) (mojom.Error, error) {
+ return mojom.Error{}, nil
}
-func (m *mojoImpl) DbJoinSyncGroup(name, sgName string, myInfo wire.SyncGroupMemberInfo) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) DbJoinSyncGroup(name, sgName string, myInfo mojom.SyncGroupMemberInfo) (mojom.Error, error) {
+ return mojom.Error{}, nil
}
-func (m *mojoImpl) DbLeaveSyncGroup(name, sgName string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) DbLeaveSyncGroup(name, sgName string) (mojom.Error, error) {
+ return mojom.Error{}, nil
}
-func (m *mojoImpl) DbDestroySyncGroup(name, sgName string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) DbDestroySyncGroup(name, sgName string) (mojom.Error, error) {
+ return mojom.Error{}, nil
}
-func (m *mojoImpl) DbEjectFromSyncGroup(name, sgName string, member string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) DbEjectFromSyncGroup(name, sgName string, member string) (mojom.Error, error) {
+ return mojom.Error{}, nil
}
-func (m *mojoImpl) DbGetSyncGroupSpec(name, sgName string) (wire.Error, wire.SyncGroupSpec, string, error) {
- return wire.Error{}, wire.SyncGroupSpec{}, "", nil
+func (m *mojoImpl) DbGetSyncGroupSpec(name, sgName string) (mojom.Error, mojom.SyncGroupSpec, string, error) {
+ return mojom.Error{}, mojom.SyncGroupSpec{}, "", nil
}
-func (m *mojoImpl) DbSetSyncGroupSpec(name, sgName string, spec wire.SyncGroupSpec, version string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) DbSetSyncGroupSpec(name, sgName string, spec mojom.SyncGroupSpec, version string) (mojom.Error, error) {
+ return mojom.Error{}, nil
}
-func (m *mojoImpl) DbGetSyncGroupMembers(name, sgName string) (wire.Error, map[string]wire.SyncGroupMemberInfo, error) {
- return wire.Error{}, nil, nil
+func (m *mojoImpl) DbGetSyncGroupMembers(name, sgName string) (mojom.Error, map[string]mojom.SyncGroupMemberInfo, error) {
+ return mojom.Error{}, nil, nil
}
////////////////////////////////////////
// nosql.Table
-func (m *mojoImpl) TableCreate(name string, perms wire.Perms) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) TableCreate(name string, mPerms mojom.Perms) (mojom.Error, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(nosqlwire.TableDesc, "Create"))
+ stub, err := m.getTable(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ vPerms, err := toV23Perms(mPerms)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ err = stub.Create(ctx, call, NoSchema, vPerms)
+ return toMojoError(err), nil
}
-func (m *mojoImpl) TableDelete(name string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) TableDelete(name string) (mojom.Error, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(nosqlwire.TableDesc, "Delete"))
+ stub, err := m.getTable(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ err = stub.Delete(ctx, call, NoSchema)
+ return toMojoError(err), nil
}
-func (m *mojoImpl) TableExists(name string) (wire.Error, bool, error) {
- return wire.Error{}, false, nil
+func (m *mojoImpl) TableExists(name string) (mojom.Error, bool, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(nosqlwire.TableDesc, "Exists"))
+ stub, err := m.getTable(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), false, nil
+ }
+ exists, err := stub.Exists(ctx, call, NoSchema)
+ return toMojoError(err), exists, nil
}
-func (m *mojoImpl) TableDeleteRowRange(name string, start, limit []byte) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) TableDeleteRowRange(name string, start, limit []byte) (mojom.Error, error) {
+ return mojom.Error{}, nil
}
-func (m *mojoImpl) TableScan(name string, start, limit []byte, stream wire.ScanStream_Request) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) TableScan(name string, start, limit []byte, stream mojom.ScanStream_Request) (mojom.Error, error) {
+ return mojom.Error{}, nil
}
-func (m *mojoImpl) TableGetPermissions(name, key string) (wire.Error, []wire.PrefixPerms, error) {
- return wire.Error{}, nil, nil
+func (m *mojoImpl) TableGetPermissions(name, key string) (mojom.Error, []mojom.PrefixPerms, error) {
+ return mojom.Error{}, nil, nil
}
-func (m *mojoImpl) TableSetPermissions(name, prefix string, perms wire.Perms) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) TableSetPermissions(name, prefix string, mPerms mojom.Perms) (mojom.Error, error) {
+ return mojom.Error{}, nil
}
-func (m *mojoImpl) TableDeletePermissions(name, prefix string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) TableDeletePermissions(name, prefix string) (mojom.Error, error) {
+ return mojom.Error{}, nil
}
////////////////////////////////////////
// nosql.Row
-func (m *mojoImpl) RowExists(name string) (wire.Error, bool, error) {
- return wire.Error{}, false, nil
+func (m *mojoImpl) RowExists(name string) (mojom.Error, bool, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(nosqlwire.RowDesc, "Exists"))
+ stub, err := m.getRow(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), false, nil
+ }
+ exists, err := stub.Exists(ctx, call, NoSchema)
+ return toMojoError(err), exists, nil
}
-func (m *mojoImpl) RowGet(name string) (wire.Error, []byte, error) {
- return wire.Error{}, nil, nil
+func (m *mojoImpl) RowGet(name string) (mojom.Error, []byte, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(nosqlwire.RowDesc, "Get"))
+ stub, err := m.getRow(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), nil, nil
+ }
+ value, err := stub.Get(ctx, call, NoSchema)
+ return toMojoError(err), value, nil
}
-func (m *mojoImpl) RowPut(name string, value []byte) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) RowPut(name string, value []byte) (mojom.Error, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(nosqlwire.RowDesc, "Put"))
+ stub, err := m.getRow(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ err = stub.Put(ctx, call, NoSchema, value)
+ return toMojoError(err), nil
}
-func (m *mojoImpl) RowDelete(name string) (wire.Error, error) {
- return wire.Error{}, nil
+func (m *mojoImpl) RowDelete(name string) (mojom.Error, error) {
+ ctx, call := m.newCtxCall(name, methodDesc(nosqlwire.RowDesc, "Delete"))
+ stub, err := m.getRow(ctx, call, name)
+ if err != nil {
+ return toMojoError(err), nil
+ }
+ err = stub.Delete(ctx, call, NoSchema)
+ return toMojoError(err), nil
}
diff --git a/services/syncbase/syncbased/main.go b/services/syncbase/syncbased/main.go
index 7fc1e6d..8def540 100644
--- a/services/syncbase/syncbased/main.go
+++ b/services/syncbase/syncbased/main.go
@@ -10,6 +10,7 @@
"v.io/syncbase/x/ref/services/syncbase/server"
"v.io/v23"
"v.io/v23/context"
+ "v.io/v23/rpc"
"v.io/v23/security"
"v.io/v23/security/access"
"v.io/x/lib/vlog"
@@ -35,10 +36,9 @@
return perms
}
-// TODO(sadovsky): We return interface{} as a quick hack to support Mojo. The
-// actual return value is of type *server.service, which we don't want to
-// export.
-func Serve(ctx *context.T) interface{} {
+// TODO(sadovsky): We return rpc.Server and rpc.Dispatcher as a quick hack to
+// support Mojo.
+func Serve(ctx *context.T) (rpc.Server, rpc.Dispatcher) {
s, err := v23.NewServer(ctx)
if err != nil {
vlog.Fatal("v23.NewServer() failed: ", err)
@@ -77,5 +77,5 @@
vlog.Info("Mounted at: ", *name)
}
- return service
+ return s, d
}
diff --git a/services/syncbase/syncbased/mojo_main.go b/services/syncbase/syncbased/mojo_main.go
index 48272bb..b478d4e 100644
--- a/services/syncbase/syncbased/mojo_main.go
+++ b/services/syncbase/syncbased/mojo_main.go
@@ -21,20 +21,26 @@
"v.io/syncbase/x/ref/services/syncbase/server"
"v.io/v23"
+ "v.io/v23/context"
+ "v.io/v23/rpc"
)
//#include "mojo/public/c/system/types.h"
import "C"
type delegate struct {
- service interface{} // actual type is *server.service
- stubs []*bindings.Stub
+ ctx *context.T
+ srv rpc.Server
+ disp rpc.Dispatcher
+ stubs []*bindings.Stub
}
-func (d *delegate) Initialize(ctx application.Context) {}
+func (d *delegate) Initialize(ctx application.Context) {
+ d.srv, d.disp = Serve(d.ctx)
+}
func (d *delegate) Create(req syncbase.Syncbase_Request) {
- impl := server.NewMojoImpl(d.service)
+ impl := server.NewMojoImpl(d.ctx, d.srv, d.disp)
stub := syncbase.NewSyncbaseStub(req, impl, bindings.GetAsyncWaiter())
d.stubs = append(d.stubs, stub)
go func() {
@@ -64,7 +70,7 @@
func MojoMain(handle C.MojoHandle) C.MojoResult {
ctx, shutdown := v23.Init()
defer shutdown()
- application.Run(&delegate{service: Serve(ctx)}, system.MojoHandle(handle))
+ application.Run(&delegate{ctx: ctx}, system.MojoHandle(handle))
return C.MOJO_RESULT_OK
}