Search in sources :

Example 1 with UnsupportedTypeException

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);
}
Also used : ParameterizedType(java.lang.reflect.ParameterizedType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) Schema(co.cask.cdap.api.data.schema.Schema) UnsupportedTypeException(co.cask.cdap.api.data.schema.UnsupportedTypeException)

Example 2 with UnsupportedTypeException

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;
}
Also used : Config(co.cask.cdap.api.Config) PluginConfig(co.cask.cdap.api.plugin.PluginConfig) Schema(co.cask.cdap.api.data.schema.Schema) Attributes(java.util.jar.Attributes) ApplicationClass(co.cask.cdap.api.artifact.ApplicationClass) ZipException(java.util.zip.ZipException) Manifest(java.util.jar.Manifest) ZipException(java.util.zip.ZipException) EOFException(java.io.EOFException) UnsupportedTypeException(co.cask.cdap.api.data.schema.UnsupportedTypeException) IOException(java.io.IOException) InvalidArtifactException(co.cask.cdap.common.InvalidArtifactException) UnsupportedTypeException(co.cask.cdap.api.data.schema.UnsupportedTypeException) Application(co.cask.cdap.api.app.Application) InvalidArtifactException(co.cask.cdap.common.InvalidArtifactException)

Example 3 with UnsupportedTypeException

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);
}
Also used : Description(co.cask.cdap.api.annotation.Description) Macro(co.cask.cdap.api.annotation.Macro) UnsupportedTypeException(co.cask.cdap.api.data.schema.UnsupportedTypeException) PluginPropertyField(co.cask.cdap.api.plugin.PluginPropertyField) Annotation(java.lang.annotation.Annotation) Name(co.cask.cdap.api.annotation.Name)

Example 4 with UnsupportedTypeException

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
    }
}
Also used : UnsupportedTypeException(co.cask.cdap.api.data.schema.UnsupportedTypeException) Stream(co.cask.cdap.api.data.stream.Stream) InputStream(java.io.InputStream)

Example 5 with UnsupportedTypeException

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);
    }
}
Also used : Schema(co.cask.cdap.api.data.schema.Schema) UnsupportedTypeException(co.cask.cdap.api.data.schema.UnsupportedTypeException) IOException(java.io.IOException)

Aggregations

UnsupportedTypeException (co.cask.cdap.api.data.schema.UnsupportedTypeException)30 Schema (co.cask.cdap.api.data.schema.Schema)11 Stream (co.cask.cdap.api.data.stream.Stream)10 IOException (java.io.IOException)9 FormatSpecification (co.cask.cdap.api.data.format.FormatSpecification)4 DatasetManagementException (co.cask.cdap.api.dataset.DatasetManagementException)3 BadRequestException (co.cask.cdap.common.BadRequestException)3 ExploreException (co.cask.cdap.explore.service.ExploreException)3 QueryHandle (co.cask.cdap.proto.QueryHandle)3 JsonObject (com.google.gson.JsonObject)3 SQLException (java.sql.SQLException)3 DatasetSpecification (co.cask.cdap.api.dataset.DatasetSpecification)2 PluginPropertyField (co.cask.cdap.api.plugin.PluginPropertyField)2 InvalidArtifactException (co.cask.cdap.common.InvalidArtifactException)2 AuditPolicy (co.cask.cdap.common.security.AuditPolicy)2 ContextManager (co.cask.cdap.hive.context.ContextManager)2 StreamId (co.cask.cdap.proto.id.StreamId)2 JsonSyntaxException (com.google.gson.JsonSyntaxException)2 InputStream (java.io.InputStream)2 InputStreamReader (java.io.InputStreamReader)2