Merge pull request #2 from wtsi-hgi/feature/arv-view
[arvados.git] / sdk / go / keepclient / support.go
index 940a110081dbaa46920cb472ea09d9e0635fd219..b467d06b21ed91ecaa06b1537ae30a6cddcb6ce2 100644 (file)
@@ -1,4 +1,3 @@
-/* Internal methods to support keepclient.go */
 package keepclient
 
 import (
@@ -21,6 +20,7 @@ type keepDisk struct {
        Port     int    `json:"service_port"`
        SSL      bool   `json:"service_ssl_flag"`
        SvcType  string `json:"service_type"`
+       ReadOnly bool   `json:"read_only"`
 }
 
 func Md5String(s string) string {
@@ -76,7 +76,7 @@ func (this *KeepClient) setClientSettingsStore() {
        }
 }
 
-func (this *KeepClient) DiscoverKeepServers() (map[string]string, error) {
+func (this *KeepClient) DiscoverKeepServers() error {
        type svcList struct {
                Items []keepDisk `json:"items"`
        }
@@ -86,31 +86,46 @@ func (this *KeepClient) DiscoverKeepServers() (map[string]string, error) {
 
        if err != nil {
                if err := this.Arvados.List("keep_disks", nil, &m); err != nil {
-                       return nil, err
+                       return err
                }
        }
 
        listed := make(map[string]bool)
-       service_roots := make(map[string]string)
-
-       for _, element := range m.Items {
-               n := ""
-
-               if element.SSL {
-                       n = "s"
+       localRoots := make(map[string]string)
+       gatewayRoots := make(map[string]string)
+       writableLocalRoots := make(map[string]string)
+
+       for _, service := range m.Items {
+               scheme := "http"
+               if service.SSL {
+                       scheme = "https"
                }
-
-               // Construct server URL
-               url := fmt.Sprintf("http%s://%s:%d", n, element.Hostname, element.Port)
+               url := fmt.Sprintf("%s://%s:%d", scheme, service.Hostname, service.Port)
 
                // Skip duplicates
-               if !listed[url] {
-                       listed[url] = true
-                       service_roots[element.Uuid] = url
+               if listed[url] {
+                       continue
                }
-               if element.SvcType == "proxy" {
+               listed[url] = true
+
+               switch service.SvcType {
+               case "disk":
+                       localRoots[service.Uuid] = url
+               case "proxy":
+                       localRoots[service.Uuid] = url
                        this.Using_proxy = true
                }
+
+               if service.ReadOnly == false {
+                       writableLocalRoots[service.Uuid] = url
+               }
+
+               // Gateway services are only used when specified by
+               // UUID, so there's nothing to gain by filtering them
+               // by service type. Including all accessible services
+               // (gateway and otherwise) merely accommodates more
+               // service configurations.
+               gatewayRoots[service.Uuid] = url
        }
 
        if this.Using_proxy {
@@ -119,9 +134,8 @@ func (this *KeepClient) DiscoverKeepServers() (map[string]string, error) {
                this.setClientSettingsStore()
        }
 
-       this.SetServiceRoots(service_roots)
-
-       return service_roots, nil
+       this.SetServiceRoots(localRoots, writableLocalRoots, gatewayRoots)
+       return nil
 }
 
 type uploadStatus struct {
@@ -204,7 +218,7 @@ func (this KeepClient) putReplicas(
        requestId := fmt.Sprintf("%x", md5.Sum([]byte(locator+time.Now().String())))[0:8]
 
        // Calculate the ordering for uploading to servers
-       sv := NewRootSorter(this.ServiceRoots(), hash).GetSortedRoots()
+       sv := NewRootSorter(this.WritableLocalRoots(), hash).GetSortedRoots()
 
        // The next server to try contacting
        next_server := 0