16306: Merge branch 'master'
[arvados.git] / sdk / R / R / RESTService.R
index 6ffd34bc26bd3f8a56b8b3e92a57cca6e4a94864..9c65e72861f41513936e431afda50f6ab443f983 100644 (file)
@@ -1,14 +1,54 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+
 RESTService <- R6::R6Class(
 
     "RESTService",
 
     public = list(
 
-        initialize = function(api)
+        token      = NULL,
+        http       = NULL,
+        httpParser = NULL,
+        numRetries = NULL,
+
+        initialize = function(token, rawHost,
+                              http, httpParser,
+                              numRetries     = 0,
+                              webDavHostName = NULL)
+        {
+            self$token      <- token
+            self$http       <- http
+            self$httpParser <- httpParser
+            self$numRetries <- numRetries
+
+            private$rawHostName    <- rawHost
+            private$webDavHostName <- webDavHostName
+        },
+
+        setNumConnRetries = function(newNumOfRetries)
         {
-            private$api <- api
-            private$http <- api$getHttpClient()
-            private$httpParser <- api$getHttpParser()
+            self$numRetries <- newNumOfRetries
+        },
+
+        getWebDavHostName = function()
+        {
+            if(is.null(private$webDavHostName))
+            {
+                publicConfigURL <- paste0("https://", private$rawHostName,
+                                               "/arvados/v1/config")
+
+                serverResponse <- self$http$exec("GET", publicConfigURL, retryTimes = self$numRetries)
+
+                configDocument <- self$httpParser$parseJSONResponse(serverResponse)
+                private$webDavHostName <- configDocument$Services$WebDAVDownload$ExternalURL
+
+                if(is.null(private$webDavHostName))
+                    stop("Unable to find WebDAV server.")
+            }
+
+            private$webDavHostName
         },
 
         create = function(files, uuid)
@@ -21,28 +61,48 @@ RESTService <- R6::R6Class(
 
         delete = function(relativePath, uuid)
         {
-            fileURL <- paste0(private$api$getWebDavHostName(), "c=",
+            fileURL <- paste0(self$getWebDavHostName(), "c=",
                               uuid, "/", relativePath);
-            headers <- list(Authorization = paste("OAuth2", private$api$getToken())) 
+            headers <- list(Authorization = paste("OAuth2", self$token))
 
-            serverResponse <- private$http$DELETE(fileURL, headers)
+            serverResponse <- self$http$exec("DELETE", fileURL, headers,
+                                             retryTimes = self$numRetries)
 
             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
                 stop(paste("Server code:", serverResponse$status_code))
 
-            paste("File deleted:", relativePath)
+            serverResponse
         },
 
         move = function(from, to, uuid)
         {
-            collectionURL <- paste0(private$api$getWebDavHostName(), "c=", uuid, "/")
+            collectionURL <- paste0(self$getWebDavHostName(), "c=", uuid, "/")
+            fromURL <- paste0(collectionURL, from)
+            toURL <- paste0(collectionURL, trimFromStart(to, "/"))
+
+            headers <- list("Authorization" = paste("OAuth2", self$token),
+                            "Destination" = toURL)
+
+            serverResponse <- self$http$exec("MOVE", fromURL, headers,
+                                             retryTimes = self$numRetries)
+
+            if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
+                stop(paste("Server code:", serverResponse$status_code))
+
+            serverResponse
+        },
+
+        copy = function(from, to, uuid)
+        {
+            collectionURL <- paste0(self$getWebDavHostName(), "c=", uuid, "/")
             fromURL <- paste0(collectionURL, from)
-            toURL <- paste0(collectionURL, to)
+            toURL <- paste0(collectionURL, trimFromStart(to, "/"))
 
-            headers <- list("Authorization" = paste("OAuth2", private$api$getToken()),
-                           "Destination" = toURL)
+            headers <- list("Authorization" = paste("OAuth2", self$token),
+                            "Destination" = toURL)
 
-            serverResponse <- private$http$MOVE(fromURL, headers)
+            serverResponse <- self$http$exec("COPY", fromURL, headers,
+                                             retryTimes = self$numRetries)
 
             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
                 stop(paste("Server code:", serverResponse$status_code))
@@ -52,42 +112,49 @@ RESTService <- R6::R6Class(
 
         getCollectionContent = function(uuid)
         {
-            collectionURL <- URLencode(paste0(private$api$getWebDavHostName(),
+            collectionURL <- URLencode(paste0(self$getWebDavHostName(),
                                               "c=", uuid))
 
-            headers <- list("Authorization" = paste("OAuth2", private$api$getToken()))
+            headers <- list("Authorization" = paste("Bearer", self$token))
 
-            response <- private$http$PROPFIND(collectionURL, headers)
+            response <- self$http$exec("PROPFIND", collectionURL, headers,
+                                       retryTimes = self$numRetries)
 
             if(all(response == ""))
                 stop("Response is empty, request may be misconfigured")
 
-            private$httpParser$getFileNamesFromResponse(response, collectionURL)
+            if(response$status_code < 200 || response$status_code >= 300)
+                stop(paste("Server code:", response$status_code))
+
+            self$httpParser$getFileNamesFromResponse(response, collectionURL)
         },
 
         getResourceSize = function(relativePath, uuid)
         {
-            collectionURL <- URLencode(paste0(private$api$getWebDavHostName(),
+            collectionURL <- URLencode(paste0(self$getWebDavHostName(),
                                               "c=", uuid))
 
             subcollectionURL <- paste0(collectionURL, "/", relativePath);
 
-            headers <- list("Authorization" = paste("OAuth2",
-                                                   private$api$getToken()))
+            headers <- list("Authorization" = paste("OAuth2", self$token))
 
-            response <- private$http$PROPFIND(subcollectionURL, headers)
+            response <- self$http$exec("PROPFIND", subcollectionURL, headers,
+                                       retryTimes = self$numRetries)
 
             if(all(response == ""))
                 stop("Response is empty, request may be misconfigured")
 
-            sizes <- private$httpParser$getFileSizesFromResponse(response,
-                                                             collectionURL)
+            if(response$status_code < 200 || response$status_code >= 300)
+                stop(paste("Server code:", response$status_code))
+
+            sizes <- self$httpParser$getFileSizesFromResponse(response,
+                                                              collectionURL)
             as.numeric(sizes)
         },
 
         read = function(relativePath, uuid, contentType = "raw", offset = 0, length = 0)
         {
-            fileURL <- paste0(private$api$getWebDavHostName(),
+            fileURL <- paste0(self$getWebDavHostName(),
                              "c=", uuid, "/", relativePath);
 
             range <- paste0("bytes=", offset, "-")
@@ -97,57 +164,68 @@ RESTService <- R6::R6Class(
 
             if(offset == 0 && length == 0)
             {
-                headers <- list(Authorization = paste("OAuth2", private$api$getToken()))
+                headers <- list(Authorization = paste("OAuth2", self$token))
             }
             else
             {
-                headers <- list(Authorization = paste("OAuth2", private$api$getToken()),
+                headers <- list(Authorization = paste("OAuth2", self$token),
                                 Range = range)
             }
 
-            if(!(contentType %in% private$httpParser$validContentTypes))
+            if(!(contentType %in% self$httpParser$validContentTypes))
                 stop("Invalid contentType. Please use text or raw.")
 
-            serverResponse <- private$http$GET(fileURL, headers)
+            serverResponse <- self$http$exec("GET", fileURL, headers,
+                                             retryTimes = self$numRetries)
 
             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
                 stop(paste("Server code:", serverResponse$status_code))
 
-            private$httpParser$parseResponse(serverResponse, contentType)
+            self$httpParser$parseResponse(serverResponse, contentType)
         },
 
         write = function(relativePath, uuid, content, contentType)
         {
-            fileURL <- paste0(private$api$getWebDavHostName(),
+            fileURL <- paste0(self$getWebDavHostName(),
                              "c=", uuid, "/", relativePath);
-            headers <- list(Authorization = paste("OAuth2", private$api$getToken()),
+            headers <- list(Authorization = paste("OAuth2", self$token),
                             "Content-Type" = contentType)
             body <- content
 
-            serverResponse <- private$http$PUT(fileURL, headers, body)
+            serverResponse <- self$http$exec("PUT", fileURL, headers, body,
+                                             retryTimes = self$numRetries)
 
             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
                 stop(paste("Server code:", serverResponse$status_code))
 
-            private$httpParser$parseResponse(serverResponse, "text")
+            self$httpParser$parseResponse(serverResponse, "text")
+        },
+
+        getConnection = function(relativePath, uuid, openMode)
+        {
+            fileURL <- paste0(self$getWebDavHostName(),
+                              "c=", uuid, "/", relativePath);
+            headers <- list(Authorization = paste("OAuth2", self$token))
+
+            conn <- self$http$getConnection(fileURL, headers, openMode)
         }
     ),
 
     private = list(
 
-        api        = NULL,
-        http       = NULL,
-        httpParser = NULL,
+        webDavHostName = NULL,
+        rawHostName    = NULL,
 
         createNewFile = function(relativePath, uuid, contentType)
         {
-            fileURL <- paste0(private$api$getWebDavHostName(), "c=",
-                              uuid, "/", relativePath);
-            headers <- list(Authorization = paste("OAuth2", private$api$getToken()), 
+            fileURL <- paste0(self$getWebDavHostName(), "c=",
+                              uuid, "/", relativePath)
+            headers <- list(Authorization = paste("OAuth2", self$token),
                             "Content-Type" = contentType)
             body <- NULL
 
-            serverResponse <- private$http$PUT(fileURL, headers, body)
+            serverResponse <- self$http$exec("PUT", fileURL, headers, body,
+                                             retryTimes = self$numRetries)
 
             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
                 stop(paste("Server code:", serverResponse$status_code))