public Response withSynchronization( final EntitlementCallCompletionCallback<T> callback, final long timeoutSec, final boolean callCompletion, final CallContext callContext) throws SubscriptionApiException, AccountApiException, EntitlementApiException { final CompletionUserRequestEntitlement waiter = callCompletion ? new CompletionUserRequestEntitlement(callContext.getUserToken()) : null; try { if (waiter != null) { killbillHandler.registerCompletionUserRequestWaiter(waiter); } final T operationValue = callback.doOperation(callContext); if (waiter != null && callback.isImmOperation()) { waiter.waitForCompletion(timeoutSec * 1000); } return callback.doResponseOk(operationValue); } catch (InterruptedException e) { return Response.status(Status.INTERNAL_SERVER_ERROR).build(); } catch (TimeoutException e) { return Response.status(Status.fromStatusCode(408)).build(); } finally { if (waiter != null) { killbillHandler.unregisterCompletionUserRequestWaiter(waiter); } } }