use of io.cdap.cdap.proto.WorkflowTokenNodeDetail in project cdap by caskdata.
the class WorkflowClient method getWorkflowTokenAtNode.
/**
* Retrieve the keys set by the specified node in the {@link WorkflowToken} for the specified workflow run
* filtered by the specified {@link WorkflowToken.Scope} and key.
*
* @param workflowRunId the run id of the workflow
* @param nodeName the name of the node
* @param scope the specified {@link WorkflowToken.Scope}
* @param key the specified key
* @return {@link WorkflowTokenDetail} with the specified filters
*/
public WorkflowTokenNodeDetail getWorkflowTokenAtNode(ProgramRunId workflowRunId, String nodeName, @Nullable WorkflowToken.Scope scope, @Nullable String key) throws IOException, UnauthenticatedException, NotFoundException, UnauthorizedException {
String path = String.format("apps/%s/workflows/%s/runs/%s/nodes/%s/token", workflowRunId.getApplication(), workflowRunId.getProgram(), workflowRunId.getRun(), nodeName);
URL url = config.resolveNamespacedURLV3(workflowRunId.getNamespaceId(), appendScopeAndKeyToUrl(path, scope, key));
HttpResponse response = restClient.execute(HttpMethod.GET, url, config.getAccessToken(), HttpURLConnection.HTTP_NOT_FOUND);
if (response.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
String msg = "Either the workflow or its run id";
if (key != null) {
msg = String.format("%s or the specified key at the specified scope", msg);
}
throw new NotFoundException(workflowRunId, msg);
}
return ObjectResponse.fromJsonBody(response, WorkflowTokenNodeDetail.class, GSON).getResponseObject();
}
use of io.cdap.cdap.proto.WorkflowTokenNodeDetail in project cdap by caskdata.
the class WorkflowHttpHandlerTest method testWorkflowToken.
@Test
@SuppressWarnings("ConstantConditions")
public void testWorkflowToken() throws Exception {
deploy(AppWithWorkflow.class, 200);
Id.Application appId = Id.Application.from(Id.Namespace.DEFAULT, AppWithWorkflow.NAME);
final Id.Workflow workflowId = Id.Workflow.from(appId, AppWithWorkflow.SampleWorkflow.NAME);
String outputPath = new File(tmpFolder.newFolder(), "output").getAbsolutePath();
startProgram(workflowId, ImmutableMap.of("inputPath", createInput("input"), "outputPath", outputPath));
Tasks.waitFor(1, () -> getProgramRuns(workflowId, ProgramRunStatus.COMPLETED).size(), 60, TimeUnit.SECONDS);
List<RunRecord> programRuns = getProgramRuns(workflowId, ProgramRunStatus.COMPLETED);
Assert.assertEquals(1, programRuns.size());
RunRecord runRecord = programRuns.get(0);
String pid = runRecord.getPid();
// Verify entire worfklow token
WorkflowTokenDetail workflowTokenDetail = getWorkflowToken(workflowId, pid, null, null);
List<WorkflowTokenDetail.NodeValueDetail> nodeValueDetails = workflowTokenDetail.getTokenData().get(AppWithWorkflow.DummyAction.TOKEN_KEY);
Assert.assertEquals(2, nodeValueDetails.size());
Assert.assertEquals(AppWithWorkflow.SampleWorkflow.FIRST_ACTION, nodeValueDetails.get(0).getNode());
Assert.assertEquals(AppWithWorkflow.SampleWorkflow.SECOND_ACTION, nodeValueDetails.get(1).getNode());
Assert.assertEquals(AppWithWorkflow.DummyAction.TOKEN_VALUE, nodeValueDetails.get(0).getValue());
Assert.assertEquals(AppWithWorkflow.DummyAction.TOKEN_VALUE, nodeValueDetails.get(1).getValue());
// Verify entire workflow token by passing in the scope and key in the request
workflowTokenDetail = getWorkflowToken(workflowId, pid, WorkflowToken.Scope.USER, AppWithWorkflow.DummyAction.TOKEN_KEY);
nodeValueDetails = workflowTokenDetail.getTokenData().get(AppWithWorkflow.DummyAction.TOKEN_KEY);
Assert.assertEquals(2, nodeValueDetails.size());
Assert.assertEquals(AppWithWorkflow.SampleWorkflow.FIRST_ACTION, nodeValueDetails.get(0).getNode());
Assert.assertEquals(AppWithWorkflow.SampleWorkflow.SECOND_ACTION, nodeValueDetails.get(1).getNode());
Assert.assertEquals(AppWithWorkflow.DummyAction.TOKEN_VALUE, nodeValueDetails.get(0).getValue());
Assert.assertEquals(AppWithWorkflow.DummyAction.TOKEN_VALUE, nodeValueDetails.get(1).getValue());
// Get workflow level tokens
WorkflowTokenNodeDetail nodeDetail = getWorkflowToken(workflowId, pid, AppWithWorkflow.SampleWorkflow.NAME, WorkflowToken.Scope.USER, null);
Map<String, String> tokenData = nodeDetail.getTokenDataAtNode();
Assert.assertEquals(2, tokenData.size());
Assert.assertEquals(AppWithWorkflow.SampleWorkflow.INITIALIZE_TOKEN_VALUE, tokenData.get(AppWithWorkflow.SampleWorkflow.INITIALIZE_TOKEN_KEY));
Assert.assertEquals(AppWithWorkflow.SampleWorkflow.DESTROY_TOKEN_SUCCESS_VALUE, tokenData.get(AppWithWorkflow.SampleWorkflow.DESTROY_TOKEN_KEY));
// Verify workflow token at a given node
WorkflowTokenNodeDetail tokenAtNode = getWorkflowToken(workflowId, pid, AppWithWorkflow.SampleWorkflow.FIRST_ACTION, null, null);
Map<String, String> tokenDataAtNode = tokenAtNode.getTokenDataAtNode();
Assert.assertEquals(1, tokenDataAtNode.size());
Assert.assertEquals(AppWithWorkflow.DummyAction.TOKEN_VALUE, tokenDataAtNode.get(AppWithWorkflow.DummyAction.TOKEN_KEY));
// Verify workflow token at a given node by passing in a scope and a key
tokenAtNode = getWorkflowToken(workflowId, pid, AppWithWorkflow.SampleWorkflow.FIRST_ACTION, WorkflowToken.Scope.USER, AppWithWorkflow.DummyAction.TOKEN_KEY);
tokenDataAtNode = tokenAtNode.getTokenDataAtNode();
Assert.assertEquals(1, tokenDataAtNode.size());
Assert.assertEquals(AppWithWorkflow.DummyAction.TOKEN_VALUE, tokenDataAtNode.get(AppWithWorkflow.DummyAction.TOKEN_KEY));
}
use of io.cdap.cdap.proto.WorkflowTokenNodeDetail in project cdap by caskdata.
the class WorkflowHttpHandler method getWorkflowToken.
@GET
@Path("/apps/{app-id}/workflows/{workflow-id}/runs/{run-id}/nodes/{node-id}/token")
public void getWorkflowToken(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("app-id") String appId, @PathParam("workflow-id") String workflowId, @PathParam("run-id") String runId, @PathParam("node-id") String nodeId, @QueryParam("scope") @DefaultValue("user") String scope, @QueryParam("key") @DefaultValue("") String key) throws NotFoundException {
WorkflowToken workflowToken = getWorkflowToken(namespaceId, appId, workflowId, runId);
WorkflowToken.Scope tokenScope = WorkflowToken.Scope.valueOf(scope.toUpperCase());
Map<String, Value> workflowTokenFromNode = workflowToken.getAllFromNode(nodeId, tokenScope);
WorkflowTokenNodeDetail tokenAtNode = WorkflowTokenNodeDetail.of(workflowTokenFromNode);
Type workflowTokenNodeDetailType = new TypeToken<WorkflowTokenNodeDetail>() {
}.getType();
if (key.isEmpty()) {
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(tokenAtNode, workflowTokenNodeDetailType));
return;
}
if (!workflowTokenFromNode.containsKey(key)) {
throw new NotFoundException(key);
}
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(WorkflowTokenNodeDetail.of(Collections.singletonMap(key, workflowTokenFromNode.get(key))), workflowTokenNodeDetailType));
}
use of io.cdap.cdap.proto.WorkflowTokenNodeDetail in project cdap by caskdata.
the class TestFrameworkTestRun method testWorkflowCondition.
@Test
public void testWorkflowCondition() throws Exception {
ApplicationManager applicationManager = deployApplication(testSpace, ConditionalWorkflowApp.class);
final WorkflowManager wfmanager = applicationManager.getWorkflowManager("ConditionalWorkflow");
wfmanager.start(ImmutableMap.of("configurable.condition", "true"));
Tasks.waitFor(true, new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return wfmanager.getHistory(ProgramRunStatus.COMPLETED).size() == 1;
}
}, 30, TimeUnit.SECONDS, 100, TimeUnit.MILLISECONDS);
List<RunRecord> history = wfmanager.getHistory();
String pid = history.get(0).getPid();
WorkflowTokenNodeDetail tokenNodeDetail = wfmanager.getTokenAtNode(pid, "MyConfigurableCondition", WorkflowToken.Scope.USER, null);
Map<String, String> expected = ImmutableMap.of("configurable.condition.initialize", "true", "configurable.condition.destroy", "true", "configurable.condition.apply", "true");
Assert.assertEquals(expected, tokenNodeDetail.getTokenDataAtNode());
tokenNodeDetail = wfmanager.getTokenAtNode(pid, "SimpleCondition", WorkflowToken.Scope.USER, null);
expected = ImmutableMap.of("simple.condition.initialize", "true");
Assert.assertEquals(expected, tokenNodeDetail.getTokenDataAtNode());
tokenNodeDetail = wfmanager.getTokenAtNode(pid, "action2", WorkflowToken.Scope.USER, null);
expected = ImmutableMap.of("action.name", "action2");
Assert.assertEquals(expected, tokenNodeDetail.getTokenDataAtNode());
}
use of io.cdap.cdap.proto.WorkflowTokenNodeDetail in project cdap by caskdata.
the class TestFrameworkTestRun method testDeployWorkflowApp.
@Category(XSlowTests.class)
@Test
@Ignore
public void testDeployWorkflowApp() throws Exception {
// Add test back when CDAP-12350 is resolved
ApplicationManager applicationManager = deployApplication(testSpace, AppWithSchedule.class);
final WorkflowManager wfmanager = applicationManager.getWorkflowManager(AppWithSchedule.WORKFLOW_NAME);
List<ScheduleDetail> schedules = wfmanager.getProgramSchedules();
Assert.assertEquals(2, schedules.size());
String scheduleName = schedules.get(1).getName();
Assert.assertNotNull(scheduleName);
Assert.assertFalse(scheduleName.isEmpty());
final int initialRuns = wfmanager.getHistory().size();
LOG.info("initialRuns = {}", initialRuns);
wfmanager.getSchedule(scheduleName).resume();
String status = wfmanager.getSchedule(scheduleName).status(200);
Assert.assertEquals("SCHEDULED", status);
// Make sure something ran before suspending
Tasks.waitFor(true, new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return wfmanager.getHistory().size() > 0;
}
}, 15, TimeUnit.SECONDS);
wfmanager.getSchedule(scheduleName).suspend();
waitForScheduleState(scheduleName, wfmanager, ProgramScheduleStatus.SUSPENDED);
// All runs should be completed
Tasks.waitFor(true, new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
for (RunRecord record : wfmanager.getHistory()) {
if (record.getStatus() != ProgramRunStatus.COMPLETED) {
return false;
}
}
return true;
}
}, 15, TimeUnit.SECONDS);
List<RunRecord> history = wfmanager.getHistory();
int workflowRuns = history.size();
LOG.info("workflowRuns = {}", workflowRuns);
Assert.assertTrue(workflowRuns > 0);
// Sleep for some time and verify there are no more scheduled jobs after the suspend.
TimeUnit.SECONDS.sleep(5);
final int workflowRunsAfterSuspend = wfmanager.getHistory().size();
Assert.assertEquals(workflowRuns, workflowRunsAfterSuspend);
wfmanager.getSchedule(scheduleName).resume();
// Check that after resume it goes to "SCHEDULED" state
waitForScheduleState(scheduleName, wfmanager, ProgramScheduleStatus.SCHEDULED);
// Make sure new runs happens after resume
Tasks.waitFor(true, new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return wfmanager.getHistory().size() > workflowRunsAfterSuspend;
}
}, 15, TimeUnit.SECONDS);
// Check scheduled state
Assert.assertEquals("SCHEDULED", wfmanager.getSchedule(scheduleName).status(200));
// Check status of non-existent schedule
Assert.assertEquals("NOT_FOUND", wfmanager.getSchedule("doesnt exist").status(404));
// Suspend the schedule
wfmanager.getSchedule(scheduleName).suspend();
// Check that after suspend it goes to "SUSPENDED" state
waitForScheduleState(scheduleName, wfmanager, ProgramScheduleStatus.SUSPENDED);
// Test workflow token while suspended
String pid = history.get(0).getPid();
WorkflowTokenDetail workflowToken = wfmanager.getToken(pid, WorkflowToken.Scope.SYSTEM, null);
Assert.assertEquals(0, workflowToken.getTokenData().size());
workflowToken = wfmanager.getToken(pid, null, null);
Assert.assertEquals(2, workflowToken.getTokenData().size());
// Wait for all workflow runs to finish execution, in case more than one run happened with an enabled schedule
Tasks.waitFor(true, new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
for (RunRecord record : wfmanager.getHistory()) {
if (record.getStatus() != ProgramRunStatus.COMPLETED) {
return false;
}
}
return true;
}
}, 15, TimeUnit.SECONDS);
// Verify workflow token after workflow completion
WorkflowTokenNodeDetail workflowTokenAtNode = wfmanager.getTokenAtNode(pid, AppWithSchedule.DummyAction.class.getSimpleName(), WorkflowToken.Scope.USER, "finished");
Assert.assertEquals(true, Boolean.parseBoolean(workflowTokenAtNode.getTokenDataAtNode().get("finished")));
workflowToken = wfmanager.getToken(pid, null, null);
Assert.assertEquals(false, Boolean.parseBoolean(workflowToken.getTokenData().get("running").get(0).getValue()));
}
Aggregations