syncbase/vsync: Handle JoinSyncGroup RPC from client-syncbase.

Change-Id: Ic535383816b9db05bb96ab7ceadab56aa59fde65
diff --git a/services/syncbase/server/interfaces/sync.vdl b/services/syncbase/server/interfaces/sync.vdl
index 7421b48..fe64066 100644
--- a/services/syncbase/server/interfaces/sync.vdl
+++ b/services/syncbase/server/interfaces/sync.vdl
@@ -4,6 +4,10 @@
 
 package interfaces
 
+import (
+	wire "v.io/syncbase/v23/services/syncbase/nosql"
+)
+
 // Sync defines methods for data exchange between Syncbases.
 // TODO(hpucha): Flesh this out further.
 type Sync interface {
@@ -18,9 +22,11 @@
 	// to publish the SyncGroup.
 	PublishSyncGroup(sg SyncGroup) error
 
-	// JoinSyncGroup is invoked on a SyncGroup Admin and checks if
-	// the requestor can join the SyncGroup.
-	JoinSyncGroup() error
+	// JoinSyncGroupAtAdmin is invoked by a prospective SyncGroup member's
+	// Syncbase on a SyncGroup admin. It checks whether the requestor is
+	// allowed to join the named SyncGroup, and if so, adds the requestor to
+	// the SyncGroup.
+	JoinSyncGroupAtAdmin(sgName, joinerName string, myInfo wire.SyncGroupMemberInfo) (SyncGroup | error)
 
 	// BlobSync methods.
 	// FetchBlob returns the requested blob.
diff --git a/services/syncbase/server/interfaces/sync.vdl.go b/services/syncbase/server/interfaces/sync.vdl.go
index 37c9a1e..de16181 100644
--- a/services/syncbase/server/interfaces/sync.vdl.go
+++ b/services/syncbase/server/interfaces/sync.vdl.go
@@ -12,6 +12,9 @@
 	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/v23/rpc"
+
+	// VDL user imports
+	"v.io/syncbase/v23/services/syncbase/nosql"
 )
 
 // SyncClientMethods is the client interface
@@ -27,9 +30,11 @@
 	// PublishSyncGroup is typically invoked on a "central" peer
 	// to publish the SyncGroup.
 	PublishSyncGroup(ctx *context.T, sg SyncGroup, opts ...rpc.CallOpt) error
-	// JoinSyncGroup is invoked on a SyncGroup Admin and checks if
-	// the requestor can join the SyncGroup.
-	JoinSyncGroup(*context.T, ...rpc.CallOpt) error
+	// JoinSyncGroupAtAdmin is invoked by a prospective SyncGroup member's
+	// Syncbase on a SyncGroup admin. It checks whether the requestor is
+	// allowed to join the named SyncGroup, and if so, adds the requestor to
+	// the SyncGroup.
+	JoinSyncGroupAtAdmin(ctx *context.T, sgName string, joinerName string, myInfo nosql.SyncGroupMemberInfo, opts ...rpc.CallOpt) (SyncGroup, error)
 	// BlobSync methods.
 	// FetchBlob returns the requested blob.
 	FetchBlob(*context.T, ...rpc.CallOpt) error
@@ -60,8 +65,8 @@
 	return
 }
 
-func (c implSyncClientStub) JoinSyncGroup(ctx *context.T, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "JoinSyncGroup", nil, nil, opts...)
+func (c implSyncClientStub) JoinSyncGroupAtAdmin(ctx *context.T, i0 string, i1 string, i2 nosql.SyncGroupMemberInfo, opts ...rpc.CallOpt) (o0 SyncGroup, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "JoinSyncGroupAtAdmin", []interface{}{i0, i1, i2}, []interface{}{&o0}, opts...)
 	return
 }
 
@@ -83,9 +88,11 @@
 	// PublishSyncGroup is typically invoked on a "central" peer
 	// to publish the SyncGroup.
 	PublishSyncGroup(ctx *context.T, call rpc.ServerCall, sg SyncGroup) error
-	// JoinSyncGroup is invoked on a SyncGroup Admin and checks if
-	// the requestor can join the SyncGroup.
-	JoinSyncGroup(*context.T, rpc.ServerCall) error
+	// JoinSyncGroupAtAdmin is invoked by a prospective SyncGroup member's
+	// Syncbase on a SyncGroup admin. It checks whether the requestor is
+	// allowed to join the named SyncGroup, and if so, adds the requestor to
+	// the SyncGroup.
+	JoinSyncGroupAtAdmin(ctx *context.T, call rpc.ServerCall, sgName string, joinerName string, myInfo nosql.SyncGroupMemberInfo) (SyncGroup, error)
 	// BlobSync methods.
 	// FetchBlob returns the requested blob.
 	FetchBlob(*context.T, rpc.ServerCall) error
@@ -134,8 +141,8 @@
 	return s.impl.PublishSyncGroup(ctx, call, i0)
 }
 
-func (s implSyncServerStub) JoinSyncGroup(ctx *context.T, call rpc.ServerCall) error {
-	return s.impl.JoinSyncGroup(ctx, call)
+func (s implSyncServerStub) JoinSyncGroupAtAdmin(ctx *context.T, call rpc.ServerCall, i0 string, i1 string, i2 nosql.SyncGroupMemberInfo) (SyncGroup, error) {
+	return s.impl.JoinSyncGroupAtAdmin(ctx, call, i0, i1, i2)
 }
 
 func (s implSyncServerStub) FetchBlob(ctx *context.T, call rpc.ServerCall) error {
@@ -171,8 +178,16 @@
 			},
 		},
 		{
-			Name: "JoinSyncGroup",
-			Doc:  "// JoinSyncGroup is invoked on a SyncGroup Admin and checks if\n// the requestor can join the SyncGroup.",
+			Name: "JoinSyncGroupAtAdmin",
+			Doc:  "// JoinSyncGroupAtAdmin is invoked by a prospective SyncGroup member's\n// Syncbase on a SyncGroup admin. It checks whether the requestor is\n// allowed to join the named SyncGroup, and if so, adds the requestor to\n// the SyncGroup.",
+			InArgs: []rpc.ArgDesc{
+				{"sgName", ``},     // string
+				{"joinerName", ``}, // string
+				{"myInfo", ``},     // nosql.SyncGroupMemberInfo
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // SyncGroup
+			},
 		},
 		{
 			Name: "FetchBlob",
diff --git a/services/syncbase/server/nosql/database_sgm.go b/services/syncbase/server/nosql/database_sgm.go
index b5797b0..62c905a 100644
--- a/services/syncbase/server/nosql/database_sgm.go
+++ b/services/syncbase/server/nosql/database_sgm.go
@@ -35,7 +35,8 @@
 	if d.batchId != nil {
 		return wire.SyncGroupSpec{}, wire.NewErrBoundToBatch(ctx)
 	}
-	return wire.SyncGroupSpec{}, verror.NewErrNotImplemented(ctx)
+	sd := vsync.NewSyncDatabase(d)
+	return sd.JoinSyncGroup(ctx, call, sgName, myInfo)
 }
 
 func (d *databaseReq) LeaveSyncGroup(ctx *context.T, call rpc.ServerCall, sgName string) error {