use of co.cask.cdap.common.ConflictException in project cdap by caskdata.
the class AppLifecycleHttpHandler method updateApp.
/**
* Updates an existing application.
*/
@POST
@Path("/apps/{app-id}/update")
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void updateApp(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") final String namespaceId, @PathParam("app-id") final String appName) throws NotFoundException, BadRequestException, UnauthorizedException, IOException {
ApplicationId appId = validateApplicationId(namespaceId, appName);
AppRequest appRequest;
try (Reader reader = new InputStreamReader(new ChannelBufferInputStream(request.getContent()), Charsets.UTF_8)) {
appRequest = GSON.fromJson(reader, AppRequest.class);
} catch (IOException e) {
LOG.error("Error reading request to update app {} in namespace {}.", appName, namespaceId, e);
throw new IOException("Error reading request body.");
} catch (JsonSyntaxException e) {
throw new BadRequestException("Request body is invalid json: " + e.getMessage());
}
try {
applicationLifecycleService.updateApp(appId, appRequest, createProgramTerminator());
responder.sendString(HttpResponseStatus.OK, "Update complete.");
} catch (InvalidArtifactException e) {
throw new BadRequestException(e.getMessage());
} catch (ConflictException e) {
responder.sendString(HttpResponseStatus.CONFLICT, e.getMessage());
} catch (NotFoundException | UnauthorizedException e) {
throw e;
} catch (Exception e) {
// this is the same behavior as deploy app pipeline, but this is bad behavior. Error handling needs improvement.
LOG.error("Deploy failure", e);
responder.sendString(HttpResponseStatus.BAD_REQUEST, e.getMessage());
}
}
use of co.cask.cdap.common.ConflictException in project cdap by caskdata.
the class SchedulerTestBase method testStreamSizeSchedule.
@Test
public void testStreamSizeSchedule() throws Exception {
// Test the StreamSizeScheduler behavior using notifications
AppFabricTestHelper.deployApplicationWithManager(AppWithStreamSizeSchedule.class, TEMP_FOLDER_SUPPLIER);
Assert.assertEquals(ProgramScheduleStatus.SUSPENDED, scheduler.getScheduleStatus(SCHEDULE_ID_1));
Assert.assertEquals(ProgramScheduleStatus.SUSPENDED, scheduler.getScheduleStatus(SCHEDULE_ID_2));
scheduler.enableSchedule(SCHEDULE_ID_1);
scheduler.enableSchedule(SCHEDULE_ID_2);
Assert.assertEquals(ProgramScheduleStatus.SCHEDULED, scheduler.getScheduleStatus(SCHEDULE_ID_1));
Assert.assertEquals(ProgramScheduleStatus.SCHEDULED, scheduler.getScheduleStatus(SCHEDULE_ID_2));
int runs = store.getRuns(PROGRAM_ID, ProgramRunStatus.ALL, 0, Long.MAX_VALUE, 100).size();
Assert.assertEquals(0, runs);
StreamMetricsPublisher metricsPublisher = createMetricsPublisher(STREAM_ID);
// Publish a notification on behalf of the stream with enough data to trigger the execution of the job
metricsPublisher.increment(1024 * 1024);
waitForRuns(store, PROGRAM_ID, 1, 15);
waitUntilFinished(runtimeService, PROGRAM_ID, 15);
// Trigger both scheduled program
metricsPublisher.increment(1024 * 1024);
waitForRuns(store, PROGRAM_ID, 3, 15);
// Suspend a schedule multiple times, and make sur that it doesn't mess up anything
scheduler.disableSchedule(SCHEDULE_ID_2);
try {
scheduler.disableSchedule(SCHEDULE_ID_2);
Assert.fail("disable() should have failed because schedule was already disabled");
} catch (ConflictException e) {
// expected
}
Assert.assertEquals(ProgramScheduleStatus.SUSPENDED, scheduler.getScheduleStatus(SCHEDULE_ID_2));
// Since schedule 2 is suspended, only the first schedule should get triggered
metricsPublisher.increment(1024 * 1024);
waitForRuns(store, PROGRAM_ID, 4, 15);
// Resume schedule 2
scheduler.enableSchedule(SCHEDULE_ID_2);
try {
scheduler.enableSchedule(SCHEDULE_ID_2);
Assert.fail("enable() should have failed because schedule was already enabled");
} catch (ConflictException e) {
// expected
}
Assert.assertEquals(ProgramScheduleStatus.SCHEDULED, scheduler.getScheduleStatus(SCHEDULE_ID_2));
// Both schedules should be trigger. In particular, the schedule that has just been resumed twice should
// only trigger once
metricsPublisher.increment(1024 * 1024);
waitForRuns(store, PROGRAM_ID, 6, 15);
// Update the schedule2's data trigger
// Both schedules should now trigger execution after 1 MB of data received
scheduler.updateSchedule(UPDATE_SCHEDULE_2);
metricsPublisher.increment(1024 * 1024);
waitForRuns(store, PROGRAM_ID, 8, 15);
scheduler.disableSchedule(SCHEDULE_ID_1);
scheduler.disableSchedule(SCHEDULE_ID_2);
waitUntilFinished(runtimeService, PROGRAM_ID, 10);
}
use of co.cask.cdap.common.ConflictException in project cdap by caskdata.
the class TestFrameworkTestRun method testConcurrentRuns.
@Test
public void testConcurrentRuns() throws Exception {
ApplicationManager appManager = deployApplication(ConcurrentRunTestApp.class);
WorkerManager workerManager = appManager.getWorkerManager(ConcurrentRunTestApp.TestWorker.class.getSimpleName());
workerManager.start();
// Start another time should fail as worker doesn't support concurrent run.
workerManager.waitForStatus(true);
try {
workerManager.start();
Assert.fail("Expected failure to start worker");
} catch (Exception e) {
Assert.assertTrue(Throwables.getRootCause(e) instanceof ConflictException);
}
workerManager.stop();
// Start the workflow
File tmpDir = TEMP_FOLDER.newFolder();
File actionFile = new File(tmpDir, "action.file");
Map<String, String> args = Collections.singletonMap("action.file", actionFile.getAbsolutePath());
WorkflowManager workflowManager = appManager.getWorkflowManager(ConcurrentRunTestApp.TestWorkflow.class.getSimpleName());
// Starts two runs, both should succeed
workflowManager.start(args);
workflowManager.start(args);
// Should get two active runs
workflowManager.waitForRuns(ProgramRunStatus.RUNNING, 2, 10L, TimeUnit.SECONDS);
// Touch the file to complete the workflow runs
Files.touch(actionFile);
workflowManager.waitForRuns(ProgramRunStatus.COMPLETED, 2, 10L, TimeUnit.SECONDS);
}
use of co.cask.cdap.common.ConflictException in project cdap by caskdata.
the class DatasetClient method update.
/**
* Updates the properties of a dataset.
*
* @param instance the dataset to update
* @param properties properties to set
* @throws NotFoundException if the dataset is not found
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public void update(DatasetId instance, Map<String, String> properties) throws NotFoundException, IOException, UnauthenticatedException, ConflictException, UnauthorizedException {
URL url = config.resolveNamespacedURLV3(instance.getParent(), String.format("data/datasets/%s/properties", instance.getDataset()));
HttpRequest request = HttpRequest.put(url).withBody(GSON.toJson(properties)).build();
HttpResponse response = restClient.execute(request, config.getAccessToken(), HttpURLConnection.HTTP_NOT_FOUND, HttpURLConnection.HTTP_CONFLICT);
if (response.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
throw new NotFoundException(instance);
} else if (response.getResponseCode() == HttpURLConnection.HTTP_CONFLICT) {
throw new ConflictException(response.getResponseBodyAsString());
}
}
use of co.cask.cdap.common.ConflictException in project cdap by caskdata.
the class ProgramLifecycleService method start.
/**
* Starts a Program with the specified argument overrides.
*
* @param programId the {@link ProgramId} to start/stop
* @param overrides the arguments to override in the program's configured user arguments before starting
* @param debug {@code true} if the program is to be started in debug mode, {@code false} otherwise
* @return {@link ProgramController}
* @throws ConflictException if the specified program is already running, and if concurrent runs are not allowed
* @throws NotFoundException if the specified program or the app it belongs to is not found in the specified namespace
* @throws IOException if there is an error starting the program
* @throws UnauthorizedException if the logged in user is not authorized to start the program. To start a program,
* a user requires {@link Action#EXECUTE} on the program
* @throws Exception if there were other exceptions checking if the current user is authorized to start the program
*/
public synchronized ProgramController start(ProgramId programId, Map<String, String> overrides, boolean debug) throws Exception {
authorizationEnforcer.enforce(programId, authenticationContext.getPrincipal(), Action.EXECUTE);
if (isConcurrentRunsInSameAppForbidden(programId.getType()) && isRunningInSameProgram(programId)) {
throw new ConflictException(String.format("Program %s is already running in an version of the same application", programId));
}
if (isRunning(programId) && !isConcurrentRunsAllowed(programId.getType())) {
throw new ConflictException(String.format("Program %s is already running", programId));
}
Map<String, String> sysArgs = propertiesResolver.getSystemProperties(Id.Program.fromEntityId(programId));
Map<String, String> userArgs = propertiesResolver.getUserProperties(Id.Program.fromEntityId(programId));
if (overrides != null) {
userArgs.putAll(overrides);
}
ProgramRuntimeService.RuntimeInfo runtimeInfo = startInternal(programId, sysArgs, userArgs, debug);
if (runtimeInfo == null) {
throw new IOException(String.format("Failed to start program %s", programId));
}
return runtimeInfo.getController();
}
Aggregations