use of co.cask.cdap.common.NamespaceNotFoundException in project cdap by caskdata.
the class ArtifactHttpHandler method addArtifact.
@POST
@Path("/namespaces/{namespace-id}/artifacts/{artifact-name}")
@AuditPolicy(AuditDetail.HEADERS)
public BodyConsumer addArtifact(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") final String namespaceId, @PathParam("artifact-name") final String artifactName, @HeaderParam(VERSION_HEADER) final String artifactVersion, @HeaderParam(EXTENDS_HEADER) final String parentArtifactsStr, @HeaderParam(PLUGINS_HEADER) String pluginClasses) throws NamespaceNotFoundException, BadRequestException {
final NamespaceId namespace = validateAndGetNamespace(namespaceId);
// and validated there
if (artifactVersion != null && !artifactVersion.isEmpty()) {
validateAndGetArtifactId(namespace, artifactName, artifactVersion);
}
final Set<ArtifactRange> parentArtifacts = parseExtendsHeader(namespace, parentArtifactsStr);
final Set<PluginClass> additionalPluginClasses;
if (pluginClasses == null) {
additionalPluginClasses = ImmutableSet.of();
} else {
try {
additionalPluginClasses = GSON.fromJson(pluginClasses, PLUGINS_TYPE);
} catch (JsonParseException e) {
responder.sendString(HttpResponseStatus.BAD_REQUEST, String.format("%s header '%s' is invalid: %s", PLUGINS_HEADER, pluginClasses, e.getMessage()));
return null;
}
}
try {
// copy the artifact contents to local tmp directory
final File destination = File.createTempFile("artifact-", ".jar", tmpDir);
return new AbstractBodyConsumer(destination) {
@Override
protected void onFinish(HttpResponder responder, File uploadedFile) {
try {
String version = (artifactVersion == null || artifactVersion.isEmpty()) ? getBundleVersion(uploadedFile) : artifactVersion;
Id.Artifact artifactId = validateAndGetArtifactId(namespace, artifactName, version);
// add the artifact to the repo
artifactRepository.addArtifact(artifactId, uploadedFile, parentArtifacts, additionalPluginClasses);
responder.sendString(HttpResponseStatus.OK, "Artifact added successfully");
} catch (ArtifactRangeNotFoundException e) {
responder.sendString(HttpResponseStatus.NOT_FOUND, e.getMessage());
} catch (ArtifactAlreadyExistsException e) {
responder.sendString(HttpResponseStatus.CONFLICT, e.getMessage());
} catch (WriteConflictException e) {
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Conflict while writing artifact, please try again.");
} catch (IOException e) {
LOG.error("Exception while trying to write artifact {}-{}-{}.", namespaceId, artifactName, artifactVersion, e);
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error performing IO while writing artifact.");
} catch (BadRequestException e) {
responder.sendString(HttpResponseStatus.BAD_REQUEST, e.getMessage());
} catch (UnauthorizedException e) {
responder.sendString(HttpResponseStatus.FORBIDDEN, e.getMessage());
} catch (Exception e) {
LOG.error("Error while writing artifact {}-{}-{}", namespaceId, artifactName, artifactVersion, e);
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error while adding artifact.");
}
}
private String getBundleVersion(File file) throws BadRequestException, IOException {
try (JarFile jarFile = new JarFile(file)) {
Manifest manifest = jarFile.getManifest();
if (manifest == null) {
throw new BadRequestException("Unable to derive version from artifact because it does not contain a manifest. " + "Please package the jar with a manifest, or explicitly specify the artifact version.");
}
Attributes attributes = manifest.getMainAttributes();
String version = attributes == null ? null : attributes.getValue(ManifestFields.BUNDLE_VERSION);
if (version == null) {
throw new BadRequestException("Unable to derive version from artifact because manifest does not contain Bundle-Version attribute. " + "Please include Bundle-Version in the manifest, or explicitly specify the artifact version.");
}
return version;
} catch (ZipException e) {
throw new BadRequestException("Artifact is not in zip format. Please make sure it is a jar file.");
}
}
};
} catch (IOException e) {
LOG.error("Exception creating temp file to place artifact {} contents", artifactName, e);
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Server error creating temp file for artifact.");
return null;
}
}
use of co.cask.cdap.common.NamespaceNotFoundException in project cdap by caskdata.
the class SecureStoreClient method listKeys.
/**
* List all the secure keys in the namespace
* @param namespaceId {@link NamespaceId} namespace id
* @return list of key names and descriptions
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
* @throws NamespaceNotFoundException if the given namespace is not found
*/
public Map<String, String> listKeys(NamespaceId namespaceId) throws IOException, UnauthenticatedException, NamespaceNotFoundException, UnauthorizedException {
URL url = config.resolveNamespacedURLV3(namespaceId, SECURE_KEYS);
HttpResponse response = restClient.execute(HttpMethod.GET, url, config.getAccessToken(), HttpURLConnection.HTTP_NOT_FOUND);
if (response.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
throw new NamespaceNotFoundException(namespaceId);
}
return ObjectResponse.fromJsonBody(response, new TypeToken<Map<String, String>>() {
}).getResponseObject();
}
use of co.cask.cdap.common.NamespaceNotFoundException in project cdap by caskdata.
the class AppLifecycleHttpHandlerTest method testDeployNonExistingNamespace.
/**
* Tests deploying an application in a non-existing non-default namespace.
*/
@Test
public void testDeployNonExistingNamespace() throws Exception {
HttpResponse response = deploy(WordCountApp.class, Constants.Gateway.API_VERSION_3_TOKEN, "random");
Assert.assertEquals(404, response.getStatusLine().getStatusCode());
NotFoundException nfe = new NamespaceNotFoundException(new NamespaceId("random"));
Assert.assertEquals(nfe.getMessage(), readResponse(response));
}
use of co.cask.cdap.common.NamespaceNotFoundException in project cdap by caskdata.
the class StreamHandlerTest method listStreams.
private List<StreamDetail> listStreams(NamespaceId namespaceId) throws Exception {
URL url = createURL(namespaceId.getNamespace(), "streams");
HttpRequest request = HttpRequest.get(url).build();
HttpResponse response = HttpRequests.execute(request);
if (response.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
throw new NamespaceNotFoundException(namespaceId);
}
Assert.assertEquals(200, response.getResponseCode());
return GSON.fromJson(response.getResponseBodyAsString(), new TypeToken<List<StreamDetail>>() {
}.getType());
}
use of co.cask.cdap.common.NamespaceNotFoundException in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method deleteQueues.
@DELETE
@Path("/queues")
public synchronized void deleteQueues(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId) throws NamespaceNotFoundException {
// synchronized to avoid a potential race condition here:
// 1. the check for state returns that all flows are STOPPED
// 2. The API deletes queues because
// Between 1. and 2., a flow is started using the /namespaces/{namespace-id}/apps/{app-id}/flows/{flow-id}/start API
// Averting this race condition by synchronizing this method. The resource that needs to be locked here is
// runtimeService. This should work because the method that is used to start a flow - startStopProgram - is also
// synchronized on this.
// This synchronization works in HA mode because even in HA mode there is only one leader at a time.
NamespaceId namespace = validateAndGetNamespace(namespaceId);
try {
List<ProgramRecord> flows = lifecycleService.list(validateAndGetNamespace(namespaceId), ProgramType.FLOW);
for (ProgramRecord flow : flows) {
String appId = flow.getApp();
String flowId = flow.getName();
ProgramId programId = new ProgramId(namespaceId, appId, ProgramType.FLOW, flowId);
ProgramStatus status = lifecycleService.getProgramStatus(programId);
if (ProgramStatus.STOPPED != status) {
responder.sendString(HttpResponseStatus.FORBIDDEN, String.format("Flow '%s' from application '%s' in namespace '%s' is running, " + "please stop it first.", flowId, appId, namespaceId));
return;
}
}
queueAdmin.dropAllInNamespace(namespace);
// delete process metrics that are used to calculate the queue size (system.queue.pending metric)
FlowUtils.deleteFlowPendingMetrics(metricStore, namespaceId, null, null);
responder.sendStatus(HttpResponseStatus.OK);
} catch (Exception e) {
LOG.error("Error while deleting queues in namespace " + namespace, e);
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, e.getMessage());
}
}
Aggregations