1

I'm currently working on integrating with a company's API, and I am able to hit their Order Retrieval endpoint in PostMan, getting a 200OK status, but in my java app, I've tried hitting the endpoint with OkHttp3, Unirest, and even my own HttpReq library, but no matter which library I use, I end up getting

<head><title>504 Gateway Time-out</title></head>
<body bgcolor="white">
<center><h1>504 Gateway Time-out</h1></center>
<hr><center>nginx/1.4.6 (Ubuntu)</center>
</body>
</html>

The headers, params, url for my java HttpRequest and PostMan are identical, as I copied the URL, params, headers from the result of printing out all the variables in Java, into PostMan. I've even tried using the Java snippets PostMan provides (HttpOk3/UniRest), but am still getting a 504. I've also tried setting timeouts to infinity, etc. What could I be doing wrong?

Here's the java HttpRequest I made with Unirest:

         try {
            Unirest.setTimeouts(30000, 100000);
            HttpResponse<String> response = Unirest.get(this.getOrderUrl)
                    .queryString("access_token", config.getAccessToken())
                    .queryString("id", circleGraphicsOrderId)
                    .header("content-type", "application/json")
                    .header("cache-control", "no-cache")
                    .header("authorization", "Basic Og==")
                    .asString();
        } catch (UnirestException e) {
            e.printStackTrace();
        }

Here's the API credentials if any of you would like to test with me:

(Params built into the url) URL = https://rest.cgorders.com/api/orders/order?access_token=97484431a4525ed2b294b699a3d2f202&id=15755354

The Params were: {access_token:97484431a4525ed2b294b699a3d2f202, id:15755354}

EDIT: Resolved! I was using wacky HttpRequest Libraries because our company code had a bunch of use cases with such libraries. Using the java provided one as Markspace wrote below resolved the issue.

P_equals_NP_2021
  • 627
  • 1
  • 9
  • 27
  • Is this API public so we can test it out? Is there a similar API that is public that we can test? – markspace Mar 08 '18 at 22:21
  • What about `User-agent`? What is PostMan using? Also, GET requests don't typically have a `Content-type` as there's no request body – Phil Mar 08 '18 at 22:21
  • @markspace I just added the public API info above. – P_equals_NP_2021 Mar 08 '18 at 22:22
  • Also, you know Unirest has specific method for basic authentication ~ http://unirest.io/java.html#user-content-basic-authentication – Phil Mar 08 '18 at 22:25
  • Should those headers start with a capital letter? – markspace Mar 08 '18 at 22:26
  • @markspace HTTP request / response headers are meant to be case insensitive. It should not matter – Phil Mar 08 '18 at 22:27
  • Wait, that URL works without any HTTP authorization. Why are you setting `Authorization: Basic Og==`? – Phil Mar 08 '18 at 22:29
  • I'm actually deleting the headers, as Phil is right and I don't even need content-type to successfully hit the endpoint via postman – P_equals_NP_2021 Mar 08 '18 at 22:29
  • @Phil Because in PostMan, even when I delete the Basic OG Auth header, it auto fills and autochecks it when I send the GET request – P_equals_NP_2021 Mar 08 '18 at 22:30
  • That's a bit weird. `Og==` is just `:` which means empty username / password. I'd omit that header but in testing, I've found it doesn't change the result – Phil Mar 08 '18 at 22:32
  • I tried playing around with the `id` and `access_token` values and was able to get a 504 response. This leads me to believe that either `circleGraphicsOrderId` or `config.getAccessToken()` are returning the wrong values. Since you haven't shown where these are assigned, we can't help you but you could have just used a debugger to check the values before making the request – Phil Mar 08 '18 at 22:35
  • FYI, your conclusion is probably wrong. Try your original code with `.queryString("access_token", "97484431a4525ed2b294b699a3d2f202").queryString("id", "15755354")` – Phil Mar 08 '18 at 22:42
  • @Phil The values from config are correct, I made sure they were before posting. Adding the queryStrings didn't fix the 504 for me, as that was something I tried earlier this morning. – P_equals_NP_2021 Mar 08 '18 at 22:52
  • I'm using curl to test and if I take one or more digits from the end of the `id` parameter, the request times out. Are you **absolutely sure** that `circleGraphicsOrderId` contains the correct value? Try adding `if (!"15755354".equals(circleGraphicsOrderId)) { throw new Exception("Incorrect value"); }` before you make the request – Phil Mar 08 '18 at 22:59
  • Well the number 15755354 was just an example. The call to the GET request is part of an integration test, where I POST an order to the API, and pass in the response value into the function which handles the GET request. The number is formatted correctly. – P_equals_NP_2021 Mar 08 '18 at 23:02
  • 1
    @Phil Actually... It seems that even though when I print them out they look the same, they indeed are different. Maybe from the result of me using gson to parse the ID from the POST response? – P_equals_NP_2021 Mar 08 '18 at 23:08
  • Plenty of reasons - different headers,different body different env parameters. – Antoniossss Mar 08 '18 at 23:57

