14287: Handle collection/.../provenance and .../used_by requests.
authorTom Clegg <tclegg@veritasgenetics.com>
Tue, 14 May 2019 15:20:49 +0000 (11:20 -0400)
committerTom Clegg <tclegg@veritasgenetics.com>
Mon, 17 Jun 2019 13:54:39 +0000 (09:54 -0400)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg@veritasgenetics.com>

lib/controller/federation/conn.go
lib/controller/router/response.go
lib/controller/router/router.go
lib/controller/rpc/conn.go
sdk/go/arvados/api.go

index 6d0e29d4ab1d5c16923e2d650ddcc29a2e86a095..79e38889463a2c9ce4207657e535ca4984da299e 100644 (file)
@@ -26,6 +26,8 @@ type Interface interface {
        CollectionUpdate(ctx context.Context, options arvados.UpdateOptions) (arvados.Collection, error)
        CollectionGet(ctx context.Context, options arvados.GetOptions) (arvados.Collection, error)
        CollectionList(ctx context.Context, options arvados.ListOptions) (arvados.CollectionList, error)
+       CollectionProvenance(ctx context.Context, options arvados.GetOptions) (map[string]interface{}, error)
+       CollectionUsedBy(ctx context.Context, options arvados.GetOptions) (map[string]interface{}, error)
        CollectionDelete(ctx context.Context, options arvados.DeleteOptions) (arvados.Collection, error)
        ContainerCreate(ctx context.Context, options arvados.CreateOptions) (arvados.Container, error)
        ContainerUpdate(ctx context.Context, options arvados.UpdateOptions) (arvados.Container, error)
@@ -240,6 +242,14 @@ func (conn *Conn) CollectionList(ctx context.Context, options arvados.ListOption
        return conn.local.CollectionList(ctx, options)
 }
 
+func (conn *Conn) CollectionProvenance(ctx context.Context, options arvados.GetOptions) (map[string]interface{}, error) {
+       return conn.local.CollectionProvenance(ctx, options)
+}
+
+func (conn *Conn) CollectionUsedBy(ctx context.Context, options arvados.GetOptions) (map[string]interface{}, error) {
+       return conn.local.CollectionUsedBy(ctx, options)
+}
+
 func (conn *Conn) CollectionDelete(ctx context.Context, options arvados.DeleteOptions) (arvados.Collection, error) {
        return conn.chooseBackend(options.UUID).CollectionDelete(ctx, options)
 }
index 82ca5ef5e61d87157dccfeb855b582023b7d187e..3eba6114503d637dcce8236c6ffa6e74af56bc36 100644 (file)
@@ -53,15 +53,19 @@ func applySelectParam(selectParam []string, orig map[string]interface{}) map[str
 }
 
 func (rtr *router) sendResponse(w http.ResponseWriter, resp interface{}, opts responseOptions) {
-       respKind := kind(resp)
        var tmp map[string]interface{}
+
        err := rtr.transcode(resp, &tmp)
        if err != nil {
                rtr.sendError(w, err)
                return
        }
 
-       tmp["kind"] = respKind
+       respKind := kind(resp)
+       if respKind != "" {
+               tmp["kind"] = respKind
+       }
+
        if items, ok := tmp["items"].([]interface{}); ok {
                for i, item := range items {
                        // Fill in "kind" by inspecting UUID
@@ -71,8 +75,8 @@ func (rtr *router) sendResponse(w http.ResponseWriter, resp interface{}, opts re
                                // unsure whether this happens
                        } else if t, ok := infixMap[uuid[6:11]]; !ok {
                                // infix not listed in infixMap
-                       } else {
-                               item["kind"] = kind(t)
+                       } else if k := kind(t); k != "" {
+                               item["kind"] = k
                        }
                        items[i] = applySelectParam(opts.Select, item)
                }
@@ -125,7 +129,11 @@ var infixMap = map[string]interface{}{
 var mungeKind = regexp.MustCompile(`\..`)
 
 func kind(resp interface{}) string {
-       return mungeKind.ReplaceAllStringFunc(fmt.Sprintf("%T", resp), func(s string) string {
+       t := fmt.Sprintf("%T", resp)
+       if !strings.HasPrefix(t, "arvados.") {
+               return ""
+       }
+       return mungeKind.ReplaceAllStringFunc(t, func(s string) string {
                // "arvados.CollectionList" => "arvados#collectionList"
                return "#" + strings.ToLower(s[1:])
        })
index faebbf754ed0ed5191c75b9a15ad692095b07300..ebfd44e5f3c9cc132f6eba3014852e7209b16fe3 100644 (file)
@@ -63,6 +63,20 @@ func (rtr *router) addRoutes(cluster *arvados.Cluster) {
                                return rtr.fed.CollectionList(ctx, *opts.(*arvados.ListOptions))
                        },
                },
+               {
+                       arvados.EndpointCollectionProvenance,
+                       func() interface{} { return &arvados.GetOptions{} },
+                       func(ctx context.Context, opts interface{}) (interface{}, error) {
+                               return rtr.fed.CollectionProvenance(ctx, *opts.(*arvados.GetOptions))
+                       },
+               },
+               {
+                       arvados.EndpointCollectionUsedBy,
+                       func() interface{} { return &arvados.GetOptions{} },
+                       func(ctx context.Context, opts interface{}) (interface{}, error) {
+                               return rtr.fed.CollectionUsedBy(ctx, *opts.(*arvados.GetOptions))
+                       },
+               },
                {
                        arvados.EndpointCollectionDelete,
                        func() interface{} { return &arvados.DeleteOptions{} },
index 9bb3eb33fb72d17aab6bbee1c54706c254b9b58a..e74e870ad0856d256d6a3b757a06d588b0370d7f 100644 (file)
@@ -140,6 +140,20 @@ func (conn *Conn) CollectionList(ctx context.Context, options arvados.ListOption
        return resp, err
 }
 
+func (conn *Conn) CollectionProvenance(ctx context.Context, options arvados.GetOptions) (map[string]interface{}, error) {
+       ep := arvados.EndpointCollectionProvenance
+       var resp map[string]interface{}
+       err := conn.requestAndDecode(ctx, &resp, ep, nil, options)
+       return resp, err
+}
+
+func (conn *Conn) CollectionUsedBy(ctx context.Context, options arvados.GetOptions) (map[string]interface{}, error) {
+       ep := arvados.EndpointCollectionUsedBy
+       var resp map[string]interface{}
+       err := conn.requestAndDecode(ctx, &resp, ep, nil, options)
+       return resp, err
+}
+
 func (conn *Conn) CollectionDelete(ctx context.Context, options arvados.DeleteOptions) (arvados.Collection, error) {
        ep := arvados.EndpointCollectionDelete
        var resp arvados.Collection
index 84f73c5a22fdb2b38b66a7166868c38837577308..874e9e517e867ae1ad7a79b17c9eb9f877baf14f 100644 (file)
@@ -16,6 +16,8 @@ var (
        EndpointCollectionUpdate              = APIEndpoint{"PATCH", "arvados/v1/collections/:uuid", "collection"}
        EndpointCollectionGet                 = APIEndpoint{"GET", "arvados/v1/collections/:uuid", ""}
        EndpointCollectionList                = APIEndpoint{"GET", "arvados/v1/collections", ""}
+       EndpointCollectionProvenance          = APIEndpoint{"GET", "arvados/v1/collections/:uuid/provenance", ""}
+       EndpointCollectionUsedBy              = APIEndpoint{"GET", "arvados/v1/collections/:uuid/used_by", ""}
        EndpointCollectionDelete              = APIEndpoint{"DELETE", "arvados/v1/collections/:uuid", ""}
        EndpointSpecimenCreate                = APIEndpoint{"POST", "arvados/v1/specimens", "specimen"}
        EndpointSpecimenUpdate                = APIEndpoint{"PATCH", "arvados/v1/specimens/:uuid", "specimen"}