use of io.cdap.cdap.common.ArtifactNotFoundException in project cdap by caskdata.
the class ArtifactStore method getPluginsInArtifact.
private SortedMap<ArtifactDescriptor, Set<PluginClass>> getPluginsInArtifact(StructuredTable artifactDataTable, Id.Artifact artifactId, Predicate<PluginClass> filter) throws ArtifactNotFoundException, IOException {
SortedMap<ArtifactDescriptor, Set<PluginClass>> result = new TreeMap<>();
// Make sure the artifact exists
ArtifactCell artifactCell = new ArtifactCell(artifactId);
Optional<StructuredRow> row = artifactDataTable.read(artifactCell.keys);
if (!row.isPresent()) {
throw new ArtifactNotFoundException(artifactId.toEntityId());
}
// include any plugin classes that are inside the artifact itself and is accepted by the filter
ArtifactData artifactData = GSON.fromJson(row.get().getString(StoreDefinition.ArtifactStore.ARTIFACT_DATA_FIELD), ArtifactData.class);
Set<PluginClass> plugins = artifactData.meta.getClasses().getPlugins().stream().filter(filter).collect(Collectors.toCollection(LinkedHashSet::new));
if (!plugins.isEmpty()) {
Location location = Locations.getLocationFromAbsolutePath(locationFactory, artifactData.getLocationPath());
ArtifactDescriptor descriptor = new ArtifactDescriptor(artifactId.getNamespace().getId(), artifactId.toArtifactId(), location);
result.put(descriptor, plugins);
}
return result;
}
use of io.cdap.cdap.common.ArtifactNotFoundException in project cdap by caskdata.
the class ArtifactStore method getPluginClasses.
/**
* Get all plugin classes of the given type and name that extend the given parent artifact.
* Results are returned as a map from plugin artifact to plugins in that artifact.
*
* @param namespace the namespace to search for plugins. The system namespace is always included.
* @param parentArtifactRange the parent artifact range to find plugins for
* @param type the type of plugin to look for
* @param name the name of the plugin to look for
* @param pluginRange the predicate for the plugins
* @param limit the limit number of the result
* @param order the order of the result
* @return an unmodifiable map of plugin artifact to plugin classes of the given type and name, accessible by the
* given artifact. The map will never be null, and will never be empty.
* @throws PluginNotExistsException if no plugin with the given type and name exists in the namespace
* @throws IOException if there was an exception reading metadata from the metastore
*/
public SortedMap<ArtifactDescriptor, PluginClass> getPluginClasses(NamespaceId namespace, ArtifactRange parentArtifactRange, String type, String name, @Nullable final Predicate<io.cdap.cdap.proto.id.ArtifactId> pluginRange, int limit, ArtifactSortOrder order) throws IOException, ArtifactNotFoundException, PluginNotExistsException {
SortedMap<ArtifactDescriptor, PluginClass> result = TransactionRunners.run(transactionRunner, context -> {
StructuredTable artifactDataTable = getTable(context, StoreDefinition.ArtifactStore.ARTIFACT_DATA_TABLE);
List<ArtifactDetail> parentArtifactDetails = getArtifacts(artifactDataTable, parentArtifactRange, Integer.MAX_VALUE, null);
if (parentArtifactDetails.isEmpty()) {
throw new ArtifactNotFoundException(parentArtifactRange.getNamespace(), parentArtifactRange.getName());
}
SortedMap<ArtifactDescriptor, PluginClass> plugins = order == ArtifactSortOrder.DESC ? new TreeMap<>(Collections.reverseOrder()) : new TreeMap<>();
List<Id.Artifact> parentArtifacts = new ArrayList<>();
for (ArtifactDetail parentArtifactDetail : parentArtifactDetails) {
parentArtifacts.add(Id.Artifact.from(Id.Namespace.from(parentArtifactRange.getNamespace()), parentArtifactDetail.getDescriptor().getArtifactId()));
Set<PluginClass> parentPlugins = parentArtifactDetail.getMeta().getClasses().getPlugins();
for (PluginClass pluginClass : parentPlugins) {
if (pluginClass.getName().equals(name) && pluginClass.getType().equals(type) && isAllowed(pluginClass)) {
plugins.put(parentArtifactDetail.getDescriptor(), pluginClass);
break;
}
}
}
// Add all plugins that extends from the given set of parents
StructuredTable pluginTable = getTable(context, StoreDefinition.ArtifactStore.PLUGIN_DATA_TABLE);
PluginKeyPrefix pluginKey = new PluginKeyPrefix(parentArtifactRange.getNamespace(), parentArtifactRange.getName(), type, name);
try (CloseableIterator<StructuredRow> iterator = pluginTable.scan(Range.singleton(pluginKey.keys), Integer.MAX_VALUE)) {
addPluginsInRangeToMap(namespace, parentArtifacts, iterator, plugins, pluginRange, limit);
}
// Add all universal plugins
StructuredTable uniPluginTable = getTable(context, StoreDefinition.ArtifactStore.UNIV_PLUGIN_DATA_TABLE);
for (String ns : Arrays.asList(namespace.getNamespace(), NamespaceId.SYSTEM.getNamespace())) {
UniversalPluginKeyPrefix universalPluginKey = new UniversalPluginKeyPrefix(ns, type, name);
try (CloseableIterator<StructuredRow> iterator = uniPluginTable.scan(Range.singleton(universalPluginKey.keys), Integer.MAX_VALUE)) {
addPluginsInRangeToMap(namespace, parentArtifacts, iterator, plugins, pluginRange, limit);
}
}
return Collections.unmodifiableSortedMap(plugins);
}, IOException.class, ArtifactNotFoundException.class);
if (result.isEmpty()) {
throw new PluginNotExistsException(new NamespaceId(parentArtifactRange.getNamespace()), type, name);
}
return result;
}
use of io.cdap.cdap.common.ArtifactNotFoundException in project cdap by caskdata.
the class ArtifactLocalizer method preloadArtifacts.
public void preloadArtifacts(Set<String> artifactNames) throws IOException, ArtifactNotFoundException {
ArtifactManager artifactManager = artifactManagerFactory.create(NamespaceId.SYSTEM, RetryStrategies.fromConfiguration(cConf, Constants.Service.TASK_WORKER + "."));
for (ArtifactInfo info : artifactManager.listArtifacts()) {
if (artifactNames.contains(info.getName()) && info.getParents().isEmpty()) {
String className = info.getClasses().getApps().stream().findFirst().map(ApplicationClass::getClassName).orElse(null);
LOG.info("Preloading artifact {}:{}-{}", info.getScope(), info.getName(), info.getVersion());
ArtifactId artifactId = NamespaceId.SYSTEM.artifact(info.getName(), info.getVersion());
try {
fetchArtifact(artifactId);
} catch (Exception e) {
LOG.debug("Failed to preload artifact {}", artifactId);
}
}
}
}
use of io.cdap.cdap.common.ArtifactNotFoundException in project cdap by caskdata.
the class AppLifecycleHttpHandler method deployAppFromArtifact.
// normally we wouldn't want to use a body consumer but would just want to read the request body directly
// since it wont be big. But the deploy app API has one path with different behavior based on content type
// the other behavior requires a BodyConsumer and only have one method per path is allowed,
// so we have to use a BodyConsumer
private BodyConsumer deployAppFromArtifact(final ApplicationId appId) throws IOException {
// Perform auth checks outside BodyConsumer as only the first http request containing auth header
// to populate SecurityRequestContext while http chunk doesn't. BodyConsumer runs in the thread
// that processes the last http chunk.
accessEnforcer.enforce(appId, authenticationContext.getPrincipal(), StandardPermission.CREATE);
// createTempFile() needs a prefix of at least 3 characters
return new AbstractBodyConsumer(File.createTempFile("apprequest-" + appId, ".json", tmpDir)) {
@Override
protected void onFinish(HttpResponder responder, File uploadedFile) {
try (FileReader fileReader = new FileReader(uploadedFile)) {
AppRequest<?> appRequest = DECODE_GSON.fromJson(fileReader, AppRequest.class);
ArtifactSummary artifactSummary = appRequest.getArtifact();
KerberosPrincipalId ownerPrincipalId = appRequest.getOwnerPrincipal() == null ? null : new KerberosPrincipalId(appRequest.getOwnerPrincipal());
// if we don't null check, it gets serialized to "null"
Object config = appRequest.getConfig();
String configString = config == null ? null : config instanceof String ? (String) config : GSON.toJson(config);
try {
applicationLifecycleService.deployApp(appId.getParent(), appId.getApplication(), appId.getVersion(), artifactSummary, configString, createProgramTerminator(), ownerPrincipalId, appRequest.canUpdateSchedules(), false, Collections.emptyMap());
} catch (DatasetManagementException e) {
if (e.getCause() instanceof UnauthorizedException) {
throw (UnauthorizedException) e.getCause();
} else {
throw e;
}
}
responder.sendString(HttpResponseStatus.OK, "Deploy Complete");
} catch (ArtifactNotFoundException e) {
responder.sendString(HttpResponseStatus.NOT_FOUND, e.getMessage());
} catch (ConflictException e) {
responder.sendString(HttpResponseStatus.CONFLICT, e.getMessage());
} catch (UnauthorizedException e) {
responder.sendString(HttpResponseStatus.FORBIDDEN, e.getMessage());
} catch (InvalidArtifactException e) {
responder.sendString(HttpResponseStatus.BAD_REQUEST, e.getMessage());
} catch (IOException e) {
LOG.error("Error reading request body for creating app {}.", appId);
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, String.format("Error while reading json request body for app %s.", appId));
} catch (Exception e) {
LOG.error("Deploy failure", e);
responder.sendString(HttpResponseStatus.BAD_REQUEST, e.getMessage());
}
}
};
}
use of io.cdap.cdap.common.ArtifactNotFoundException in project cdap by caskdata.
the class CapabilityApplier method shouldDeployApp.
// Returns true if capability applier should try to deploy this application. 2 conditions when it returns true:
// 1. Either the application is not deployed before.
// 2. If application is deployed before then the app artifact of the deployed application is not the latest one
// available.
private boolean shouldDeployApp(ApplicationId applicationId, SystemApplication application) throws Exception {
ApplicationDetail currAppDetail;
try {
currAppDetail = applicationLifecycleService.getAppDetail(applicationId);
} catch (ApplicationNotFoundException exception) {
return true;
}
// Compare if the app artifact version of currently deployed application with highest version of app artifact
// available. If it's not same, capability applier should redeploy application.
ArtifactSummary summary = application.getArtifact();
NamespaceId artifactNamespace = ArtifactScope.SYSTEM.equals(summary.getScope()) ? NamespaceId.SYSTEM : applicationId.getParent();
ArtifactRange range = new ArtifactRange(artifactNamespace.getNamespace(), summary.getName(), ArtifactVersionRange.parse(summary.getVersion()));
// this method will not throw ArtifactNotFoundException, if no artifacts in the range, we are expecting an empty
// collection returned.
List<ArtifactDetail> artifactDetail = artifactRepository.getArtifactDetails(range, 1, ArtifactSortOrder.DESC);
if (artifactDetail.isEmpty()) {
throw new ArtifactNotFoundException(range.getNamespace(), range.getName());
}
ArtifactId latestArtifactId = artifactDetail.get(0).getDescriptor().getArtifactId();
// same artifact. If same means no need to deploy the application again.
return !currAppDetail.getArtifact().getVersion().equals(latestArtifactId.getVersion().getVersion());
}
Aggregations