use of io.cdap.cdap.proto.BasicThrowable in project cdap by cdapio.
the class SystemWorkerServiceTest method testStartAndStopWithInvalidRequest.
@Test
public void testStartAndStopWithInvalidRequest() throws Exception {
InetSocketAddress addr = systemWorkerService.getBindAddress();
URI uri = URI.create(String.format("http://%s:%s", addr.getHostName(), addr.getPort()));
// Post invalid request
RunnableTaskRequest noClassReq = RunnableTaskRequest.getBuilder("NoClass").build();
String reqBody = GSON.toJson(noClassReq);
HttpResponse response = HttpRequests.execute(HttpRequest.post(uri.resolve("/v3Internal/system/run").toURL()).withBody(reqBody).build(), new DefaultHttpRequestConfig(false));
Assert.assertEquals(HttpURLConnection.HTTP_BAD_REQUEST, response.getResponseCode());
BasicThrowable basicThrowable;
basicThrowable = GSON.fromJson(response.getResponseBodyAsString(), BasicThrowable.class);
Assert.assertTrue(basicThrowable.getClassName().contains("java.lang.ClassNotFoundException"));
Assert.assertNotNull(basicThrowable.getMessage());
Assert.assertTrue(basicThrowable.getMessage().contains("NoClass"));
Assert.assertNotEquals(basicThrowable.getStackTraces().length, 0);
}
use of io.cdap.cdap.proto.BasicThrowable in project cdap by cdapio.
the class ProgramNotificationSubscriberService method handleProgramCompletion.
/**
* Handles a program completion notification.
*
* @param appMetadataStore the {@link AppMetadataStore} to write the status to
* @param programHeartbeatTable the {@link ProgramHeartbeatTable} to write the status to
* @param programRunId the program run of the completed program
* @param programRunStatus the status of the completion
* @param notification the {@link Notification} that carries information about the program completion
* @param sourceId the source message id of the notification
* @param runnables a {@link List} adding {@link Runnable} to be executed after event handling is completed
* @return a {@link RunRecordDetail} that carries the result of updates to {@link AppMetadataStore}. If there
* is no update, {@code null} will be returned
* @throws Exception if failed to update program status
*/
@Nullable
private RunRecordDetail handleProgramCompletion(AppMetadataStore appMetadataStore, ProgramHeartbeatTable programHeartbeatTable, ProgramRunId programRunId, ProgramRunStatus programRunStatus, Notification notification, byte[] sourceId, List<Runnable> runnables) throws Exception {
Map<String, String> properties = notification.getProperties();
long endTimeSecs = getTimeSeconds(properties, ProgramOptionConstants.END_TIME);
if (endTimeSecs == -1) {
LOG.warn("Ignore program {} notification for program {} without end time specified, {}", programRunStatus.name().toLowerCase(), programRunId, notification);
return null;
}
BasicThrowable failureCause = decodeBasicThrowable(properties.get(ProgramOptionConstants.PROGRAM_ERROR));
// If there is any states missing, it will be handled here.
if (programRunId.getType() == ProgramType.WORKFLOW) {
processWorkflowOnStop(appMetadataStore, programHeartbeatTable, programRunId, programRunStatus, notification, sourceId, runnables);
}
RunRecordDetailWithExistingStatus recordedRunRecord = appMetadataStore.recordProgramStop(programRunId, endTimeSecs, programRunStatus, failureCause, sourceId);
if (recordedRunRecord != null) {
writeToHeartBeatTable(recordedRunRecord, endTimeSecs, programHeartbeatTable);
getEmitMetricsRunnable(programRunId, recordedRunRecord, STATUS_METRICS_NAME.get(programRunStatus), recordedRunRecord.getExistingStatus()).ifPresent(runnables::add);
// emit program run time metric.
long runTime = endTimeSecs - RunIds.getTime(programRunId.getRun(), TimeUnit.SECONDS);
SystemArguments.getProfileIdFromArgs(programRunId.getNamespaceId(), recordedRunRecord.getSystemArgs()).ifPresent(profileId -> {
emitRunTimeMetric(programRunId, programRunStatus, runTime, recordedRunRecord);
emitStoppingTimeMetric(programRunId, profileId, recordedRunRecord);
});
runnables.add(() -> {
programCompletionNotifiers.forEach(notifier -> notifier.onProgramCompleted(programRunId, recordedRunRecord.getStatus()));
runRecordMonitorService.removeRequest(programRunId, true);
});
}
return recordedRunRecord;
}
use of io.cdap.cdap.proto.BasicThrowable in project cdap by cdapio.
the class RunRecordCorrectorServiceTest method testFixUnderlyingProgramInWorkflow.
@Test
public void testFixUnderlyingProgramInWorkflow() throws Exception {
AtomicInteger sourceId = new AtomicInteger(0);
ArtifactId artifactId = NamespaceId.DEFAULT.artifact("testArtifact", "1.0").toApiArtifactId();
// set up a workflow
Map<String, String> wfSystemArg = ImmutableMap.of(ProgramOptionConstants.CLUSTER_MODE, ClusterMode.ISOLATED.name(), SystemArguments.PROFILE_NAME, ProfileId.NATIVE.getScopedName());
ProgramRunId wfId = NamespaceId.DEFAULT.app("test").workflow("testWF").run(randomRunId());
store.setProvisioning(wfId, Collections.emptyMap(), wfSystemArg, Bytes.toBytes(sourceId.getAndIncrement()), artifactId);
store.setProvisioned(wfId, 0, Bytes.toBytes(sourceId.getAndIncrement()));
store.setStart(wfId, null, Collections.emptyMap(), Bytes.toBytes(sourceId.getAndIncrement()));
store.setRunning(wfId, System.currentTimeMillis(), null, Bytes.toBytes(sourceId.getAndIncrement()));
// set up a spark program inside workflow, and in ISOLATED mode
Map<String, String> spSystemArgs = ImmutableMap.of(ProgramOptionConstants.CLUSTER_MODE, ClusterMode.ISOLATED.name(), SystemArguments.PROFILE_NAME, ProfileId.NATIVE.getScopedName(), ProgramOptionConstants.WORKFLOW_NAME, wfId.getProgram(), ProgramOptionConstants.WORKFLOW_RUN_ID, wfId.getRun(), ProgramOptionConstants.WORKFLOW_NODE_ID, "spark");
ProgramRunId spId = NamespaceId.DEFAULT.app("test").spark("phase-1").run(randomRunId());
store.setProvisioning(spId, Collections.emptyMap(), spSystemArgs, Bytes.toBytes(sourceId.getAndIncrement()), artifactId);
store.setProvisioned(spId, 0, Bytes.toBytes(sourceId.getAndIncrement()));
store.setStart(spId, null, Collections.emptyMap(), Bytes.toBytes(sourceId.getAndIncrement()));
store.setRunning(spId, System.currentTimeMillis(), null, Bytes.toBytes(sourceId.getAndIncrement()));
// mark the workflow as finished
store.setStop(wfId, System.currentTimeMillis(), ProgramRunStatus.COMPLETED, Bytes.toBytes(sourceId.getAndIncrement()));
ProgramStateWriter programStateWriter = new NoOpProgramStateWriter() {
@Override
public void error(ProgramRunId programRunId, Throwable failureCause) {
store.setStop(programRunId, System.currentTimeMillis(), ProgramRunStatus.FAILED, new BasicThrowable(failureCause), Bytes.toBytes(sourceId.getAndIncrement()));
}
};
ProgramRuntimeService noOpRuntimeSerivce = new AbstractProgramRuntimeService(cConf, null, new NoOpProgramStateWriter(), null, false) {
@Override
public ProgramLiveInfo getLiveInfo(ProgramId programId) {
return new NotRunningProgramLiveInfo(programId);
}
@Override
public Map<RunId, RuntimeInfo> list(ProgramId program) {
return Collections.emptyMap();
}
};
// Create a run record fixer.
// Set the start buffer time to -1 so that it fixes right away.
RunRecordCorrectorService fixer = new RunRecordCorrectorService(cConf, store, programStateWriter, noOpRuntimeSerivce, namespaceAdmin, datasetFramework, -1L, 5) {
};
fixer.fixRunRecords();
// check the record is fixed for spark program
Assert.assertEquals(ProgramRunStatus.FAILED, store.getRun(spId).getStatus());
}
use of io.cdap.cdap.proto.BasicThrowable in project cdap by cdapio.
the class RemoteExecutionException method fromBasicThrowable.
/**
* Converts a {@link BasicThrowable} to a RemoteExecutionException.
*
* @return An exception which retains the local stacktrace.
*/
public static RemoteExecutionException fromBasicThrowable(BasicThrowable basicThrowable) {
BasicThrowable cause = basicThrowable.getCause();
Exception causeException = cause == null ? null : fromBasicThrowable(cause);
RemoteTaskException remoteTaskException = new RemoteTaskException(basicThrowable.getClassName(), basicThrowable.getMessage(), causeException);
remoteTaskException.setStackTrace(basicThrowable.getStackTraces());
// Wrap the remote exception as the cause so that we retain the local stacktrace of the exception.
return new RemoteExecutionException(remoteTaskException);
}
use of io.cdap.cdap.proto.BasicThrowable in project cdap by cdapio.
the class DefaultPreviewRunner method startPreview.
@Override
public Future<PreviewRequest> startPreview(PreviewRequest previewRequest) throws Exception {
ProgramId programId = previewRequest.getProgram();
long submitTimeMillis = RunIds.getTime(programId.getApplication(), TimeUnit.MILLISECONDS);
previewStarted(programId);
AppRequest<?> request = previewRequest.getAppRequest();
if (request == null) {
// This shouldn't happen
throw new IllegalStateException("Preview request shouldn't have an empty application request");
}
ArtifactSummary artifactSummary = request.getArtifact();
ApplicationId preview = programId.getParent();
try {
namespaceAdmin.create(new NamespaceMeta.Builder().setName(programId.getNamespaceId()).build());
} catch (NamespaceAlreadyExistsException e) {
LOG.debug("Namespace {} already exists.", programId.getNamespaceId());
}
DataTracerFactoryProvider.setDataTracerFactory(preview, dataTracerFactory);
String config = request.getConfig() == null ? null : GSON.toJson(request.getConfig());
PreviewConfig previewConfig = previewRequest.getAppRequest().getPreview();
PreferencesDetail preferences = preferencesFetcher.get(programId, true);
Map<String, String> userProps = new HashMap<>(preferences.getProperties());
if (previewConfig != null) {
userProps.putAll(previewConfig.getRuntimeArgs());
}
try {
LOG.debug("Deploying preview application for {}", programId);
applicationLifecycleService.deployApp(preview.getParent(), preview.getApplication(), preview.getVersion(), artifactSummary, config, NOOP_PROGRAM_TERMINATOR, null, request.canUpdateSchedules(), true, userProps);
} catch (Exception e) {
PreviewStatus previewStatus = new PreviewStatus(PreviewStatus.Status.DEPLOY_FAILED, submitTimeMillis, new BasicThrowable(e), null, null);
previewTerminated(programId, previewStatus);
throw e;
}
LOG.debug("Starting preview for {}", programId);
ProgramController controller = programLifecycleService.start(programId, userProps, false, true);
long startTimeMillis = System.currentTimeMillis();
AtomicBoolean timeout = new AtomicBoolean();
CompletableFuture<PreviewRequest> resultFuture = new CompletableFuture<>();
controller.addListener(new AbstractListener() {
@Override
public void init(ProgramController.State currentState, @Nullable Throwable cause) {
switch(currentState) {
case STARTING:
case ALIVE:
case STOPPING:
setStatus(programId, new PreviewStatus(PreviewStatus.Status.RUNNING, submitTimeMillis, null, startTimeMillis, null));
break;
case COMPLETED:
terminated(PreviewStatus.Status.COMPLETED, null);
break;
case KILLED:
terminated(PreviewStatus.Status.KILLED, null);
break;
case ERROR:
terminated(PreviewStatus.Status.RUN_FAILED, cause);
break;
}
}
@Override
public void completed() {
terminated(PreviewStatus.Status.COMPLETED, null);
}
@Override
public void killed() {
terminated(timeout.get() ? PreviewStatus.Status.KILLED_BY_TIMER : PreviewStatus.Status.KILLED, null);
}
@Override
public void error(Throwable cause) {
terminated(PreviewStatus.Status.RUN_FAILED, cause);
}
/**
* Handle termination of program run.
*
* @param status the termination status
* @param failureCause if the program was terminated due to error, this carries the failure cause
*/
private void terminated(PreviewStatus.Status status, @Nullable Throwable failureCause) {
PreviewStatus previewStatus = new PreviewStatus(status, submitTimeMillis, failureCause == null ? null : new BasicThrowable(failureCause), startTimeMillis, System.currentTimeMillis());
previewTerminated(programId, previewStatus);
if (failureCause == null) {
resultFuture.complete(previewRequest);
} else {
resultFuture.completeExceptionally(failureCause);
}
}
}, Threads.SAME_THREAD_EXECUTOR);
trackPreviewTimeout(previewRequest, timeout, resultFuture);
PreviewMessage message = new PreviewMessage(PreviewMessage.Type.PROGRAM_RUN_ID, programId.getParent(), GSON.toJsonTree(controller.getProgramRunId()));
previewDataPublisher.publish(programId.getParent(), message);
return resultFuture;
}
Aggregations