Search code examples
javaspringprometheusresttemplatepromql

how to send GET request with Query param using Rest Template in java


i need to send GET request with query param: query=100 - (avg(rate(node_cpu_seconds_total{job="prometheus",mode="idle"}[1m])) * 100) with RestTemplate

this is a PromQL query for prometheus

i tried do it, but i always get 400 error bad request, although the same request in postman is going well.

i tried encode it to url too, but it didn't work

what is my problem?here is a postman request that I need to send using java spring RestTemplate

String url = "http://localhost:9090/api/v1/query";
    String queryParam = "100 - (avg(rate(node_cpu_seconds_total{job=\"prometheus\",mode=\"idle\"}[1m])) * 100)";


    Object response = getWithParam(url, "query", queryParam);

    public Object getWithParam(String url, String paramName, String paramValue) {
    
    String encodedParamValue = UriComponentsBuilder
            .fromPath(paramValue)
            .build()
            .encode()
            .toUriString();
    HttpEntity requestEntity = new HttpEntity<>(null, createHeaders(paramName, encodedParamValue));



    ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET,
            requestEntity, Object.class);

    return response.getBody();
}

private MultiValueMap<String, String> createHeaders(String paramName, String paramValue) {
  
    MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
    headers.add(paramName, paramValue);
    return headers;
}

here's the error I'm getting: 400 Bad Request: "{"status":"error","errorType":"bad_data","error":"invalid parameter "query": unknown position: parse error: no expression found in input"}"


Solution

  • You are encoding your request param as a header in the restTemplate request, which is not the way to go.

    RestTemplate has a wealth of methods that allow you to pass the urlVariables directly. You can i.e. use the following.

    ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... urlVariables)
    

    So, in your case you can simply go with:

    String url = "http://localhost:9090/api/v1/query";
    String queryParam = "100 - (avg(rate(node_cpu_seconds_total{job=\"prometheus\",mode=\"idle\"}[1m])) * 100)";
    
    var response = restTemplate.getForEntity("/api/v1/query?query={query}", Object.class, queryParam);
    

    You can also use exchange method if you please

    var response2 = restTemplate.exchange("/api/v1/query?query={query}", HttpMethod.GET, new HttpEntity<>(null), Object.class, queryParam);