use of co.cask.cdap.api.data.schema.UnsupportedTypeException in project cdap by caskdata.
the class AbstractSchemaGenerator method doGenerate.
/**
* Actual schema generation. It recursively resolves container types.
*
* @param typeToken Encapsulate the Java type for generating a {@link Schema}.
* @param knownRecords Set of record names that has the schema already generated. It is used for
* recursive class field references.
* @param acceptRecursion Whether to tolerate type recursion. If false, will throw UnsupportedTypeException if
* a recursive type is encountered.
* @return A {@link Schema} representing the given java {@link Type}.
* @throws UnsupportedTypeException Indicates schema generation is not support for the given java {@link Type}.
*/
@SuppressWarnings("unchecked")
protected final Schema doGenerate(TypeToken<?> typeToken, Set<String> knownRecords, boolean acceptRecursion) throws UnsupportedTypeException {
Type type = typeToken.getType();
Class<?> rawType = typeToken.getRawType();
if (SIMPLE_SCHEMAS.containsKey(rawType)) {
return SIMPLE_SCHEMAS.get(rawType);
}
// Enum type, simply use all the enum constants for ENUM schema.
if (rawType.isEnum()) {
return Schema.enumWith((Class<Enum<?>>) rawType);
}
// Java array, use ARRAY schema.
if (rawType.isArray()) {
Schema componentSchema = doGenerate(TypeToken.of(rawType.getComponentType()), knownRecords, acceptRecursion);
if (rawType.getComponentType().isPrimitive()) {
return Schema.arrayOf(componentSchema);
}
return Schema.arrayOf(Schema.unionOf(componentSchema, Schema.of(Schema.Type.NULL)));
}
if (!(type instanceof Class || type instanceof ParameterizedType)) {
throw new UnsupportedTypeException("Type " + type + " is not supported. " + "Only Class or ParameterizedType are supported.");
}
// Any parameterized Collection class would be represented by ARRAY schema.
if (Collection.class.isAssignableFrom(rawType)) {
if (!(type instanceof ParameterizedType)) {
throw new UnsupportedTypeException("Only supports parameterized Collection type.");
}
TypeToken<?> componentType = typeToken.resolveType(((ParameterizedType) type).getActualTypeArguments()[0]);
Schema componentSchema = doGenerate(componentType, knownRecords, acceptRecursion);
return Schema.arrayOf(Schema.unionOf(componentSchema, Schema.of(Schema.Type.NULL)));
}
// Java Map, use MAP schema.
if (Map.class.isAssignableFrom(rawType)) {
if (!(type instanceof ParameterizedType)) {
throw new UnsupportedTypeException("Only supports parameterized Map type.");
}
Type[] typeArgs = ((ParameterizedType) type).getActualTypeArguments();
TypeToken<?> keyType = typeToken.resolveType(typeArgs[0]);
TypeToken<?> valueType = typeToken.resolveType(typeArgs[1]);
Schema valueSchema = doGenerate(valueType, knownRecords, acceptRecursion);
return Schema.mapOf(doGenerate(keyType, knownRecords, acceptRecursion), Schema.unionOf(valueSchema, Schema.of(Schema.Type.NULL)));
}
// Any Java class, class name as the record name.
String recordName = typeToken.getRawType().getName();
if (knownRecords.contains(recordName)) {
// Record already seen before
if (acceptRecursion) {
// simply create a reference RECORD schema by the name.
return Schema.recordOf(recordName);
} else {
throw new UnsupportedTypeException("Recursive type not supported for class " + recordName);
}
}
// Delegate to child class to generate RECORD schema.
return generateRecord(typeToken, knownRecords, acceptRecursion);
}
use of co.cask.cdap.api.data.schema.UnsupportedTypeException in project cdap by caskdata.
the class ArtifactInspector 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 {
Object appMain = artifactClassLoader.loadClass(mainClassName).newInstance();
if (!(appMain instanceof Application)) {
// possible for 3rd party plugin artifacts to have the main class set
return builder;
}
Application app = (Application) appMain;
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));
} 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 co.cask.cdap.api.data.schema.UnsupportedTypeException in project cdap by caskdata.
the class ArtifactInspector method createPluginProperty.
/**
* Creates a {@link PluginPropertyField} based on the given field.
*/
private PluginPropertyField createPluginProperty(Field field, TypeToken<?> resolvingType) throws UnsupportedTypeException {
TypeToken<?> fieldType = resolvingType.resolveType(field.getGenericType());
Class<?> rawType = fieldType.getRawType();
Name nameAnnotation = field.getAnnotation(Name.class);
Description descAnnotation = field.getAnnotation(Description.class);
String name = nameAnnotation == null ? field.getName() : nameAnnotation.value();
String description = descAnnotation == null ? "" : descAnnotation.value();
Macro macroAnnotation = field.getAnnotation(Macro.class);
boolean macroSupported = macroAnnotation != null;
if (rawType.isPrimitive()) {
return new PluginPropertyField(name, description, rawType.getName(), true, macroSupported);
}
rawType = Primitives.unwrap(rawType);
if (!rawType.isPrimitive() && !String.class.equals(rawType)) {
throw new UnsupportedTypeException("Only primitive and String types are supported");
}
boolean required = true;
for (Annotation annotation : field.getAnnotations()) {
if (annotation.annotationType().getName().endsWith(".Nullable")) {
required = false;
break;
}
}
return new PluginPropertyField(name, description, rawType.getSimpleName().toLowerCase(), required, macroSupported);
}
use of co.cask.cdap.api.data.schema.UnsupportedTypeException in project cdap by caskdata.
the class AllProgramsApp method configure.
@Override
public void configure() {
setName(NAME);
setDescription("Application which has everything");
addStream(new Stream(STREAM_NAME, "test stream"));
createDataset(DATASET_NAME, KeyValueTable.class, DatasetProperties.builder().setDescription("test dataset").build());
createDataset(DATASET_NAME2, KeyValueTable.class);
createDataset(DATASET_NAME3, KeyValueTable.class);
addFlow(new NoOpFlow());
addMapReduce(new NoOpMR());
addMapReduce(new NoOpMR2());
addWorkflow(new NoOpWorkflow());
addWorker(new NoOpWorker());
addSpark(new NoOpSpark());
addService(new NoOpService());
schedule(buildSchedule(SCHEDULE_NAME, ProgramType.WORKFLOW, NoOpWorkflow.NAME).setDescription(SCHEDULE_DESCRIPTION).triggerByTime("* * * * *"));
try {
createDataset(DS_WITH_SCHEMA_NAME, ObjectMappedTable.class, ObjectMappedTableProperties.builder().setType(DsSchema.class).setDescription("test object mapped table").build());
} catch (UnsupportedTypeException e) {
// ignore for test
}
}
use of co.cask.cdap.api.data.schema.UnsupportedTypeException in project cdap by caskdata.
the class ObjectMappedTableDefinition method configureSchema.
private DatasetProperties configureSchema(DatasetProperties properties) {
Map<String, String> props = properties.getProperties();
Preconditions.checkArgument(props.containsKey(ObjectMappedTableProperties.OBJECT_TYPE));
// schema can normally be derived from the type. However, we cannot use the Type in this method because
// this is called by the system, where the Type is often not available. for example, if somebody creates
// an ObjectMappedTable<Purchase> where Purchase is a class internal to their app.
// we require schema here because we want to validate it to make sure it is supported.
Preconditions.checkArgument(props.containsKey(ObjectMappedTableProperties.OBJECT_SCHEMA));
Preconditions.checkArgument(props.containsKey(ObjectMappedTableProperties.ROW_KEY_EXPLORE_NAME));
Preconditions.checkArgument(props.containsKey(ObjectMappedTableProperties.ROW_KEY_EXPLORE_TYPE));
try {
Schema objectSchema = ObjectMappedTableProperties.getObjectSchema(props);
validateSchema(objectSchema);
String keyName = ObjectMappedTableProperties.getRowKeyExploreName(props);
Schema.Type keyType = ObjectMappedTableProperties.getRowKeyExploreType(props);
Schema fullSchema = addKeyToSchema(objectSchema, keyName, keyType);
return TableProperties.builder().setSchema(fullSchema).setRowFieldName(keyName).addAll(properties.getProperties()).build();
} catch (IOException e) {
throw new IllegalArgumentException("Could not parse schema.", e);
} catch (UnsupportedTypeException e) {
throw new IllegalArgumentException("Schema is of an unsupported type.", e);
}
}
Aggregations