Merge branch '19704-aneta-r-sdk' refs #19704
[arvados.git] / sdk / R / R / RESTService.R
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: Apache-2.0
4
5 RESTService <- R6::R6Class(
6
7     "RESTService",
8
9     public = list(
10
11         token      = NULL,
12         http       = NULL,
13         httpParser = NULL,
14         numRetries = NULL,
15
16         initialize = function(token, rawHost,
17                               http, httpParser,
18                               numRetries     = 0,
19                               webDavHostName = NULL)
20         {
21             self$token      <- token
22             self$http       <- http
23             self$httpParser <- httpParser
24             self$numRetries <- numRetries
25
26             private$rawHostName    <- rawHost
27             private$webDavHostName <- webDavHostName
28         },
29
30         setNumConnRetries = function(newNumOfRetries)
31         {
32             self$numRetries <- newNumOfRetries
33         },
34
35         getWebDavHostName = function()
36         {
37             if(is.null(private$webDavHostName))
38             {
39                 publicConfigURL <- paste0("https://", private$rawHostName,
40                                                "/arvados/v1/config")
41
42                 serverResponse <- self$http$exec("GET", publicConfigURL, retryTimes = self$numRetries)
43
44                 configDocument <- self$httpParser$parseJSONResponse(serverResponse)
45                 private$webDavHostName <- configDocument$Services$WebDAVDownload$ExternalURL
46
47                 if(is.null(private$webDavHostName))
48                     stop("Unable to find WebDAV server.")
49             }
50
51             private$webDavHostName
52         },
53
54         create = function(files, uuid)
55         {
56             sapply(files, function(filePath)
57             {
58                 private$createNewFile(filePath, uuid, "text/html")
59             })
60         },
61
62         delete = function(relativePath, uuid)
63         {
64             fileURL <- paste0(self$getWebDavHostName(), "c=",
65                               uuid, "/", relativePath);
66             headers <- list(Authorization = paste("OAuth2", self$token))
67
68             serverResponse <- self$http$exec("DELETE", fileURL, headers,
69                                              retryTimes = self$numRetries)
70
71             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
72                 stop(paste("Server code:", serverResponse$status_code))
73
74             serverResponse
75         },
76
77         move = function(from, to, uuid)
78         {
79             collectionURL <- paste0(self$getWebDavHostName(), "c=", uuid, "/")
80             fromURL <- paste0(collectionURL, from)
81             toURL <- paste0(collectionURL, trimFromStart(to, "/"))
82
83             headers <- list("Authorization" = paste("OAuth2", self$token),
84                             "Destination" = toURL)
85
86             serverResponse <- self$http$exec("MOVE", fromURL, headers,
87                                              retryTimes = self$numRetries)
88
89             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
90                 stop(paste("Server code:", serverResponse$status_code))
91
92             serverResponse
93         },
94
95         copy = function(from, to, uuid)
96         {
97             collectionURL <- paste0(self$getWebDavHostName(), "c=", uuid, "/")
98             fromURL <- paste0(collectionURL, from)
99             toURL <- paste0(collectionURL, trimFromStart(to, "/"))
100
101             headers <- list("Authorization" = paste("OAuth2", self$token),
102                             "Destination" = toURL)
103
104             serverResponse <- self$http$exec("COPY", fromURL, headers,
105                                              retryTimes = self$numRetries)
106
107             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
108                 stop(paste("Server code:", serverResponse$status_code))
109
110             serverResponse
111         },
112
113        getCollectionContent = function(uuid, relativePath = NULL)
114
115         {
116             collectionURL <- URLencode(paste0(self$getWebDavHostName(),
117                                              "c=", uuid, "/", relativePath))
118
119             headers <- list("Authorization" = paste("Bearer", self$token))
120
121             response <- self$http$exec("PROPFIND", collectionURL, headers,
122                                        retryTimes = self$numRetries)
123
124             if(all(response == ""))
125                 stop("Response is empty, request may be misconfigured")
126
127             if(response$status_code < 200 || response$status_code >= 300)
128                 stop(paste("Server code:", response$status_code))
129
130             self$httpParser$getFileNamesFromResponse(response, collectionURL)
131         },
132
133         getResourceSize = function(relativePath, uuid)
134         {
135             collectionURL <- URLencode(paste0(self$getWebDavHostName(),
136                                               "c=", uuid))
137
138             subcollectionURL <- paste0(collectionURL, "/", relativePath);
139
140             headers <- list("Authorization" = paste("OAuth2", self$token))
141
142             response <- self$http$exec("PROPFIND", subcollectionURL, headers,
143                                        retryTimes = self$numRetries)
144
145             if(all(response == ""))
146                 stop("Response is empty, request may be misconfigured")
147
148             if(response$status_code < 200 || response$status_code >= 300)
149                 stop(paste("Server code:", response$status_code))
150
151             sizes <- self$httpParser$getFileSizesFromResponse(response,
152                                                               collectionURL)
153             as.numeric(sizes)
154         },
155
156         read = function(relativePath, uuid, contentType = "raw", offset = 0, length = 0)
157         {
158             fileURL <- paste0(self$getWebDavHostName(),
159                              "c=", uuid, "/", relativePath);
160
161             range <- paste0("bytes=", offset, "-")
162
163             if(length > 0)
164                 range = paste0(range, offset + length - 1)
165
166             if(offset == 0 && length == 0)
167             {
168                 headers <- list(Authorization = paste("OAuth2", self$token))
169             }
170             else
171             {
172                 headers <- list(Authorization = paste("OAuth2", self$token),
173                                 Range = range)
174             }
175
176             if(!(contentType %in% self$httpParser$validContentTypes))
177                 stop("Invalid contentType. Please use text or raw.")
178
179             serverResponse <- self$http$exec("GET", fileURL, headers,
180                                              retryTimes = self$numRetries)
181
182             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
183                 stop(paste("Server code:", serverResponse$status_code))
184
185             self$httpParser$parseResponse(serverResponse, contentType)
186         },
187
188         write = function(relativePath, uuid, content, contentType)
189         {
190             fileURL <- paste0(self$getWebDavHostName(),
191                              "c=", uuid, "/", relativePath);
192             headers <- list(Authorization = paste("OAuth2", self$token),
193                             "Content-Type" = contentType)
194             body <- content
195
196             serverResponse <- self$http$exec("PUT", fileURL, headers, body,
197                                              retryTimes = self$numRetries)
198
199             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
200                 stop(paste("Server code:", serverResponse$status_code))
201
202             self$httpParser$parseResponse(serverResponse, "text")
203         },
204
205         getConnection = function(relativePath, uuid, openMode)
206         {
207             fileURL <- paste0(self$getWebDavHostName(),
208                               "c=", uuid, "/", relativePath);
209             headers <- list(Authorization = paste("OAuth2", self$token))
210
211             conn <- self$http$getConnection(fileURL, headers, openMode)
212         }
213     ),
214
215     private = list(
216
217         webDavHostName = NULL,
218         rawHostName    = NULL,
219
220         createNewFile = function(relativePath, uuid, contentType)
221         {
222             fileURL <- paste0(self$getWebDavHostName(), "c=",
223                               uuid, "/", relativePath)
224             headers <- list(Authorization = paste("OAuth2", self$token),
225                             "Content-Type" = contentType)
226             body <- NULL
227
228             serverResponse <- self$http$exec("PUT", fileURL, headers, body,
229                                              retryTimes = self$numRetries)
230
231             if (serverResponse$status_code < 200){ # to wyrzuca błędy
232                 stop(paste("Server code:", serverResponse$status_code))}
233             else if (serverResponse$status_code >= 300 & serverResponse$status_code < 422) {
234                 stop(paste("Server code:", serverResponse$status_code))}
235             else if (serverResponse$status_code == 422 ) {
236                 stop(paste("Project of that name already exists. If you want to change it use project_update() instead"))}
237
238             paste("File created:", relativePath)
239         }
240     ),
241
242     cloneable = FALSE
243 )