blob: a6127cd1c6a6bdb6a3b8df4c433c328a181d0ca8 [file] [log] [blame]
Adam Sadovskyb85e3532015-04-08 20:38:27 -07001// Copyright 2015 The Vanadium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Adam Sadovskyb85e3532015-04-08 20:38:27 -07005package server
6
7import (
8 "strings"
9
Adam Sadovskyf3b7abc2015-05-04 15:33:22 -070010 wire "v.io/syncbase/v23/services/syncbase"
11 "v.io/syncbase/x/ref/services/syncbase/server/nosql"
12 "v.io/syncbase/x/ref/services/syncbase/server/util"
Adam Sadovskyb85e3532015-04-08 20:38:27 -070013 "v.io/v23/rpc"
14 "v.io/v23/security"
15 "v.io/v23/verror"
16)
17
18type dispatcher struct {
19 s *service
20}
21
22var _ rpc.Dispatcher = (*dispatcher)(nil)
23
24func NewDispatcher(s *service) *dispatcher {
25 return &dispatcher{s: s}
26}
27
28// TODO(sadovsky): Return a real authorizer in various places below.
Adam Sadovskyf3b7abc2015-05-04 15:33:22 -070029func (disp *dispatcher) Lookup(suffix string) (interface{}, security.Authorizer, error) {
Adam Sadovskyb85e3532015-04-08 20:38:27 -070030 suffix = strings.TrimPrefix(suffix, "/")
Adam Sadovskyf3b7abc2015-05-04 15:33:22 -070031 parts := strings.SplitN(suffix, "/", 2)
32
33 if len(suffix) == 0 {
34 return wire.ServiceServer(disp.s), nil, nil
35 }
Adam Sadovskyb85e3532015-04-08 20:38:27 -070036
37 // Validate all key atoms up front, so that we can avoid doing so in all our
38 // method implementations.
Adam Sadovskyf3b7abc2015-05-04 15:33:22 -070039 appName := parts[0]
40 if !util.ValidKeyAtom(appName) {
41 return nil, nil, wire.NewErrInvalidName(nil, suffix)
42 }
43
44 aExists := false
45 a, err := disp.s.app(nil, nil, appName)
46 if err == nil {
47 aExists = true
48 } else {
49 if verror.ErrorID(err) != verror.ErrNoExistOrNoAccess.ID {
50 return nil, nil, err
51 } else {
52 a = &app{
53 name: appName,
54 s: disp.s,
55 }
Adam Sadovskyb85e3532015-04-08 20:38:27 -070056 }
57 }
58
Adam Sadovskyb85e3532015-04-08 20:38:27 -070059 if len(parts) == 1 {
Adam Sadovskyf3b7abc2015-05-04 15:33:22 -070060 return wire.AppServer(a), nil, nil
Adam Sadovskyb85e3532015-04-08 20:38:27 -070061 }
62
Adam Sadovskyf3b7abc2015-05-04 15:33:22 -070063 // All database, table, and row methods require the app to exist. If it
64 // doesn't, abort early.
65 if !aExists {
66 return nil, nil, verror.New(verror.ErrNoExistOrNoAccess, nil, a.name)
Adam Sadovskyb85e3532015-04-08 20:38:27 -070067 }
68
Adam Sadovskyf3b7abc2015-05-04 15:33:22 -070069 // Note, it's possible for the app to be deleted concurrently with downstream
70 // handling of this request. Depending on the order in which things execute,
71 // the client may not get an error, but in any case ultimately the store will
72 // end up in a consistent state.
73 return nosql.NewDispatcher(a).Lookup(parts[1])
Adam Sadovskyb85e3532015-04-08 20:38:27 -070074}