public void failTask(String errMsg, Throwable t, boolean logAsWarning) { final Level logLevel = logAsWarning ? Level.WARNING : Level.INFO; final String msg = errMsg == null ? "Unexpected State" : errMsg; if (t != null) { log(logLevel, () -> String.format("%s%s Error: %s", msg, msg.endsWith(".") ? "" : ".", Utils.toString(t))); } else { log(logLevel, () -> msg); } ServiceTaskCallbackResponse body = new ServiceTaskCallbackResponse(); body.taskInfo = new TaskState(); body.taskInfo.stage = TaskStage.FAILED; body.taskSubStage = DefaultSubStage.ERROR; if (t != null) { body.taskInfo.failure = getServiceErrorResponse(t); } else { ServiceErrorResponse rsp = new ServiceErrorResponse(); rsp.message = msg; body.taskInfo.failure = rsp; } sendRequest(Operation.createPatch(getUri()) .setBody(body) .setCompletion((op, ex) -> { if (ex != null) { logWarning("Self patch failed: %s", Utils.toString(ex)); } })); }
/** * Merges received task state with the persisted one. * * @param currentState existing state * @param op the current service operation */ private void syncTaskStates( ExtensibilitySubscriptionCallback currentState, Operation op) { currentState.status = ExtensibilitySubscriptionCallback.Status.RESUME; // Original callback to task which has to be resumed. ServiceTaskCallbackResponse serviceTaskCallbackResponse = currentState.serviceTaskCallback .getFinishedResponse(); // Every service task which supports extensibility should provide it's own // 'extensibilityCallbackResponse' which will define suitable for modification fields, once // the response from subscriber is received. Here fields are merged from response to // callback. ServiceTaskCallbackResponse extensibilityResponse = op .getBody(currentState.replyPayload.getClass()); // Save the properties that came back from the response to support update Map<String, String> customProperties = extensibilityResponse.customProperties; // Inherit original callback in order to be aware which task stage should be resumed. extensibilityResponse.copy(serviceTaskCallbackResponse); extensibilityResponse.customProperties = customProperties; // Store extensibility callback in order to be used as finished callback response. currentState.replyPayload = extensibilityResponse; }
private void failTask(String msg, String taskDocumentSelfLink) { String errMsg = msg != null ? msg : "Unexpected State"; logWarning("Fail extensibility task: %s", errMsg); ServiceTaskCallbackResponse body = new ServiceTaskCallbackResponse(); body.taskInfo = new TaskState(); body.taskInfo.stage = TaskStage.FAILED; body.taskSubStage = DefaultSubStage.ERROR; ServiceErrorResponse rsp = new ServiceErrorResponse(); rsp.message = errMsg; body.taskInfo.failure = rsp; sendRequest(Operation.createPatch(UriUtils.buildUri(getHost(), taskDocumentSelfLink)) .setBody(body) .setCompletion((op, ex) -> { if (ex != null) { logWarning("Patch for fail task operation failed: %s", Utils.toString(ex)); } })); }
@Test public void testTimeout() throws Throwable { ExtensibilitySubscriptionCallback state = createExtensibilityCallback( ExtensibilitySubscriptionCallback.Status.BLOCKED); state.due = LocalDateTime.now().plus(5, SECONDS); state.serviceTaskCallback = new ServiceTaskCallback(); state.serviceTaskCallback.serviceSelfLink = TestStatelessService.SELF_LINK; state.replyPayload = new ServiceTaskCallbackResponse(); state.replyPayload.taskInfo = TaskState.createAsStarted(); state.replyPayload.taskSubStage = DefaultSubStage.CREATED; state.taskStateJson = TestStatelessService.class.getSimpleName(); DeferredResult<Void> done = new DeferredResult<>(); this.host.startService(new TestStatelessService(done)); this.host.waitForServiceAvailable(TestStatelessService.SELF_LINK); URI uri = UriUtils.buildUri(host, ExtensibilitySubscriptionCallbackService.FACTORY_LINK); sender.sendPostAndWait(uri, state, ExtensibilitySubscriptionCallback.class); this.waitFor("Task did not time out.", () -> done.isDone()); }
private void notifyCaller(CompositionSubTaskState state) { ServiceTaskCallbackResponse callbackResponse = getFinishedCallbackResponse(state); callbackResponse.customProperties = mergeCustomProperties( callbackResponse.customProperties, state.customProperties); callbackResponse.addProperty(REFERER, this.getSelfLink()); sendRequest(Operation.createPatch(this, state.serviceTaskCallback.serviceSelfLink) .setBody(callbackResponse) // Pragma needed because the service might be still in creation state (asynch // creation) .addPragmaDirective(Operation.PRAGMA_DIRECTIVE_QUEUE_FOR_SERVICE_AVAILABILITY) .setCompletion((o, e) -> { if (e != null) { logWarning("Notifying parent task %s from composition failed: %s", o.getUri(), Utils.toString(e)); } })); }
public ServiceTaskCallbackResponse getFailedResponse(ServiceErrorResponse failure) { return new ServiceTaskCallbackResponse(taskStageFailed, subStageFailed, failure); }
public ServiceTaskCallbackResponse getFinishedResponse() { return new ServiceTaskCallbackResponse(taskStageComplete, subStageComplete, null); }
public ServiceTaskCallbackResponse getFailedResponse(Throwable e) { return new ServiceTaskCallbackResponse(taskStageFailed, subStageFailed, Utils.toServiceErrorResponse(e)); }