Search code examples
javahttprequesthttpresponse

For asynchronous http api request getting http responce code 202 in Java


I have below DSS http connection to url:

private static HttpURLConnection connection(String urlSpec) {
        HttpURLConnection connection = new URL(urlSpec).openConnection() as HttpURLConnection
        connection.setRequestProperty('Prefer', 'respond-async, wait=60')
        connection.setRequestProperty('Accept', 'application/json')
 
        connection.setRequestMethod("POST")
        connection.setRequestProperty("Content-Type", "application/json; utf-8")
        connection.setDoOutput(true)
        connection
    }

Below is the part of my code where i am checking the http response and if the response is http 200 which is HTTP_OK then i can fetch the data and insert into database table. But now the problem is now during processing i am getting now in between Got http error code as 202 which is HTTP_ACCEPTED and for this reason i am not able to process this data into database table.

I think HTTP 202 is to be expected when requesting async. It means that server has received your query and is working on it. We need to keep checking the status of the request, by retrying the new URL sent in the 202 response, until you get HTTP 200. But i dont know how can i do this ?


Solution

  • Well, yes, you need to keep asking the remote resource if the task has been completed or not.

    202 is non-committal, meaning that there is no way for the HTTP to later send an asynchronous response indicating the outcome of processing the request.

    I see you're also working with "bare metal" utilities, such as HttpURLConnection, and that leads me to believe you do not have any library support for retrying HTTP calls.

    In this case what you could do is spawn a new thread, maybe using an ExecutorService, and submit/execute a task which simply loops, e.g.

    while (!Thread.interrupted()) { ... }
    

    calling your URL until an HTTP_OK is received.


    A skeleton could be

    executorService.execute(() -> {
      while (!Thread.interrupted()) {
        // Return a valid value if `HTTP_OK`, otherwise `null`
        final var result = callRemoteUrl(url);
        
        if (result != null) {
          callback.call(result);
          return;
        }
      }
    });
    

    Where callback is an instance which receive the HTTP result asynchronously.


    while (true)
      HttpURLConnection connection = connection("XXX.com")
      
      if (connection.responseCode >= HTTP_SERVER_ERROR) {
        // Server/internal error, we can't do anything
        // Maybe throw a custom Exception.
        break;
      }
    
      if (connection.responseCode != HTTP_OK) {
        try {
          // Adjust the delay between calls, in ms
          Thread.sleep(1000);
        } catch (final InterruptedException e) {
          // Ignore
        }
        
        // Try again
        continue;
      }
      
      println("Got http response code: ${connection.responseCode}, message: ${connection.responseMessage}")
    
      log.info("Successful request to ${connection.getURL()}")
      //println(connection.getInputStream().getText())
    
      LazyMap json = jsonFromExtractionConnection(connection)
      //Process the data from the response JSON and put it in the Map object for processing
      tryToProcessMarketDataFromExtractionJson(json, ricMap)
    
      // Filter the empty records out and take valid map from Data for inserting into DB table .
      def validMap = ricMap.findAll { key, val ->
          val.fs != null
      }
    
      insertIntoDb(validMap)
      writeToFile(outFile, sql(ORACLE), Select.query, Arrays.asList(Data.COLUMNS))
      
      // We're done, end the loop
      break;
    }