Home > Enterprise >  Java Call method with return type and method to be called
Java Call method with return type and method to be called

Time:10-26

I have lots of calls against a REST API that i want handled the same way. Perform call, check if not authenticated. Refresh Token call again or if we hit rate limit despite rate limit function. Sleep and perform call again.

I would like to wrap this in a function that can be called in the way

 ReturnType returnVal=  handleIntegration(ReturnType , functionToBecCalled)

How can this be achieved?

For the example below something like

CustomersResponse customersReponse = handleIntegration(CustomersResponse , connection.customers.findCustomersResponse())
EmployeesReponse employeesRepsonse = handleIntegration(EmployeeResponse , connection.employees.findEmployeesResponse())

//Current Code

            bucket.consume();
            CustomersResponse customersResponse = null;
            try {
                 customersResponse = connection.customers.findCustomersResponse();
            } catch (IntegrationException e) {
                if (e.getStatusCode() == 401) {
                    this.newAccessFromRefreshToken();
                    customersResponse = connection.customers.findCustomersResponse();
                }else if (e.getStatusCode() == 429){
                    Thread.sleep(500);
                    customersResponse = connection.customers.findCustomersResponse();
                }else
                    throw e;
            }   

        bucket.consume();
            EmployeeResponse employeeResponse = null;
            try {
                 employeeResponse = connection.employees.findEmployeesResponse();
            } catch (IntegrationException e) {
                if (e.getStatusCode() == 401) {
                    this.newAccessFromRefreshToken();
                    employeeResponse = connection.employees.findEmployeesResponse();
                }else if (e.getStatusCode() == 429){
                    Thread.sleep(500);
                    employeeResponse = connection.employees.findEmployeesResponse();
                }else
                    throw e;
            }   

CodePudding user response:

If you are at least on Java 8 with lambdas, you can do it like this:

<T> T handleIntegration(Class<T> clazz, Supplier<T> method) {
  bucket.consume(); // I don't know how this fits - BEWARE!
  T response = null;
  try {
    response = method.get();
  } catch (IntegrationException e) {
    if (e.getStatusCode() == 401) {
      this.newAccessFromRefreshToken();
      response = method.get();
    } else if (e.getStatusCode() == 429){
      Thread.sleep(500);
      response = method.get();
    } else
      throw e;
    }
  }
  // I don't know what you want to do with the response, returning it here for example
  return response;
}

And use it e.g. as:

CustomersResponse customersReponse = handleIntegration(
  CustomersResponse.class,
  () -> connection.customers.findCustomersResponse()
);

Caveat: I assumed IntegrationException is an unchecked exception. If it is checked or in any case, e.g. connection.customers.findCustomersResponse() throws a checked exception, the provided java.util.function.Supplier will not do. You will have to provide a functional interface that throws the specific checked exception.

Unrelated Note: Thread.sleep() is easy, but you may want to consider a better way, because sleep blocks the thread.

CodePudding user response:

You could try something like the following with the help of Java 8 Functional Interfaces and Generics:

public <T> T handleIntegration(Supplier<T> supplier) {
    bucket.consume();
    T result = null;
    try {
        result = supplier.get();
    } catch (IntegrationException e) {
        if (e.getStatusCode() == 401) {
            this.newAccessFromRefreshToken();
            result = connection.employees.findEmployeesResponse();
        } else if (e.getStatusCode() == 429) {
            Thread.sleep(500);
            result = connection.employees.findEmployeesResponse();
        } else
            throw e;
    }
    return result;
}

Then you could call the method like this:

CustomersResponse returnVal = handleIntegration(connection.customers::findCustomersResponse)

  • Related