+ if (!usePolling) {
+ // doesn't use polling - just return the completed future
+ return CompletableFuture.completedFuture(outcome);
+ }
+
+ HttpPollingConfig cfg = (HttpPollingConfig) config;
+
+ switch (detmStatus(rawResponse, response)) {
+ case SUCCESS -> {
+ logger.info("{}.{} request succeeded for {}", params.getActor(), params.getOperation(),
+ params.getRequestId());
+ return CompletableFuture
+ .completedFuture(setOutcome(outcome, OperationResult.SUCCESS, rawResponse, response));
+ }
+ case FAILURE -> {
+ logger.info("{}.{} request failed for {}", params.getActor(), params.getOperation(),
+ params.getRequestId());
+ return CompletableFuture
+ .completedFuture(setOutcome(outcome, OperationResult.FAILURE, rawResponse, response));
+ }
+ default -> logger.info("{}.{} request incomplete for {}", params.getActor(), params.getOperation(),
+ params.getRequestId());
+ }
+
+ // still incomplete
+
+ // see if the limit for the number of polls has been reached
+ if (pollCount++ >= cfg.getMaxPolls()) {
+ logger.warn("{}: exceeded 'poll' limit {} for {}", getFullName(), cfg.getMaxPolls(),
+ params.getRequestId());
+ setOutcome(outcome, OperationResult.FAILURE_TIMEOUT);
+ return CompletableFuture.completedFuture(outcome);
+ }
+
+ // sleep and then poll
+ Function<Void, CompletableFuture<OperationOutcome>> doPoll = unused -> issuePoll(outcome);
+ return sleep(getPollWaitMs(), TimeUnit.MILLISECONDS).thenComposeAsync(doPoll);
+ }
+
+ /**
+ * Polls to see if the original request is complete. This method polls using an HTTP
+ * "get" request whose URL is constructed by appending the extracted "poll ID" to the
+ * poll path from the configuration data.
+ *
+ * @param outcome outcome to be populated with the response
+ * @return a future that can be used to cancel the poll or await its response
+ */
+ protected CompletableFuture<OperationOutcome> issuePoll(OperationOutcome outcome) {
+ String path = getPollingPath();
+ String url = getClient().getBaseUrl() + path;
+
+ logger.debug("{}: 'poll' count {} for {}", getFullName(), pollCount, params.getRequestId());
+
+ logMessage(EventType.OUT, CommInfrastructure.REST, url, null);
+
+ return handleResponse(outcome, url, callback -> getClient().get(callback, path, null));
+ }
+
+ /**
+ * Determines the status of the response. This particular method simply throws an
+ * exception.
+ *
+ * @param rawResponse raw response
+ * @param response decoded response
+ * @return the status of the response
+ */
+ protected Status detmStatus(Response rawResponse, T response) {
+ throw new UnsupportedOperationException("cannot determine response status");
+ }
+
+ /**
+ * Gets the URL to use when polling. Typically, this is some unique ID appended to the
+ * polling path found within the configuration data. This particular method simply
+ * returns the polling path from the configuration data.
+ *
+ * @return the URL to use when polling
+ */
+ protected String getPollingPath() {
+ return ((HttpPollingConfig) config).getPollPath();