use of io.cdap.cdap.api.security.AccessException 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(FullHttpRequest request, HttpResponder responder, @PathParam("namespace-id") final String namespaceId, @PathParam("app-id") final String appName) throws NotFoundException, BadRequestException, AccessException, IOException {
ApplicationId appId = validateApplicationId(namespaceId, appName);
AppRequest appRequest;
try (Reader reader = new InputStreamReader(new ByteBufInputStream(request.content()), StandardCharsets.UTF_8)) {
appRequest = DECODE_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 io.cdap.cdap.api.security.AccessException in project cdap by caskdata.
the class CoreSchedulerService method getProgramScheduleWithUserAndArtifactId.
/**
* Gets a copy of the given {@link ProgramSchedule} and add user and artifact ID in the schedule properties
* TODO CDAP-13662 - move logic to find artifactId and userId to dashboard service and remove this method
*/
private ProgramSchedule getProgramScheduleWithUserAndArtifactId(ProgramSchedule schedule) {
Map<String, String> additionalProperties = new HashMap<>();
// add artifact id to the schedule property
ProgramDescriptor programDescriptor;
try {
programDescriptor = appMetaStore.loadProgram(schedule.getProgramId());
} catch (Exception e) {
LOG.error("Exception occurs when looking up program descriptor for program {} in schedule {}", schedule.getProgramId(), schedule, e);
throw new RuntimeException(String.format("Exception occurs when looking up program descriptor for" + " program %s in schedule %s", schedule.getProgramId(), schedule), e);
}
additionalProperties.put(ProgramOptionConstants.ARTIFACT_ID, GSON.toJson(programDescriptor.getArtifactId().toApiArtifactId()));
String userId;
try {
userId = impersonator.getUGI(schedule.getProgramId()).getUserName();
} catch (AccessException e) {
LOG.error("Exception occurs when looking up user group information for program {} in schedule {}", schedule.getProgramId(), schedule, e);
throw new RuntimeException(String.format("Exception occurs when looking up user group information for" + " program %s in schedule %s", schedule.getProgramId(), schedule), e);
}
// add the user name to the schedule property
additionalProperties.put(ProgramOptionConstants.USER_ID, userId);
// make a copy of the existing schedule properties and add the additional properties in the copy
Map<String, String> newProperties = new HashMap<>(schedule.getProperties());
newProperties.putAll(additionalProperties);
// construct a copy of the schedule with the additional properties added
return new ProgramSchedule(schedule.getName(), schedule.getDescription(), schedule.getProgramId(), newProperties, schedule.getTrigger(), schedule.getConstraints(), schedule.getTimeoutMillis());
}
use of io.cdap.cdap.api.security.AccessException in project cdap by caskdata.
the class ImpersonationHandler method getCredentials.
@POST
@Path("/credentials")
public void getCredentials(FullHttpRequest request, HttpResponder responder) throws Exception {
String requestContent = request.content().toString(StandardCharsets.UTF_8);
if (requestContent == null) {
throw new BadRequestException("Request body is empty.");
}
ImpersonationRequest impersonationRequest = GSON.fromJson(requestContent, ImpersonationRequest.class);
LOG.debug("Fetching credentials for {}", impersonationRequest);
UGIWithPrincipal ugiWithPrincipal;
try {
ugiWithPrincipal = ugiProvider.getConfiguredUGI(impersonationRequest);
} catch (AccessException e) {
throw new ServiceException(e, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
Credentials credentials = ImpersonationUtils.doAs(ugiWithPrincipal.getUGI(), new Callable<Credentials>() {
@Override
public Credentials call() throws Exception {
return tokenSecureStoreRenewer.createCredentials();
}
});
// example: hdfs:///cdap/credentials
Location credentialsDir = locationFactory.create("credentials");
if (credentialsDir.isDirectory() || credentialsDir.mkdirs() || credentialsDir.isDirectory()) {
// the getTempFile() doesn't create the file within the directory that you call it on. It simply appends the path
// without a separator, which is why we manually append the "tmp"
// example: hdfs:///cdap/credentials/tmp.5960fe60-6fd8-4f3e-8e92-3fb6d4726006.credentials
Location credentialsFile = credentialsDir.append("tmp").getTempFile(".credentials");
// 600 is owner-only READ_WRITE
try (DataOutputStream os = new DataOutputStream(new BufferedOutputStream(credentialsFile.getOutputStream("600")))) {
credentials.writeTokenStorageToStream(os);
}
LOG.debug("Wrote credentials for user {} to {}", ugiWithPrincipal.getPrincipal(), credentialsFile);
PrincipalCredentials principalCredentials = new PrincipalCredentials(ugiWithPrincipal.getPrincipal(), credentialsFile.toURI().toString());
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(principalCredentials));
} else {
throw new IllegalStateException("Unable to create credentials directory.");
}
}
use of io.cdap.cdap.api.security.AccessException in project cdap by caskdata.
the class AbstractContext method createRuntimeProgramContext.
/**
* Creates a new instance of {@link RuntimeProgramContext} to be
* provided to {@link RuntimeProgramContextAware} dataset.
*/
private RuntimeProgramContext createRuntimeProgramContext(final DatasetId datasetId) {
return new RuntimeProgramContext() {
@Override
public void notifyNewPartitions(Collection<? extends PartitionKey> partitionKeys) throws IOException {
String topic = cConf.get(Constants.Dataset.DATA_EVENT_TOPIC);
if (Strings.isNullOrEmpty(topic)) {
// Don't publish if there is no data event topic
return;
}
TopicId dataEventTopic = NamespaceId.SYSTEM.topic(topic);
MessagePublisher publisher = getMessagingContext().getMessagePublisher();
byte[] payload = Bytes.toBytes(GSON.toJson(Notification.forPartitions(datasetId, partitionKeys)));
int failure = 0;
long startTime = System.currentTimeMillis();
while (true) {
try {
publisher.publish(dataEventTopic.getNamespace(), dataEventTopic.getTopic(), payload);
return;
} catch (TopicNotFoundException e) {
// this shouldn't happen since the TMS creates the data event topic on startup.
throw new IOException("Unexpected exception due to missing topic '" + dataEventTopic + "'", e);
} catch (AccessException e) {
throw new IOException("Unexpected access exception during publishing notification to '" + dataEventTopic + "'", e);
} catch (IOException e) {
long sleepTime = retryStrategy.nextRetry(++failure, startTime);
if (sleepTime < 0) {
throw e;
}
try {
TimeUnit.MILLISECONDS.sleep(sleepTime);
} catch (InterruptedException ex) {
// If interrupted during sleep, just reset the interrupt flag and return
Thread.currentThread().interrupt();
return;
}
}
}
}
@Override
public ProgramRunId getProgramRunId() {
return programRunId;
}
@Nullable
@Override
public NamespacedEntityId getComponentId() {
return AbstractContext.this.getComponentId();
}
};
}
use of io.cdap.cdap.api.security.AccessException in project cdap by caskdata.
the class UnitTestManager method deployApplication.
@Override
public ApplicationManager deployApplication(NamespaceId namespace, Class<? extends Application> applicationClz, @Nullable Config configObject, File... bundleEmbeddedJars) throws AccessException {
Preconditions.checkNotNull(applicationClz, "Application class cannot be null.");
Type configType = Artifacts.getConfigType(applicationClz);
try {
ArtifactId artifactId = new ArtifactId(namespace.getNamespace(), applicationClz.getSimpleName(), "1.0-SNAPSHOT");
addAppArtifact(artifactId, applicationClz, new Manifest(), bundleEmbeddedJars);
if (configObject == null) {
configObject = (Config) TypeToken.of(configType).getRawType().newInstance();
}
Application app = applicationClz.newInstance();
MockAppConfigurer configurer = new MockAppConfigurer(app);
app.configure(configurer, new DefaultApplicationContext<>(configObject));
ApplicationId applicationId = new ApplicationId(namespace.getNamespace(), configurer.getName());
ArtifactSummary artifactSummary = new ArtifactSummary(artifactId.getArtifact(), artifactId.getVersion());
appFabricClient.deployApplication(Id.Application.fromEntityId(applicationId), new AppRequest(artifactSummary, configObject));
return appManagerFactory.create(applicationId);
} catch (AccessException e) {
throw e;
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
Aggregations