use of io.cdap.cdap.api.artifact.ApplicationClass in project cdap by cdapio.
the class AbstractProgramRuntimeService method regenerateAppSpec.
/**
* Regenerates the app spec before the program start
*
* @return the regenerated app spec, or null if there is any exception generating the app spec.
*/
@Nullable
private ApplicationSpecification regenerateAppSpec(ArtifactDetail artifactDetail, ProgramId programId, ArtifactId artifactId, ApplicationSpecification existingAppSpec, ProgramOptions options) throws InterruptedException, ExecutionException, TimeoutException {
ApplicationClass appClass = Iterables.getFirst(artifactDetail.getMeta().getClasses().getApps(), null);
if (appClass == null) {
// This should never happen.
throw new IllegalStateException(String.format("No application class found in artifact '%s' in namespace '%s'.", artifactDetail.getDescriptor().getArtifactId(), programId.getNamespace()));
}
AppDeploymentInfo deploymentInfo = new AppDeploymentInfo(artifactId, artifactDetail.getDescriptor().getLocation(), programId.getNamespaceId(), appClass, existingAppSpec.getName(), existingAppSpec.getAppVersion(), existingAppSpec.getConfiguration(), null, false, new AppDeploymentRuntimeInfo(existingAppSpec, options.getUserArguments().asMap(), options.getArguments().asMap()));
Configurator configurator = this.configuratorFactory.create(deploymentInfo);
ListenableFuture<ConfigResponse> future = configurator.config();
ConfigResponse response = future.get(120, TimeUnit.SECONDS);
if (response.getExitCode() == 0) {
AppSpecInfo appSpecInfo = response.getAppSpecInfo();
if (appSpecInfo != null && appSpecInfo.getAppSpec() != null) {
return appSpecInfo.getAppSpec();
}
}
return null;
}
use of io.cdap.cdap.api.artifact.ApplicationClass in project cdap by cdapio.
the class ArtifactStore method deleteMeta.
private void deleteMeta(StructuredTableContext context, Id.Artifact artifactId, ArtifactData oldMeta) throws IOException {
// delete old artifact data
StructuredTable artifactTable = getTable(context, StoreDefinition.ArtifactStore.ARTIFACT_DATA_TABLE);
ArtifactCell artifactCell = new ArtifactCell(artifactId);
artifactTable.delete(artifactCell.keys);
// delete old appclass metadata
StructuredTable appClassTable = getTable(context, StoreDefinition.ArtifactStore.APP_DATA_TABLE);
for (ApplicationClass appClass : oldMeta.meta.getClasses().getApps()) {
AppClassKey appClassKey = new AppClassKey(artifactId.getNamespace().toEntityId(), appClass.getClassName());
deleteRangeFromTable(appClassTable, Range.singleton(appClassKey.keys));
}
// delete old plugins, we loop twice to only access to one table at a time to prevent deadlock
StructuredTable pluginDataTable = getTable(context, StoreDefinition.ArtifactStore.PLUGIN_DATA_TABLE);
for (PluginClass pluginClass : oldMeta.meta.getClasses().getPlugins()) {
// delete metadata for each artifact this plugin extends
for (ArtifactRange artifactRange : oldMeta.meta.getUsableBy()) {
// these four fields are prefixes of the plugin table primary keys
PluginKeyPrefix pluginKey = new PluginKeyPrefix(artifactRange.getNamespace(), artifactRange.getName(), pluginClass.getType(), pluginClass.getName());
pluginDataTable.delete(concatFields(pluginKey.keys, artifactCell.keys));
}
}
// Delete the universal plugin row
StructuredTable uniPluginTable = getTable(context, StoreDefinition.ArtifactStore.UNIV_PLUGIN_DATA_TABLE);
for (PluginClass pluginClass : oldMeta.meta.getClasses().getPlugins()) {
if (oldMeta.meta.getUsableBy().isEmpty()) {
UniversalPluginKeyPrefix pluginKey = new UniversalPluginKeyPrefix(artifactId.getNamespace().getId(), pluginClass.getType(), pluginClass.getName());
uniPluginTable.delete(concatFields(pluginKey.keys, artifactCell.keys));
}
}
// delete the old jar file
try {
new EntityImpersonator(artifactId.toEntityId(), impersonator).impersonate(() -> {
Locations.getLocationFromAbsolutePath(locationFactory, oldMeta.getLocationPath()).delete();
return null;
});
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
// this should not happen
throw Throwables.propagate(e);
}
}
use of io.cdap.cdap.api.artifact.ApplicationClass in project cdap by cdapio.
the class DefaultArtifactInspector method inspectApplications.
private ArtifactClasses.Builder inspectApplications(Id.Artifact artifactId, ArtifactClasses.Builder builder, Location artifactLocation, ClassLoader artifactClassLoader) throws IOException, InvalidArtifactException {
// right now we force users to include the application main class as an attribute in their manifest,
// which forces them to have a single application class.
// in the future, we may want to let users do this or maybe specify a list of classes or
// a package that will be searched for applications, to allow multiple applications in a single artifact.
String mainClassName;
try {
Manifest manifest = BundleJarUtil.getManifest(artifactLocation);
if (manifest == null) {
return builder;
}
Attributes manifestAttributes = manifest.getMainAttributes();
if (manifestAttributes == null) {
return builder;
}
mainClassName = manifestAttributes.getValue(ManifestFields.MAIN_CLASS);
} catch (ZipException e) {
throw new InvalidArtifactException(String.format("Couldn't unzip artifact %s, please check it is a valid jar file.", artifactId), e);
}
if (mainClassName == null) {
return builder;
}
try {
Class<?> mainClass = artifactClassLoader.loadClass(mainClassName);
if (!(Application.class.isAssignableFrom(mainClass))) {
// possible for 3rd party plugin artifacts to have the main class set
return builder;
}
Application app = (Application) mainClass.newInstance();
java.lang.reflect.Type configType;
// we can deserialize the config into that object. Otherwise it'll just be a Config
try {
configType = Artifacts.getConfigType(app.getClass());
} catch (Exception e) {
throw new InvalidArtifactException(String.format("Could not resolve config type for Application class %s in artifact %s. " + "The type must extend Config and cannot be parameterized.", mainClassName, artifactId));
}
Schema configSchema = configType == Config.class ? null : schemaGenerator.generate(configType);
builder.addApp(new ApplicationClass(mainClassName, "", configSchema, getArtifactRequirements(app.getClass())));
} catch (ClassNotFoundException e) {
throw new InvalidArtifactException(String.format("Could not find Application main class %s in artifact %s.", mainClassName, artifactId));
} catch (UnsupportedTypeException e) {
throw new InvalidArtifactException(String.format("Config for Application %s in artifact %s has an unsupported schema. " + "The type must extend Config and cannot be parameterized.", mainClassName, artifactId));
} catch (InstantiationException | IllegalAccessException e) {
throw new InvalidArtifactException(String.format("Could not instantiate Application class %s in artifact %s.", mainClassName, artifactId), e);
}
return builder;
}
use of io.cdap.cdap.api.artifact.ApplicationClass in project cdap by cdapio.
the class ArtifactStore method getApplicationClasses.
/**
* Get all application classes that belong to the specified namespace of the specified classname.
* Results are returned as a sorted map from artifact to application classes in that artifact.
* Map entries are sorted by the artifact.
*
* @param namespace the namespace from which to get application classes
* @param className the classname of application classes to get
* @return an unmodifiable map of artifact the application classes in that artifact.
* The map will never be null. If there are no application classes, an empty map will be returned.
*/
public SortedMap<ArtifactDescriptor, ApplicationClass> getApplicationClasses(final NamespaceId namespace, final String className) {
return TransactionRunners.run(transactionRunner, context -> {
StructuredTable table = getTable(context, StoreDefinition.ArtifactStore.APP_DATA_TABLE);
SortedMap<ArtifactDescriptor, ApplicationClass> result = Maps.newTreeMap();
Collection<Field<?>> keys = ImmutableList.of(Fields.stringField(StoreDefinition.ArtifactStore.NAMESPACE_FIELD, namespace.getNamespace()), Fields.stringField(StoreDefinition.ArtifactStore.CLASS_NAME_FIELD, className));
try (CloseableIterator<StructuredRow> iterator = table.scan(Range.singleton(keys), Integer.MAX_VALUE)) {
while (iterator.hasNext()) {
StructuredRow row = iterator.next();
Map.Entry<ArtifactDescriptor, ApplicationClass> entry = extractApplicationClass(row);
result.put(entry.getKey(), entry.getValue());
}
}
return Collections.unmodifiableSortedMap(result);
});
}
use of io.cdap.cdap.api.artifact.ApplicationClass in project cdap by cdapio.
the class ApplicationClassCodec method deserialize.
@Override
public ApplicationClass deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
Schema configSchema = getConfigSchema(jsonObject, context);
Requirements requirements = getRequirements(jsonObject, context);
return new ApplicationClass(getStringValue(jsonObject, CLASS_NAME), getStringValue(jsonObject, DESCRIPTION), configSchema, requirements);
}
Aggregations