7167: Use struct instead of map for APIConfig
[arvados.git] / sdk / go / arvadosclient / arvadosclient.go
index e43162fac7735754628246bbf33e12a2790e2133..cc99efdcf4b5deb327113780fdb8bf355163becf 100644 (file)
@@ -23,6 +23,7 @@ var PDHMatch StringMatcher = regexp.MustCompile(`^[0-9a-f]{32}\+\d+$`).MatchStri
 
 var MissingArvadosApiHost = errors.New("Missing required environment variable ARVADOS_API_HOST")
 var MissingArvadosApiToken = errors.New("Missing required environment variable ARVADOS_API_TOKEN")
+var ErrInvalidArgument = errors.New("Invalid argument")
 
 // Indicates an error that was returned by the API server.
 type APIServerError struct {
@@ -77,21 +78,42 @@ type ArvadosClient struct {
        DiscoveryDoc Dict
 }
 
-// Create a new ArvadosClient, initialized with standard Arvados environment
-// variables ARVADOS_API_HOST, ARVADOS_API_TOKEN, and (optionally)
-// ARVADOS_API_HOST_INSECURE.
+// APIConfig struct consists of:
+//    APIToken        string
+//    APIHost         string
+//    APIHostInsecure bool
+//    ExternalClient  bool
+type APIConfig struct {
+       APIToken        string
+       APIHost         string
+       APIHostInsecure bool
+       ExternalClient  bool
+}
+
+// Create a new ArvadosClient, initialized with standard Arvados environment variables
+// ARVADOS_API_HOST, ARVADOS_API_TOKEN, ARVADOS_API_HOST_INSECURE, ARVADOS_EXTERNAL_CLIENT.
 func MakeArvadosClient() (ac ArvadosClient, err error) {
+       var config APIConfig
+       config.APIToken = os.Getenv("ARVADOS_API_TOKEN")
+       config.APIHost = os.Getenv("ARVADOS_API_HOST")
+
        var matchTrue = regexp.MustCompile("^(?i:1|yes|true)$")
-       insecure := matchTrue.MatchString(os.Getenv("ARVADOS_API_HOST_INSECURE"))
-       external := matchTrue.MatchString(os.Getenv("ARVADOS_EXTERNAL_CLIENT"))
 
+       config.APIHostInsecure = matchTrue.MatchString(os.Getenv("ARVADOS_API_HOST_INSECURE"))
+       config.ExternalClient = matchTrue.MatchString(os.Getenv("ARVADOS_EXTERNAL_CLIENT"))
+
+       return MakeArvadosClientWithConfig(config)
+}
+
+// Create a new ArvadosClient, using the given input parameters.
+func MakeArvadosClientWithConfig(config APIConfig) (ac ArvadosClient, err error) {
        ac = ArvadosClient{
-               ApiServer:   os.Getenv("ARVADOS_API_HOST"),
-               ApiToken:    os.Getenv("ARVADOS_API_TOKEN"),
-               ApiInsecure: insecure,
+               ApiServer:   config.APIHost,
+               ApiToken:    config.APIToken,
+               ApiInsecure: config.APIHostInsecure,
                Client: &http.Client{Transport: &http.Transport{
-                       TLSClientConfig: &tls.Config{InsecureSkipVerify: insecure}}},
-               External: external}
+                       TLSClientConfig: &tls.Config{InsecureSkipVerify: config.APIHostInsecure}}},
+               External: config.ExternalClient}
 
        if ac.ApiServer == "" {
                return ac, MissingArvadosApiHost
@@ -247,16 +269,12 @@ func (c ArvadosClient) Update(resourceType string, uuid string, parameters Dict,
 
 // Get a resource. See Call for argument descriptions.
 func (c ArvadosClient) Get(resourceType string, uuid string, parameters Dict, output interface{}) (err error) {
-       if uuid == "" {
+       if !UUIDMatch(uuid) && !(resourceType == "collections" && PDHMatch(uuid)) {
                // No object has uuid == "": there is no need to make
                // an API call. Furthermore, the HTTP request for such
                // an API call would be "GET /arvados/v1/type/", which
                // is liable to be misinterpreted as the List API.
-               return APIServerError{
-                       ServerAddress:     c.ApiServer,
-                       HttpStatusCode:    http.StatusNotFound,
-                       HttpStatusMessage: "Not Found",
-               }
+               return ErrInvalidArgument
        }
        return c.Call("GET", resourceType, uuid, "", parameters, output)
 }
@@ -268,7 +286,10 @@ func (c ArvadosClient) List(resource string, parameters Dict, output interface{}
 
 const API_DISCOVERY_RESOURCE = "discovery/v1/apis/arvados/v1/rest"
 
-// Discovery returns the value of the given parameter in the discovery document.
+// Discovery returns the value of the given parameter in the discovery
+// document. Returns a non-nil error if the discovery document cannot
+// be retrieved/decoded. Returns ErrInvalidArgument if the requested
+// parameter is not found in the discovery document.
 func (c *ArvadosClient) Discovery(parameter string) (value interface{}, err error) {
        if len(c.DiscoveryDoc) == 0 {
                c.DiscoveryDoc = make(Dict)
@@ -283,6 +304,6 @@ func (c *ArvadosClient) Discovery(parameter string) (value interface{}, err erro
        if found {
                return value, nil
        } else {
-               return value, errors.New("Not found")
+               return value, ErrInvalidArgument
        }
 }