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)