veyron.io/wspr/veyron/services/wsprd: wspr part of New namespace
client library that uses the native Go namespace library behind
the scene using wspr.
This CL adds features to allow JS clients to send requests asking
wspr to call specific methods on the namespace client library.
Related to:
http://go/vcl/5566
http://go/vcl/5609
Change-Id: I50e63379aeeb61ef1e5d258c7817e5693a23539d
diff --git a/services/wsprd/app/app.go b/services/wsprd/app/app.go
index c1e404a..54f49fd 100644
--- a/services/wsprd/app/app.go
+++ b/services/wsprd/app/app.go
@@ -25,6 +25,7 @@
"veyron.io/wspr/veyron/services/wsprd/identity"
"veyron.io/wspr/veyron/services/wsprd/ipc/server"
"veyron.io/wspr/veyron/services/wsprd/lib"
+ "veyron.io/wspr/veyron/services/wsprd/namespace"
"veyron.io/wspr/veyron/services/wsprd/signature"
)
@@ -689,3 +690,8 @@
return
}
}
+
+// HandleNamespaceRequest uses the namespace client to respond to namespace specific requests such as glob
+func (c *Controller) HandleNamespaceRequest(ctx context.T, data string, w lib.ClientWriter) {
+ namespace.HandleRequest(ctx, c.rt, data, w)
+}
diff --git a/services/wsprd/namespace/request_handler.go b/services/wsprd/namespace/request_handler.go
new file mode 100644
index 0000000..de1210c
--- /dev/null
+++ b/services/wsprd/namespace/request_handler.go
@@ -0,0 +1,82 @@
+package namespace
+
+import (
+ "encoding/json"
+
+ "veyron.io/veyron/veyron2"
+ "veyron.io/veyron/veyron2/context"
+ "veyron.io/veyron/veyron2/naming"
+ "veyron.io/veyron/veyron2/verror2"
+
+ "veyron.io/wspr/veyron/services/wsprd/lib"
+)
+
+// request struct represents a request to call a method on the namespace client
+type request struct {
+ Method namespaceMethod
+ Args json.RawMessage
+ Roots []string
+}
+
+type namespaceMethod int
+
+// enumerates the methods available to be called on the namespace client
+const (
+ methodGlob namespaceMethod = 0
+)
+
+// globArgs defines the args for the glob method
+type globArgs struct {
+ Pattern string
+}
+
+// handleRequest uses the namespace client to respond to namespace specific requests such as glob
+func HandleRequest(ctx context.T, rt veyron2.Runtime, data string, w lib.ClientWriter) {
+ // Decode the request
+ var req request
+ if err := json.Unmarshal([]byte(data), &req); err != nil {
+ w.Error(verror2.Convert(verror2.Internal, ctx, err))
+ return
+ }
+
+ // Create a namespace and set roots if provided
+ var ns = rt.Namespace()
+ if len(req.Roots) > 0 {
+ ns.SetRoots(req.Roots...)
+ }
+
+ switch req.Method {
+ case methodGlob:
+ glob(ctx, ns, w, req.Args)
+ default:
+ w.Error(verror2.Make(verror2.NoExist, ctx, req.Method))
+ }
+}
+
+func glob(ctx context.T, ns naming.Namespace, w lib.ClientWriter, rawArgs json.RawMessage) {
+ var args globArgs
+ if err := json.Unmarshal([]byte(rawArgs), &args); err != nil {
+ w.Error(verror2.Convert(verror2.Internal, ctx, err))
+ return
+ }
+
+ // Call glob on the namespace client instance
+ ch, err := ns.Glob(ctx, args.Pattern)
+
+ if err != nil {
+ w.Error(verror2.Convert(verror2.Internal, ctx, err))
+ return
+ }
+
+ // Send the results as streams
+ for name := range ch {
+ if err := w.Send(lib.ResponseStream, name); err != nil {
+ w.Error(verror2.Make(verror2.Internal, ctx, name))
+ return
+ }
+ }
+
+ if err := w.Send(lib.ResponseStreamClose, nil); err != nil {
+ w.Error(verror2.Make(verror2.Internal, ctx, "ResponseStreamClose"))
+ }
+}
diff --git a/services/wsprd/wspr/pipe.go b/services/wsprd/wspr/pipe.go
index 0a288c6..9841482 100644
--- a/services/wsprd/wspr/pipe.go
+++ b/services/wsprd/wspr/pipe.go
@@ -65,6 +65,9 @@
// A request to run the authorizer for an rpc.
websocketAuthResponse = 12
+
+ // A request to run a namespace client method
+ websocketNamespaceRequest = 13
)
type websocketMessage struct {
@@ -254,11 +257,12 @@
ww := p.writerCreator(msg.Id)
+ // TODO(mattr): Get the proper context information
+ // from javascript.
+ ctx := p.wspr.rt.NewContext()
+
switch msg.Type {
case websocketVeyronRequest:
- // TODO(mattr): Get the proper context information
- // from javascript.
- ctx := p.wspr.rt.NewContext()
p.controller.HandleVeyronRequest(ctx, msg.Id, msg.Data, ww)
case websocketStreamingValue:
// SendOnStream queues up the message to be sent, but doesn't do the send
@@ -274,9 +278,6 @@
case websocketServerResponse:
go p.controller.HandleServerResponse(msg.Id, msg.Data)
case websocketSignatureRequest:
- // TODO(mattr): Get the proper context information
- // from javascript.
- ctx := p.wspr.rt.NewContext()
go p.controller.HandleSignatureRequest(ctx, msg.Data, ww)
case websocketLookupResponse:
go p.controller.HandleLookupResponse(msg.Id, msg.Data)
@@ -288,6 +289,8 @@
go p.controller.HandleUnlinkJSIdentity(msg.Data, ww)
case websocketAuthResponse:
go p.controller.HandleAuthResponse(msg.Id, msg.Data)
+ case websocketNamespaceRequest:
+ go p.controller.HandleNamespaceRequest(ctx, msg.Data, ww)
default:
ww.Error(verror.Unknownf("unknown message type: %v", msg.Type))
}