use of io.cdap.cdap.proto.id.ArtifactId in project cdap by caskdata.
the class ArtifactHttpHandler method deleteArtifact.
@DELETE
@Path("/namespaces/{namespace-id}/artifacts/{artifact-name}/versions/{artifact-version}")
public void deleteArtifact(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("artifact-name") String artifactName, @PathParam("artifact-version") String artifactVersion) throws Exception {
NamespaceId namespace = NamespaceId.SYSTEM.getNamespace().equalsIgnoreCase(namespaceId) ? NamespaceId.SYSTEM : validateAndGetNamespace(namespaceId);
ArtifactId artifactId = validateAndGetArtifactId(namespace, artifactName, artifactVersion);
try {
artifactRepository.deleteArtifact(Id.Artifact.fromEntityId(artifactId));
responder.sendStatus(HttpResponseStatus.OK);
} catch (IOException e) {
LOG.error("Exception deleting artifact named {} for namespace {} from the store.", artifactName, namespaceId, e);
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error deleting artifact metadata from the store: " + e.getMessage());
}
}
use of io.cdap.cdap.proto.id.ArtifactId in project cdap by caskdata.
the class ArtifactHttpHandler method writeProperty.
@PUT
@Path("/namespaces/{namespace-id}/artifacts/{artifact-name}/versions/{artifact-version}/properties/{property}")
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void writeProperty(FullHttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("artifact-name") String artifactName, @PathParam("artifact-version") String artifactVersion, @PathParam("property") String key) throws Exception {
NamespaceId namespace = NamespaceId.SYSTEM.getNamespace().equalsIgnoreCase(namespaceId) ? NamespaceId.SYSTEM : validateAndGetNamespace(namespaceId);
ArtifactId artifactId = validateAndGetArtifactId(namespace, artifactName, artifactVersion);
String value = request.content().toString(StandardCharsets.UTF_8);
if (value == null) {
responder.sendStatus(HttpResponseStatus.OK);
return;
}
try {
artifactRepository.writeArtifactProperty(Id.Artifact.fromEntityId(artifactId), key, value);
responder.sendStatus(HttpResponseStatus.OK);
} catch (IOException e) {
LOG.error("Exception writing properties for artifact {}.", artifactId, e);
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error writing property to artifact.");
}
}
use of io.cdap.cdap.proto.id.ArtifactId in project cdap by caskdata.
the class ArtifactHttpHandler method deleteProperty.
@DELETE
@Path("/namespaces/{namespace-id}/artifacts/{artifact-name}/versions/{artifact-version}/properties/{property}")
public void deleteProperty(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("artifact-name") String artifactName, @PathParam("artifact-version") String artifactVersion, @PathParam("property") String key) throws Exception {
NamespaceId namespace = NamespaceId.SYSTEM.getNamespace().equalsIgnoreCase(namespaceId) ? NamespaceId.SYSTEM : validateAndGetNamespace(namespaceId);
ArtifactId artifactId = validateAndGetArtifactId(namespace, artifactName, artifactVersion);
try {
artifactRepository.deleteArtifactProperty(Id.Artifact.fromEntityId(artifactId), key);
responder.sendStatus(HttpResponseStatus.OK);
} catch (IOException e) {
LOG.error("Exception updating properties for artifact {}.", artifactId, e);
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error deleting property for artifact.");
}
}
use of io.cdap.cdap.proto.id.ArtifactId 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);
// that processes the last http chunk.
if (artifactVersion != null && !artifactVersion.isEmpty()) {
ArtifactId artifactId = validateAndGetArtifactId(namespace, artifactName, artifactVersion);
// If the artifact ID is available, use it to perform an authorization check.
contextAccessEnforcer.enforce(artifactId, StandardPermission.CREATE);
} else {
// If there is no version, we perform an enforceOnParent check in which the entityID is not needed.
contextAccessEnforcer.enforceOnParent(EntityType.ARTIFACT, namespace, StandardPermission.CREATE);
}
final Set<ArtifactRange> parentArtifacts = parseExtendsHeader(namespace, parentArtifactsStr);
final Set<PluginClass> additionalPluginClasses;
if (pluginClasses == null || pluginClasses.isEmpty()) {
additionalPluginClasses = ImmutableSet.of();
} else {
try {
additionalPluginClasses = GSON.fromJson(pluginClasses, PLUGINS_TYPE);
additionalPluginClasses.forEach(PluginClass::validate);
} catch (JsonParseException e) {
throw new BadRequestException(String.format("%s header '%s' is invalid.", PLUGINS_HEADER, pluginClasses), e);
} catch (IllegalArgumentException e) {
throw new BadRequestException(String.format("Invalid PluginClasses '%s'.", pluginClasses), e);
}
}
try {
// copy the artifact contents to local tmp directory
Files.createDirectories(tmpDir.toPath());
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;
ArtifactId artifactId = validateAndGetArtifactId(namespace, artifactName, version);
// add the artifact to the repo
artifactRepository.addArtifact(Id.Artifact.fromEntityId(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 io.cdap.cdap.proto.id.ArtifactId in project cdap by caskdata.
the class AbstractProgramRuntimeService method run.
@Override
public final RuntimeInfo run(ProgramDescriptor programDescriptor, ProgramOptions options, RunId runId) {
ProgramId programId = programDescriptor.getProgramId();
ProgramRunId programRunId = programId.run(runId);
ClusterMode clusterMode = ProgramRunners.getClusterMode(options);
// Creates the ProgramRunner based on the cluster mode
ProgramRunner runner = (clusterMode == ClusterMode.ON_PREMISE ? programRunnerFactory : Optional.ofNullable(remoteProgramRunnerFactory).orElseThrow(UnsupportedOperationException::new)).create(programId.getType());
File tempDir = createTempDirectory(programId, runId);
AtomicReference<Runnable> cleanUpTaskRef = new AtomicReference<>(createCleanupTask(tempDir, runner));
DelayedProgramController controller = new DelayedProgramController(programRunId);
RuntimeInfo runtimeInfo = createRuntimeInfo(controller, programId, () -> cleanUpTaskRef.get().run());
updateRuntimeInfo(runtimeInfo);
executor.execute(() -> {
try {
// Get the artifact details and save it into the program options.
ArtifactId artifactId = programDescriptor.getArtifactId();
ArtifactDetail artifactDetail = getArtifactDetail(artifactId);
ApplicationSpecification appSpec = programDescriptor.getApplicationSpecification();
ProgramDescriptor newProgramDescriptor = programDescriptor;
boolean isPreview = Boolean.valueOf(options.getArguments().getOption(ProgramOptionConstants.IS_PREVIEW, "false"));
// for preview we already have a resolved app spec, so no need to regenerate the app spec again
if (!isPreview && appSpec != null && ClusterMode.ON_PREMISE.equals(clusterMode)) {
try {
ApplicationSpecification generatedAppSpec = regenerateAppSpec(artifactDetail, programId, artifactId, appSpec, options);
appSpec = generatedAppSpec != null ? generatedAppSpec : appSpec;
newProgramDescriptor = new ProgramDescriptor(programDescriptor.getProgramId(), appSpec);
} catch (Exception e) {
LOG.warn("Failed to regenerate the app spec for program {}, using the existing app spec", programId);
}
}
ProgramOptions runtimeProgramOptions = updateProgramOptions(artifactId, programId, options, runId, clusterMode, Iterables.getFirst(artifactDetail.getMeta().getClasses().getApps(), null));
// Take a snapshot of all the plugin artifacts used by the program
ProgramOptions optionsWithPlugins = createPluginSnapshot(runtimeProgramOptions, programId, tempDir, newProgramDescriptor.getApplicationSpecification());
// Create and run the program
Program executableProgram = createProgram(cConf, runner, newProgramDescriptor, artifactDetail, tempDir);
cleanUpTaskRef.set(createCleanupTask(cleanUpTaskRef.get(), executableProgram));
controller.setProgramController(runner.run(executableProgram, optionsWithPlugins));
} catch (Exception e) {
controller.failed(e);
programStateWriter.error(programRunId, e);
LOG.error("Exception while trying to run program", e);
}
});
return runtimeInfo;
}
Aggregations