/** * Constructor for Status Poller All params are required * * @param request The request that initiated the event * @param responsePromise Handler - Promise used to pass response to client * @param interval Interval between polls in millisecs * @param retries Max number of times the timer is allowed to be called * @param desiredState The desired state of the monitored object * @param conn Azure connection object to be used for the polling API call * @param retryOn404 Flag that determines if the poller should retry or fail when the response is * 404. */ public StatusPoller( Request request, CompletablePromise<T> responsePromise, long interval, long retries, String desiredState, AWSConnection conn, boolean retryOn404) { if (responsePromise != null) { this.responsePromise = responsePromise; } else { IllegalArgumentException e = new IllegalArgumentException( StatusPoller.MISSING_PARAM_MSG.format(new Object[] {"handler"})); throw e; } if (request != null) { this.request = request; } else { IllegalArgumentException e = new IllegalArgumentException( StatusPoller.MISSING_PARAM_MSG.format(new Object[] {"request"})); responsePromise.failure(e); throw e; } if (interval > -1) { this.interval = interval; } else { IllegalArgumentException e = new IllegalArgumentException( StatusPoller.NEGATIVE_PARAM_MSG.format(new Object[] {"interval"})); responsePromise.failure(e); throw e; } if (retries > -1) { this.retries = retries; } else { IllegalArgumentException e = new IllegalArgumentException( StatusPoller.NEGATIVE_PARAM_MSG.format(new Object[] {"retries"})); responsePromise.failure(e); throw e; } if (conn != null) { this.conn = conn; } else { IllegalArgumentException e = new IllegalArgumentException( StatusPoller.MISSING_PARAM_MSG.format(new Object[] {"connection"})); responsePromise.failure(e); throw e; } if (AWSUtil.isValued(desiredState)) { this.desiredState = desiredState; } else { IllegalArgumentException e = new IllegalArgumentException( StatusPoller.MISSING_PARAM_MSG.format(new Object[] {"desiredState"})); responsePromise.failure(e); throw e; } this.retryOn404 = retryOn404; this.promise = run(); }
/** * This is the method to call when the timer expires. The timer will continue to reset until the * verification context is verified or the verification context expires. If the context is * verified, the status will be COMPLETE. If the context expires, the status will be FAILURE. * * @param scheduledTime Time in milliseconds when the timer should fire * @param actualTime Time in milliseconds * @return long - next scheduled time for firing; 0 implies the timer is complete */ @Override public long timerFire(long scheduledTime, long actualTime) { if (getLogger().isTraceEnabled()) { getLogger().trace("The timer has fired for request " + request.getReqId()); } T response = getResponseObject(); Status status = null; String msg = null; long timerInterval = 0; // initialize to assume completion long timerResetValue = System.currentTimeMillis() + interval; response.setReqId(request.getReqId()); response.setTimestamp(System.currentTimeMillis()); if (!(--retries > -1)) { status = Status.FAILURE; msg = "The timer call has exceeded the maximum number of retries."; getLogger().error(msg); response.setStatus(status); response.setMessage(msg); responsePromise.complete(response); } else if (promise != null && promise.isCompleted()) { try { IHttpResponse httpResponse = (IHttpResponse) promise.get(); int respStatus = httpResponse.getStatusCode(); if (respStatus == 404 && retryOn404) { timerInterval = timerResetValue; // reset timer promise = run(); // refresh the response } else if (respStatus == 200) { String azureStatus = getStatus(httpResponse); try { if (desiredState.equalsIgnoreCase(azureStatus)) { // azureStatus could be null response = updateResponseObject(request, response, getJaxbObject(httpResponse)); status = Status.COMPLETE; msg = "Success"; response.setStatus(status); response.setMessage(msg); responsePromise.complete(response); } else if (isFailedState(azureStatus)) { // allows for short-circuit of failed calls status = Status.FAILURE; msg = "The status of " + azureStatus + " was returned which implies the call failed."; getLogger().error(msg); response.setStatus(status); response.setMessage(msg); responsePromise.complete(response); } else { timerInterval = timerResetValue; // reset timer promise = run(); // refresh the response } } catch (Exception e) { status = Status.FAILURE; msg = "An exception occurred while polling status. " + e.getMessage(); getLogger().error(msg, e); response.setStatus(status); response.setMessage(msg); responsePromise.complete(response); } } else { status = Status.FAILURE; msg = "Unexpected response status was returned by the API call. Status: " + respStatus; getLogger().error(msg); response.setStatus(status); response.setMessage(msg); responsePromise.complete(response); } } catch (Throwable e) { status = Status.FAILURE; msg = "An exception occurred while polling status. " + e.getMessage(); getLogger().error(msg, e); response.setStatus(status); response.setMessage(msg); responsePromise.complete(response); } } else if (promise == null) { status = Status.FAILURE; msg = "The HTTP Promise object is null."; getLogger().error(msg); response.setStatus(status); response.setMessage(msg); responsePromise.complete(response); } else { timerInterval = timerResetValue; // reset timer } // make sure this is called at the end so a new JAXB object will be computed next time fired clearJaxbObject(); return timerInterval; }