2 Answers2

0

The following works for me. What do you need to change to get it working how you want?

public class GetRequest {

   public static void main( String[] args ) {
      System.out.println( new GetRequest().get( "" ) );
   }

   public String get( String search ) {

      try {
         URL url = new URL( "https://rest.cgorders.com/api/orders/order?access_token=97484431a4525ed2b294b699a3d2f202&id=15755354" );
         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
         conn.setRequestMethod( "GET" );
         conn.setRequestProperty( "Accept", "application/json" );

         conn.connect();

         BufferedReader br = new BufferedReader( new InputStreamReader(
                 conn.getInputStream(), "UTF-8" ) );

         StringBuilder sb = new StringBuilder( 2048 );
         for( String line; (line = br.readLine()) != null; ) {
            sb.append( line );
         }
         conn.disconnect();

         return sb.toString();

      } catch( IOException ex ) {
         Logger.getLogger( Pixabay.class.getName() ).log( Level.SEVERE, null, ex );
         return ex.toString();
      }

   }
}
markspace
  • 10,621
  • 3
  • 25
  • 39
  • What library is that HttpURLConnection from? I'll try using that library and see if that resolves it. – P_equals_NP_2021 Mar 08 '18 at 22:33
  • 2
    Just the standard Java API. No libraries. – markspace Mar 08 '18 at 22:33
  • It's highly unlikely the particular HTTP client library is at fault here – Phil Mar 08 '18 at 22:36
  • That wasn't my point. The OP is probably supplying some parameters that cause it to fail, or their local system is at fault. The above works. If it works on the OPs system (or doesn't) then we can narrow down the point of failure to either code or local config. @Phil – markspace Mar 08 '18 at 22:38
  • Your code worked! Thanks so much Mark. I've been stuck on this all day, lesson learned is when in doubt, stick with Java provided libraries. – P_equals_NP_2021 Mar 08 '18 at 22:39
  • @TDaddy this code _"works"_ because the query string parameters are hard coded. Your original code would work too if you used string literals instead of `circleGraphicsOrderId` – Phil Mar 08 '18 at 22:40
  • 1
    From comments above, it looks like your `id` or `access_token` might be at fault, try adding those, then test again. This is basic debugging technique "divide and conquer". Start with something working, then modify incrementally until you find the problem. @TDaddy – markspace Mar 08 '18 at 22:41
0

I used Spring's RestTemplate HTTP client and it worked just fine. Maybe that client can be used.

public static void main(String[] args) {
    RestTemplate restTemplate = new RestTemplate();
    Gson gson = new GsonBuilder().setPrettyPrinting().create();

    HttpHeaders hh = new HttpHeaders();
    hh.setContentType(MediaType.APPLICATION_JSON);
    hh.set(AUTHORIZATION, "Basic Og==");
    hh.setCacheControl("no-cache");
    HttpEntity he = new HttpEntity(hh);

    String url = "https://rest.cgorders.com/api/orders/order?access_token=97484431a4525ed2b294b699a3d2f202&id=15755354";
    Map results = restTemplate.exchange(url, HttpMethod.GET, he, Map.class).getBody();

    //this also worked and is a lot less code
    //Map results = restTemplate.getForObject("https://rest.cgorders.com/api/orders/order?access_token=97484431a4525ed2b294b699a3d2f202&id=15755354", Map.class);
    System.out.println(gson.toJson(results));
}

Here are the imports in case you want to duplicate.

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.Map;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import static org.springframework.http.HttpHeaders.AUTHORIZATION;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;
Jose Martinez
  • 11,452
  • 7
  • 53
  • 68