Replaced README with README.Rmd
[arvados.git] / sdk / R / R / RESTService.R
1 RESTService <- R6::R6Class(
2
3     "RESTService",
4
5     public = list(
6
7         hostName   = NULL,
8         token      = NULL,
9         http       = NULL,
10         httpParser = NULL,
11         numRetries = NULL,
12
13         initialize = function(token, hostName,
14                               http, httpParser,
15                               numRetries     = 0,
16                               webDavHostName = NULL)
17         {
18             version <- "v1"
19
20             self$token       <- token
21             self$hostName    <- paste0("https://", hostName,
22                                        "/arvados/", version, "/")
23             self$http        <- http
24             self$httpParser  <- httpParser
25             self$numRetries  <- numRetries
26
27             private$rawHostName    <- hostName
28             private$webDavHostName <- webDavHostName
29         },
30
31         setNumConnRetries = function(newNumOfRetries)
32         {
33             self$numRetries <- newNumOfRetries
34         },
35
36         getWebDavHostName = function()
37         {
38             if(is.null(private$webDavHostName))
39             {
40                 discoveryDocumentURL <- paste0("https://", private$rawHostName,
41                                                "/discovery/v1/apis/arvados/v1/rest")
42
43                 headers <- list(Authorization = paste("OAuth2", self$token))
44
45                 serverResponse <- self$http$execute("GET", discoveryDocumentURL, headers,
46                                                     retryTimes = self$numRetries)
47
48                 discoveryDocument <- self$httpParser$parseJSONResponse(serverResponse)
49                 private$webDavHostName <- discoveryDocument$keepWebServiceUrl
50
51                 if(is.null(private$webDavHostName))
52                     stop("Unable to find WebDAV server.")
53             }
54
55             private$webDavHostName
56         },
57
58         getResource = function(resource, uuid)
59         {
60             resourceURL <- paste0(self$hostName, resource, "/", uuid)
61             headers <- list(Authorization = paste("OAuth2", self$token))
62
63             serverResponse <- self$http$execute("GET", resourceURL, headers,
64                                                 retryTimes = self$numRetries)
65
66             resource <- self$httpParser$parseJSONResponse(serverResponse)
67
68             if(!is.null(resource$errors))
69                 stop(resource$errors)
70
71             resource
72         },
73
74         listResources = function(resource, filters = NULL, limit = 100, offset = 0)
75         {
76             resourceURL <- paste0(self$hostName, resource)
77             headers <- list(Authorization = paste("OAuth2", self$token))
78             body <- NULL
79
80             serverResponse <- self$http$execute("GET", resourceURL, headers, body,
81                                                 filters, limit, offset,
82                                                 self$numRetries)
83
84             resources <- self$httpParser$parseJSONResponse(serverResponse)
85
86             if(!is.null(resources$errors))
87                 stop(resources$errors)
88
89             resources
90         },
91
92         fetchAllItems = function(resourceURL, filters)
93         {
94             headers <- list(Authorization = paste("OAuth2", self$token))
95
96             offset <- 0
97             itemsAvailable <- .Machine$integer.max
98             items <- c()
99             while(length(items) < itemsAvailable)
100             {
101                 serverResponse <- self$http$execute(verb       = "GET",
102                                                     url        = resourceURL,
103                                                     headers    = headers,
104                                                     body       = NULL,
105                                                     query      = filters,
106                                                     limit      = NULL,
107                                                     offset     = offset,
108                                                     retryTimes = self$numRetries)
109
110                 parsedResponse <- self$httpParser$parseJSONResponse(serverResponse)
111
112                 if(!is.null(parsedResponse$errors))
113                     stop(parsedResponse$errors)
114
115                 items          <- c(items, parsedResponse$items)
116                 offset         <- length(items)
117                 itemsAvailable <- parsedResponse$items_available
118             }
119
120             items
121         },
122
123         deleteResource = function(resource, uuid)
124         {
125             collectionURL <- paste0(self$hostName, resource, "/", uuid)
126             headers <- list("Authorization" = paste("OAuth2", self$token),
127                             "Content-Type"  = "application/json")
128
129             serverResponse <- self$http$execute("DELETE", collectionURL, headers,
130                                                 retryTimes = self$numRetries)
131
132             removedResource <- self$httpParser$parseJSONResponse(serverResponse)
133
134             if(!is.null(removedResource$errors))
135                 stop(removedResource$errors)
136
137             removedResource
138         },
139
140         updateResource = function(resource, uuid, newContent)
141         {
142             resourceURL <- paste0(self$hostName, resource, "/", uuid)
143             headers <- list("Authorization" = paste("OAuth2", self$token),
144                             "Content-Type"  = "application/json")
145
146             newContent <- jsonlite::toJSON(newContent, auto_unbox = T)
147
148             serverResponse <- self$http$execute("PUT", resourceURL, headers, newContent,
149                                                 retryTimes = self$numRetries)
150
151             updatedResource <- self$httpParser$parseJSONResponse(serverResponse)
152
153             if(!is.null(updatedResource$errors))
154                 stop(updatedResource$errors)
155
156             updatedResource
157         },
158
159         createResource = function(resource, content)
160         {
161             resourceURL <- paste0(self$hostName, resource)
162             headers <- list("Authorization" = paste("OAuth2", self$token),
163                             "Content-Type"  = "application/json")
164
165             content <- jsonlite::toJSON(content, auto_unbox = T)
166
167             serverResponse <- self$http$execute("POST", resourceURL, headers, content,
168                                                 retryTimes = self$numRetries)
169
170             newResource <- self$httpParser$parseJSONResponse(serverResponse)
171
172             if(!is.null(newResource$errors))
173                 stop(newResource$errors)
174
175             newResource
176         },
177
178         create = function(files, uuid)
179         {
180             sapply(files, function(filePath)
181             {
182                 private$createNewFile(filePath, uuid, "text/html")
183             })
184         },
185
186         delete = function(relativePath, uuid)
187         {
188             fileURL <- paste0(self$getWebDavHostName(), "c=",
189                               uuid, "/", relativePath);
190             headers <- list(Authorization = paste("OAuth2", self$token)) 
191
192             serverResponse <- self$http$execute("DELETE", fileURL, headers,
193                                                 retryTimes = self$numRetries)
194
195             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
196                 stop(paste("Server code:", serverResponse$status_code))
197
198             serverResponse
199         },
200
201         move = function(from, to, uuid)
202         {
203             collectionURL <- paste0(self$getWebDavHostName(), "c=", uuid, "/")
204             fromURL <- paste0(collectionURL, from)
205             toURL <- paste0(collectionURL, to)
206
207             headers <- list("Authorization" = paste("OAuth2", self$token),
208                            "Destination" = toURL)
209
210             serverResponse <- self$http$execute("MOVE", fromURL, headers,
211                                                 retryTimes = self$numRetries)
212
213             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
214                 stop(paste("Server code:", serverResponse$status_code))
215
216             serverResponse
217         },
218
219         getCollectionContent = function(uuid)
220         {
221             collectionURL <- URLencode(paste0(self$getWebDavHostName(),
222                                               "c=", uuid))
223
224             headers <- list("Authorization" = paste("OAuth2", self$token))
225
226             response <- self$http$execute("PROPFIND", collectionURL, headers,
227                                           retryTimes = self$numRetries)
228
229             if(all(response == ""))
230                 stop("Response is empty, request may be misconfigured")
231
232             if(response$status_code < 200 || response$status_code >= 300)
233                 stop(paste("Server code:", response$status_code))
234
235             self$httpParser$getFileNamesFromResponse(response, collectionURL)
236         },
237
238         getResourceSize = function(relativePath, uuid)
239         {
240             collectionURL <- URLencode(paste0(self$getWebDavHostName(),
241                                               "c=", uuid))
242
243             subcollectionURL <- paste0(collectionURL, "/", relativePath);
244
245             headers <- list("Authorization" = paste("OAuth2", self$token))
246
247             response <- self$http$execute("PROPFIND", subcollectionURL, headers,
248                                           retryTimes = self$numRetries)
249
250             if(all(response == ""))
251                 stop("Response is empty, request may be misconfigured")
252
253             if(response$status_code < 200 || response$status_code >= 300)
254                 stop(paste("Server code:", response$status_code))
255
256             sizes <- self$httpParser$getFileSizesFromResponse(response,
257                                                               collectionURL)
258             as.numeric(sizes)
259         },
260
261         read = function(relativePath, uuid, contentType = "raw", offset = 0, length = 0)
262         {
263             fileURL <- paste0(self$getWebDavHostName(),
264                              "c=", uuid, "/", relativePath);
265
266             range <- paste0("bytes=", offset, "-")
267
268             if(length > 0)
269                 range = paste0(range, offset + length - 1)
270
271             if(offset == 0 && length == 0)
272             {
273                 headers <- list(Authorization = paste("OAuth2", self$token))
274             }
275             else
276             {
277                 headers <- list(Authorization = paste("OAuth2", self$token),
278                                 Range = range)
279             }
280
281             if(!(contentType %in% self$httpParser$validContentTypes))
282                 stop("Invalid contentType. Please use text or raw.")
283
284             serverResponse <- self$http$execute("GET", fileURL, headers,
285                                                 retryTimes = self$numRetries)
286
287             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
288                 stop(paste("Server code:", serverResponse$status_code))
289
290             self$httpParser$parseResponse(serverResponse, contentType)
291         },
292
293         write = function(relativePath, uuid, content, contentType)
294         {
295             fileURL <- paste0(self$getWebDavHostName(),
296                              "c=", uuid, "/", relativePath);
297             headers <- list(Authorization = paste("OAuth2", self$token),
298                             "Content-Type" = contentType)
299             body <- content
300
301             serverResponse <- self$http$execute("PUT", fileURL, headers, body,
302                                                 retryTimes = self$numRetries)
303
304             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
305                 stop(paste("Server code:", serverResponse$status_code))
306
307             self$httpParser$parseResponse(serverResponse, "text")
308         },
309
310         getConnection = function(uuid, relativePath, openMode)
311         {
312             fileURL <- paste0(self$getWebDavHostName(), 
313                               "c=", uuid, "/", relativePath);
314             headers <- list(Authorization = paste("OAuth2", self$token))
315
316             h <- curl::new_handle()
317             curl::handle_setheaders(h, .list = headers)
318
319             conn <- curl::curl(url = fileURL, open = openMode, handle = h)
320
321             conn
322         }
323     ),
324
325     private = list(
326
327         webDavHostName = NULL,
328         rawHostName    = NULL,
329
330         createNewFile = function(relativePath, uuid, contentType)
331         {
332             fileURL <- paste0(self$getWebDavHostName(), "c=",
333                               uuid, "/", relativePath)
334             headers <- list(Authorization = paste("OAuth2", self$token), 
335                             "Content-Type" = contentType)
336             body <- NULL
337
338             serverResponse <- self$http$execute("PUT", fileURL, headers, body,
339                                                 retryTimes = self$numRetries)
340
341             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
342                 stop(paste("Server code:", serverResponse$status_code))
343
344             paste("File created:", relativePath)
345         }
346     ),
347
348     cloneable = FALSE
349 )