diff --git a/bin/export.r b/bin/export.r new file mode 100755 index 0000000000000000000000000000000000000000..1fdc4f3a5137d1634c944cf2594178fdc210b934 --- /dev/null +++ b/bin/export.r @@ -0,0 +1,160 @@ +#!/usr/bin/Rscript --vanilla --no-save --no-restore --quiet --encoding=UTF-8 +# Call SIDO web service to get data +# +## Uses +## - RCurl: https://cran.r-project.org/web/packages/RCurl/index.html +## - keyring: https://cran.r-project.org/web/packages/keyring/index.html +## - logger: https://cran.r-project.org/web/packages/logger/index.html + +sido_ws_url <- "https://sido.pheno.fr/ws" +observatory_schema <- "foret" +keyring_service <- "sido-export" + +#' Load or install a package. +#' +#' @param packagename string package name +require_install_package <- function(packagename) { + if (!library(packagename, character.only=TRUE, logical.return=TRUE)) { + logger::log_info("Installing the library {packagename}...") + install.packages(packagename, repos = "http://cran.at.r-project.org/") + if (!library(packagename, character.only=TRUE, logical.return=TRUE)) { + logger::log_error("Installing the library {packagename} failed.") + q() + } + } + require(packagename, quietly = TRUE, character.only = TRUE) +} + +require_install_package("RCurl") +require_install_package("jsonlite") +require_install_package("keyring") +require_install_package("logger") + +#' Get keyring +#' +#' @return keyring for the script +get_keyring <- function(keyring_service) { + logger::log_info("Using backend_file") + kr <- keyring::default_backend(keyring = keyring_service) + if (kr$keyring_is_locked(keyring=keyring_service)) { + kr$keyring_unlock(keyring = keyring_service) + } + kr +} + +#' Get key value from keyring. +#' +#' @param kr keyring for the script +#' @param key_name string key name +#' @param prompt string prompt message +#' @return string keyring value +get_keyring_value <- function(kr, key_name, prompt) { + logger::log_info("Getting keyring value for {key_name}...") + if (!keyring::has_keyring_support()) { + logger::log_error("No keyring support!") + logger::log_info("Set value for the variable sido_{key_name} in the code.") + q() + } + keyring_service <- kr$keyring_default() + + key_list <- kr$list() + match_keys <- subset(key_list, + service == keyring_service & username == key_name) + if (dim(match_keys)[1] == 0) { + logger::log_info("No value found for {keyring_service} and {key_name}.") + kr$set(service = keyring_service, username = key_name, prompt = prompt) + } + kr$get(service = keyring_service, username = key_name) +} + +#' Get access token using client credentials. +#' +#' @param sido_url string root URL of SIDO WS +#' @param sido_client_id string OAuth2 client ID for SIDO +#' @param sido_client_secret string OAuth2 client secret for SIDO +#' @return access token +get_access_token <- function(sido_url, sido_client_id, sido_client_secret) { + logger::log_info("Getting access token...") + token_url <- paste0(sido_url, "/oauth/token") + # Perform the POST request + post_data <- paste0( + "client_id=", sido_client_id, + "&client_secret=", sido_client_secret, + "&grant_type=client_credentials") + headers <- c("Content-Type" = "application/x-www-form-urlencoded") + opts <- list(postfields = post_data, httpheader = headers) + logger::log_info("Calling {token_url}...") + post_response <- RCurl::postForm(token_url, .opts = opts) + logger::log_info("Parsing JSON...") + token <- jsonlite::fromJSON(post_response) + token$access_token +} + +#' Get queries for a given schema. +#' +#' @param sido_url string root URL of SIDO WS +#' @param schema string schema name +#' @param access_token string access token +#' @return queries list of query names +get_queries <- function(sido_url, schema, access_token) { + logger::log_info("Getting queries...") + queries_url <- paste0(sido_url, "/data/queries/", schema) + headers <- c("Authorization" = paste0("Bearer ", access_token)) + queries_response <- RCurl::getURL(queries_url, + .opts = list(httpheader = headers)) + queries <- jsonlite::fromJSON(queries_response) + queries$data[, "name"] +} + +#' Get data for a given schema and query. +#' +#' @param sido_url string root URL of SIDO WS +#' @param schema string schema name +#' @param query string query name +#' @param access_token string access token +#' @return data data frame +get_data <- function(sido_url, schema, query, access_token) { + logger::log_info("- Getting data for {schema}/{query}...") + data_url <- paste0(sido_url, "/data/", schema, "/", query) + headers <- c("Authorization" = paste0("Bearer ", access_token)) + data_response <- RCurl::getURL(data_url, + .opts = list(httpheader = headers), + .encoding = "UTF-8") + data <- jsonlite::fromJSON(data_response) + if (data$status != 200) { + logger::log_error(paste0(" Error ", data$status, ": ", data$message)) + } + df <- data.frame(data$data$values) + names(df) <- data$data$properties$title + df +} + +# Run + +kr <- get_keyring(keyring_service) +sido_client_id <- get_keyring_value(kr, "client_id", + "Type your client_id for SIDO") +sido_client_secret <- get_keyring_value(kr, "client_secret", + "Type your client_secret for SIDO") + +token <- get_access_token(sido_ws_url, sido_client_id, sido_client_secret) +queries <- get_queries(sido_ws_url, observatory_schema, token) +logger::log_info("- nb of queries: {0}", length(queries)) +for (i in seq_along(queries)) { + query = queries[i] + logger::log_info("- query: {query}") + if (query == "data") { + logger::log_info(" - skipping data query") + } else { + data <- get_data(sido_ws_url, observatory_schema, query, token) + filename <- paste0(observatory_schema, "-", query, ".csv") + logger::log_info(" - file: {filename}...") + write.table(data, + file = filename, + col.names = TRUE, + row.names = FALSE, + sep = ",", + quote = TRUE) + logger::log_info(" done") + } +} diff --git a/sido-gwt/src/main/java/fr/soeretempo/sido/gwt/server/ws/QueryServiceImpl.java b/sido-gwt/src/main/java/fr/soeretempo/sido/gwt/server/ws/QueryServiceImpl.java index 73619af3687156e566903223dfb120be42ac59c0..b18d308c8f4d3357c0a6902f12894c3307b43b42 100644 --- a/sido-gwt/src/main/java/fr/soeretempo/sido/gwt/server/ws/QueryServiceImpl.java +++ b/sido-gwt/src/main/java/fr/soeretempo/sido/gwt/server/ws/QueryServiceImpl.java @@ -112,12 +112,15 @@ public class QueryServiceImpl implements QueryService { @Override public final WsQuery getQuery(@NonNull final Datasource obs, - final String queryName) { - if (getQueries(obs) != null) { - return getQueries(obs).get(0); - } else { - return null; + @NonNull final String queryName) { + final var queries = getQueries(obs); + if (queries != null) { + return queries.stream() + .filter(query -> queryName.equals(query.getName())) + .findFirst() + .orElse(null); } + return null; } @Override