Improved HTTP request filtering and response error handling.
[arvados.git] / sdk / R / R / HttpRequest.R
1 source("./R/custom_classes.R")
2
3 HttpRequest <- setRefClass(
4
5     "HttrRequest",
6
7     fields = list(
8         send_method         = "character",
9         server_base_url     = "character",
10         server_relative_url = "character",
11         auth_token          = "character",
12         allowed_methods     = "list",
13         query_filters       = "ANY",
14         response_limit      = "ANY",
15         query_offset        = "ANY"
16     ),
17
18     methods = list(
19         initialize = function(method,
20                               token,
21                               base_url,
22                               relative_url,
23                               filters = NULL,
24                               limit = 100,
25                               offset = 0) 
26         {
27             send_method         <<- method
28             auth_token          <<- token
29             server_base_url     <<- base_url
30             server_relative_url <<- relative_url
31             query_filters       <<- filters
32             response_limit      <<- limit
33             query_offset        <<- offset
34         },
35
36         execute = function() 
37         {
38             http_method <- switch(send_method,
39                                   "GET"    = .self$getRequest,
40                                   "POST"   = .self$postRequest,
41                                   "PUT"    = .self$putRequest,
42                                   "DELETE" = .self$deleteRequest,
43                                   "PATCH"  = .self$pathcRequest)
44             http_method()
45         },
46
47         getRequest = function() 
48         {
49             requestHeaders <- httr::add_headers(Authorization = .self$getAuthHeader())
50             requestQuery   <- .self$generateQuery()
51             url            <- paste0(server_base_url, server_relative_url, requestQuery)
52
53             server_data <- httr::GET(url    = url,
54                                      config = requestHeaders)
55         },
56
57         #Todo(Fudo): Try to make this more generic
58         postRequest = function() 
59         {
60             #Todo(Fudo): Implement this later on.
61             print("POST method")
62         },
63
64         putRequest = function() 
65         {
66             #Todo(Fudo): Implement this later on.
67             print("PUT method")
68         },
69
70         deleteRequest = function() 
71         {
72             #Todo(Fudo): Implement this later on.
73             print("DELETE method")
74         },
75
76         pathcRequest = function() 
77         {
78             #Todo(Fudo): Implement this later on.
79             print("PATCH method")
80         },
81
82         getAuthHeader = function() 
83         {
84             auth_method <- "OAuth2"
85             auth_header <- paste(auth_method, auth_token)
86         },
87
88         generateQuery = function() 
89         {
90             #Todo(Fudo): This function is a mess, refactor it
91             finalQuery <- "?alt=json"
92
93             if(!is.null(query_filters))
94             {
95                 filters <- sapply(query_filters, function(filter)
96                 {
97                     if(length(filter) != 3)
98                         stop("Filter list must have exacthey 3 elements.")
99
100                     attributeAndOperator = filter[c(1, 2)]
101                     filterList = filter[[3]]
102                     filterListIsPrimitive = TRUE
103                     if(length(filterList) > 1)
104                         filterListIsPrimitive = FALSE
105
106                     attributeAndOperator <- sapply(attributeAndOperator, function(component) {
107                         component <- paste0("\"", component, "\"")
108                     })
109
110                     filterList <- sapply(unlist(filterList), function(filter) {
111                         filter <- paste0("\"", filter, "\"")
112                     })
113
114                     filterList <- paste(filterList, collapse = ",+")
115
116                     if(!filterListIsPrimitive)
117                         filterList <- paste0("[", filterList, "]")
118
119                     filter <- c(attributeAndOperator, filterList)
120
121                     queryParameter <- paste(filter, collapse = ",+")
122                     queryParameter <- paste0("[", queryParameter, "]")
123         
124                 })
125
126                 filters <- paste(filters, collapse = ",+")
127                 filters <- paste0("[", filters, "]")
128
129                 encodedQuery <- URLencode(filters, reserved = T, repeated = T)
130
131                 finalQuery <- paste0(finalQuery, "&filters=", encodedQuery)
132
133                 #Todo(Fudo): This is a hack for now. Find a proper solution.
134                 finalQuery <- stringr::str_replace_all(finalQuery, "%2B", "+")
135             }
136
137             if(!is.null(response_limit))
138             {
139                 if(!is.numeric(response_limit))
140                     stop("Limit must be a numeric type.")
141                 
142                 finalQuery <- paste0(finalQuery, "&limit=", response_limit)
143             }
144
145             if(!is.null(query_offset))
146             {
147                 if(!is.numeric(query_offset))
148                     stop("Offset must be a numeric type.")
149                 
150                 finalQuery <- paste0(finalQuery, "&offset=", query_offset)
151             }
152
153             finalQuery
154         }
155     )
156 )