Search in sources :

Example 1 with InvalidSchemaException

use of io.confluent.kafka.schemaregistry.exceptions.InvalidSchemaException in project schema-registry by confluentinc.

the class SubjectVersionsResource method register.

@POST
@PerformanceMetric("subjects.versions.register")
@Operation(summary = "Register a new schema under the specified subject. If successfully " + "registered, this returns the unique identifier of this schema in the registry. The " + "returned identifier should be used to retrieve this schema from the schemas resource and " + "is different from the schema's version which is associated with the subject. If the same " + "schema is registered under a different subject, the same identifier will be returned. " + "However, the version of the schema may be different under different subjects.\n" + "A schema should be compatible with the previously registered schema or schemas (if there " + "are any) as per the configured compatibility level. The configured compatibility level " + "can be obtained by issuing a GET http:get:: /config/(string: subject). If that returns " + "null, then GET http:get:: /config\n" + "When there are multiple instances of Schema Registry running in the same cluster, the " + "schema registration request will be forwarded to one of the instances designated as " + "the primary. If the primary is not available, the client will get an error code " + "indicating that the forwarding has failed.", responses = { @ApiResponse(content = @Content(schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = RegisterSchemaResponse.class))), @ApiResponse(responseCode = "409", description = "Incompatible schema"), @ApiResponse(responseCode = "422", description = "Error code 42201 -- Invalid schema or " + "schema type"), @ApiResponse(responseCode = "500", description = "Error code 50001 -- Error in the backend data store\n" + "Error code 50002 -- Operation timed out\n" + "Error code 50003 -- Error while forwarding the request to the primary") })
public void register(@Suspended final AsyncResponse asyncResponse, @Context HttpHeaders headers, @Parameter(description = "Name of the subject", required = true) @PathParam("subject") String subjectName, @Parameter(description = "Whether to register the normalized schema") @QueryParam("normalize") boolean normalize, @Parameter(description = "Schema", required = true) @NotNull RegisterSchemaRequest request) {
    log.info("Registering new schema: subject {}, version {}, id {}, type {}, schema size {}", subjectName, request.getVersion(), request.getId(), request.getSchemaType(), request.getSchema() == null ? 0 : request.getSchema().length());
    if (subjectName != null && (CharMatcher.javaIsoControl().matchesAnyOf(subjectName) || QualifiedSubject.create(this.schemaRegistry.tenant(), subjectName).getSubject().equals(GLOBAL_RESOURCE_NAME))) {
        throw Errors.invalidSubjectException(subjectName);
    }
    subjectName = QualifiedSubject.normalize(schemaRegistry.tenant(), subjectName);
    Map<String, String> headerProperties = requestHeaderBuilder.buildRequestHeaders(headers, schemaRegistry.config().whitelistHeaders());
    Schema schema = new Schema(subjectName, request.getVersion() != null ? request.getVersion() : 0, request.getId() != null ? request.getId() : -1, request.getSchemaType() != null ? request.getSchemaType() : AvroSchema.TYPE, request.getReferences(), request.getSchema());
    int id;
    try {
        id = schemaRegistry.registerOrForward(subjectName, schema, normalize, headerProperties);
    } catch (IdDoesNotMatchException e) {
        throw Errors.idDoesNotMatchException(e);
    } catch (InvalidSchemaException e) {
        throw Errors.invalidSchemaException(e);
    } catch (OperationNotPermittedException e) {
        throw Errors.operationNotPermittedException(e.getMessage());
    } catch (SchemaRegistryTimeoutException e) {
        throw Errors.operationTimeoutException("Register operation timed out", e);
    } catch (SchemaRegistryStoreException e) {
        throw Errors.storeException("Register schema operation failed while writing" + " to the Kafka store", e);
    } catch (SchemaRegistryRequestForwardingException e) {
        throw Errors.requestForwardingFailedException("Error while forwarding register schema request" + " to the leader", e);
    } catch (IncompatibleSchemaException e) {
        throw Errors.incompatibleSchemaException("Schema being registered is incompatible with" + " an earlier schema for subject \"" + subjectName + "\", details: " + e.getMessage(), e);
    } catch (UnknownLeaderException e) {
        throw Errors.unknownLeaderException("Leader not known.", e);
    } catch (SchemaRegistryException e) {
        throw Errors.schemaRegistryException("Error while registering schema", e);
    }
    RegisterSchemaResponse registerSchemaResponse = new RegisterSchemaResponse();
    registerSchemaResponse.setId(id);
    asyncResponse.resume(registerSchemaResponse);
}
Also used : SchemaRegistryRequestForwardingException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryRequestForwardingException) UnknownLeaderException(io.confluent.kafka.schemaregistry.exceptions.UnknownLeaderException) Schema(io.confluent.kafka.schemaregistry.client.rest.entities.Schema) AvroSchema(io.confluent.kafka.schemaregistry.avro.AvroSchema) SchemaRegistryStoreException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryStoreException) SchemaRegistryException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryException) RegisterSchemaResponse(io.confluent.kafka.schemaregistry.client.rest.entities.requests.RegisterSchemaResponse) IncompatibleSchemaException(io.confluent.kafka.schemaregistry.exceptions.IncompatibleSchemaException) InvalidSchemaException(io.confluent.kafka.schemaregistry.exceptions.InvalidSchemaException) IdDoesNotMatchException(io.confluent.kafka.schemaregistry.exceptions.IdDoesNotMatchException) OperationNotPermittedException(io.confluent.kafka.schemaregistry.exceptions.OperationNotPermittedException) SchemaRegistryTimeoutException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryTimeoutException) PerformanceMetric(io.confluent.rest.annotations.PerformanceMetric) POST(javax.ws.rs.POST) Operation(io.swagger.v3.oas.annotations.Operation)

Example 2 with InvalidSchemaException

use of io.confluent.kafka.schemaregistry.exceptions.InvalidSchemaException in project schema-registry by confluentinc.

the class KafkaSchemaRegistry method isCompatible.

/**
 * @param previousSchemas Full schema history in chronological order
 */
@Override
public List<String> isCompatible(String subject, Schema newSchema, List<Schema> previousSchemas) throws SchemaRegistryException {
    if (previousSchemas == null) {
        log.error("Previous schema not provided");
        throw new InvalidSchemaException("Previous schema not provided");
    }
    List<ParsedSchema> prevParsedSchemas = new ArrayList<>(previousSchemas.size());
    for (Schema previousSchema : previousSchemas) {
        ParsedSchema prevParsedSchema = parseSchema(previousSchema);
        prevParsedSchemas.add(prevParsedSchema);
    }
    ParsedSchema parsedSchema = canonicalizeSchema(newSchema, true, false);
    return isCompatibleWithPrevious(subject, parsedSchema, prevParsedSchemas);
}
Also used : InvalidSchemaException(io.confluent.kafka.schemaregistry.exceptions.InvalidSchemaException) ParsedSchema(io.confluent.kafka.schemaregistry.ParsedSchema) Schema(io.confluent.kafka.schemaregistry.client.rest.entities.Schema) AvroSchema(io.confluent.kafka.schemaregistry.avro.AvroSchema) ArrayList(java.util.ArrayList) ParsedSchema(io.confluent.kafka.schemaregistry.ParsedSchema)

Example 3 with InvalidSchemaException

use of io.confluent.kafka.schemaregistry.exceptions.InvalidSchemaException in project schema-registry by confluentinc.

the class CompatibilityResource method testCompatibilityForSubject.

@POST
@Path("/subjects/{subject}/versions")
@Operation(summary = "Test input schema against a subject's schemas for compatibility, " + "based on the compatibility level of the subject configured. In other word, " + "it will perform the same compatibility check as register for that subject", description = "the compatibility level applied for the check is the configured compatibility level " + "for the subject (http:get:: /config/(string: subject)). If this subject's " + "compatibility level was never changed, then the global compatibility level " + "applies (http:get:: /config).", responses = { @ApiResponse(content = @Content(schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = CompatibilityCheckResponse.class))), @ApiResponse(responseCode = "422", description = "Error code 42201 -- Invalid schema or schema type\n" + "Error code 42202 -- Invalid version"), @ApiResponse(responseCode = "500", description = "Error code 50001 -- Error in the " + "backend data store") })
@PerformanceMetric("compatibility.subjects.versions.verify")
public void testCompatibilityForSubject(@Suspended final AsyncResponse asyncResponse, @Parameter(description = "Subject of the schema version against which compatibility is to " + "be tested", required = true) @PathParam("subject") String subject, @Parameter(description = "Schema", required = true) @NotNull RegisterSchemaRequest request, @Parameter(description = "Whether to return detailed error messages") @QueryParam("verbose") boolean verbose) {
    log.info("Testing schema subject {} compatibility with specified version {}, id {}, type {}", subject, request.getVersion(), request.getId(), request.getSchemaType());
    subject = QualifiedSubject.normalize(schemaRegistry.tenant(), subject);
    // returns true if posted schema is compatible with the specified subject.
    List<String> errorMessages;
    List<Schema> previousSchemas = new ArrayList<>();
    try {
        // Don't check compatibility against deleted schema
        schemaRegistry.getAllVersions(subject, false).forEachRemaining(previousSchemas::add);
    } catch (SchemaRegistryException e) {
        throw Errors.storeException("Error while retrieving schema for subject " + subject, e);
    }
    Schema schema = new Schema(subject, 0, -1, request.getSchemaType() != null ? request.getSchemaType() : AvroSchema.TYPE, request.getReferences(), request.getSchema());
    try {
        errorMessages = schemaRegistry.isCompatible(subject, schema, previousSchemas);
    } catch (InvalidSchemaException e) {
        if (verbose) {
            errorMessages = Collections.singletonList(e.getMessage());
        } else {
            throw Errors.invalidSchemaException(e);
        }
    } catch (SchemaRegistryStoreException e) {
        throw Errors.storeException("Error while getting compatibility level for subject " + subject, e);
    } catch (SchemaRegistryException e) {
        throw Errors.schemaRegistryException("Error while getting compatibility level for subject " + subject, e);
    }
    CompatibilityCheckResponse compatibilityCheckResponse = createCompatiblityCheckResponse(errorMessages, verbose);
    asyncResponse.resume(compatibilityCheckResponse);
}
Also used : CompatibilityCheckResponse(io.confluent.kafka.schemaregistry.client.rest.entities.requests.CompatibilityCheckResponse) InvalidSchemaException(io.confluent.kafka.schemaregistry.exceptions.InvalidSchemaException) Schema(io.confluent.kafka.schemaregistry.client.rest.entities.Schema) AvroSchema(io.confluent.kafka.schemaregistry.avro.AvroSchema) ArrayList(java.util.ArrayList) SchemaRegistryException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryException) SchemaRegistryStoreException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryStoreException) Path(javax.ws.rs.Path) PerformanceMetric(io.confluent.rest.annotations.PerformanceMetric) POST(javax.ws.rs.POST) Operation(io.swagger.v3.oas.annotations.Operation)

Example 4 with InvalidSchemaException

use of io.confluent.kafka.schemaregistry.exceptions.InvalidSchemaException in project schema-registry by confluentinc.

the class CompatibilityResource method testCompatibilityBySubjectName.

@POST
@Path("/subjects/{subject}/versions/{version}")
@Operation(summary = "Test input schema against a particular version of a subject's schema for " + "compatibility.", description = "the compatibility level applied for the check is the configured compatibility level " + "for the subject (http:get:: /config/(string: subject)). If this subject's " + "compatibility level was never changed, then the global compatibility level " + "applies (http:get:: /config).", responses = { @ApiResponse(content = @Content(schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = CompatibilityCheckResponse.class))), @ApiResponse(responseCode = "404", description = "Error code 40401 -- Subject not found\n" + "Error code 40402 -- Version not found"), @ApiResponse(responseCode = "422", description = "Error code 42201 -- Invalid schema or schema type\n" + "Error code 42202 -- Invalid version"), @ApiResponse(responseCode = "500", description = "Error code 50001 -- Error in the " + "backend data store") })
@PerformanceMetric("compatibility.subjects.versions.verify")
public void testCompatibilityBySubjectName(@Suspended final AsyncResponse asyncResponse, @Parameter(description = "Subject of the schema version against which compatibility is to " + "be tested", required = true) @PathParam("subject") String subject, @Parameter(description = "Version of the subject's schema against which compatibility is to be " + "tested. Valid values for versionId are between [1,2^31-1] or the string " + "\"latest\"." + "\"latest\" checks compatibility of the input schema with the last registered " + "schema " + "under the specified subject", required = true) @PathParam("version") String version, @Parameter(description = "Schema", required = true) @NotNull RegisterSchemaRequest request, @Parameter(description = "Whether to return detailed error messages") @QueryParam("verbose") boolean verbose) {
    log.info("Testing schema subject {} compatibility between existing version {} and " + "specified version {}, id {}, type {}", subject, version, request.getVersion(), request.getId(), request.getSchemaType());
    subject = QualifiedSubject.normalize(schemaRegistry.tenant(), subject);
    // returns true if posted schema is compatible with the specified version. "latest" is
    // a special version
    List<String> errorMessages;
    VersionId versionId = parseVersionId(version);
    Schema schemaForSpecifiedVersion;
    try {
        // Don't check compatibility against deleted schema
        schemaForSpecifiedVersion = schemaRegistry.get(subject, versionId.getVersionId(), false);
    } catch (InvalidVersionException e) {
        throw Errors.invalidVersionException(e.getMessage());
    } catch (SchemaRegistryException e) {
        throw Errors.storeException("Error while retrieving schema for subject " + subject + " and version " + versionId.getVersionId(), e);
    }
    if (schemaForSpecifiedVersion == null && !versionId.isLatest()) {
        throw Errors.versionNotFoundException(versionId.getVersionId());
    }
    Schema schema = new Schema(subject, 0, -1, request.getSchemaType() != null ? request.getSchemaType() : AvroSchema.TYPE, request.getReferences(), request.getSchema());
    try {
        errorMessages = schemaRegistry.isCompatible(subject, schema, schemaForSpecifiedVersion != null ? Collections.singletonList(schemaForSpecifiedVersion) : Collections.emptyList());
    } catch (InvalidSchemaException e) {
        if (verbose) {
            errorMessages = Collections.singletonList(e.getMessage());
        } else {
            throw Errors.invalidSchemaException(e);
        }
    } catch (SchemaRegistryStoreException e) {
        throw Errors.storeException("Error while getting compatibility level for subject " + subject, e);
    } catch (SchemaRegistryException e) {
        throw Errors.schemaRegistryException("Error while getting compatibility level for subject " + subject, e);
    }
    CompatibilityCheckResponse compatibilityCheckResponse = createCompatiblityCheckResponse(errorMessages, verbose);
    asyncResponse.resume(compatibilityCheckResponse);
}
Also used : VersionId(io.confluent.kafka.schemaregistry.rest.VersionId) CompatibilityCheckResponse(io.confluent.kafka.schemaregistry.client.rest.entities.requests.CompatibilityCheckResponse) InvalidSchemaException(io.confluent.kafka.schemaregistry.exceptions.InvalidSchemaException) InvalidVersionException(io.confluent.kafka.schemaregistry.exceptions.InvalidVersionException) Schema(io.confluent.kafka.schemaregistry.client.rest.entities.Schema) AvroSchema(io.confluent.kafka.schemaregistry.avro.AvroSchema) SchemaRegistryException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryException) SchemaRegistryStoreException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryStoreException) Path(javax.ws.rs.Path) PerformanceMetric(io.confluent.rest.annotations.PerformanceMetric) POST(javax.ws.rs.POST) Operation(io.swagger.v3.oas.annotations.Operation)

Example 5 with InvalidSchemaException

use of io.confluent.kafka.schemaregistry.exceptions.InvalidSchemaException in project schema-registry by confluentinc.

the class KafkaSchemaRegistry method loadSchema.

private ParsedSchema loadSchema(String schemaType, String schema, List<io.confluent.kafka.schemaregistry.client.rest.entities.SchemaReference> references, boolean isNew) throws InvalidSchemaException {
    if (schemaType == null) {
        schemaType = AvroSchema.TYPE;
    }
    SchemaProvider provider = schemaProvider(schemaType);
    if (provider == null) {
        String errMsg = "Invalid schema type " + schemaType;
        log.error(errMsg);
        throw new InvalidSchemaException(errMsg);
    }
    final String type = schemaType;
    try {
        return provider.parseSchemaOrElseThrow(schema, references, isNew);
    } catch (Exception e) {
        throw new InvalidSchemaException("Invalid schema " + schema + " with refs " + references + " of type " + type + ", details: " + e.getMessage());
    }
}
Also used : InvalidSchemaException(io.confluent.kafka.schemaregistry.exceptions.InvalidSchemaException) ProtobufSchemaProvider(io.confluent.kafka.schemaregistry.protobuf.ProtobufSchemaProvider) SchemaProvider(io.confluent.kafka.schemaregistry.SchemaProvider) JsonSchemaProvider(io.confluent.kafka.schemaregistry.json.JsonSchemaProvider) AvroSchemaProvider(io.confluent.kafka.schemaregistry.avro.AvroSchemaProvider) SchemaString(io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString) IncompatibleSchemaException(io.confluent.kafka.schemaregistry.exceptions.IncompatibleSchemaException) RestException(io.confluent.rest.exceptions.RestException) SchemaRegistryException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryException) TimeoutException(java.util.concurrent.TimeoutException) ReferenceExistsException(io.confluent.kafka.schemaregistry.exceptions.ReferenceExistsException) InvalidSchemaException(io.confluent.kafka.schemaregistry.exceptions.InvalidSchemaException) RestClientException(io.confluent.kafka.schemaregistry.client.rest.exceptions.RestClientException) SchemaRegistryStoreException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryStoreException) StoreTimeoutException(io.confluent.kafka.schemaregistry.storage.exceptions.StoreTimeoutException) UnknownLeaderException(io.confluent.kafka.schemaregistry.exceptions.UnknownLeaderException) StoreException(io.confluent.kafka.schemaregistry.storage.exceptions.StoreException) OperationNotPermittedException(io.confluent.kafka.schemaregistry.exceptions.OperationNotPermittedException) SchemaVersionNotSoftDeletedException(io.confluent.kafka.schemaregistry.exceptions.SchemaVersionNotSoftDeletedException) IdGenerationException(io.confluent.kafka.schemaregistry.exceptions.IdGenerationException) SchemaRegistryTimeoutException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryTimeoutException) SubjectNotSoftDeletedException(io.confluent.kafka.schemaregistry.exceptions.SubjectNotSoftDeletedException) IOException(java.io.IOException) IdDoesNotMatchException(io.confluent.kafka.schemaregistry.exceptions.IdDoesNotMatchException) SchemaRegistryInitializationException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryInitializationException) ExecutionException(java.util.concurrent.ExecutionException) StoreInitializationException(io.confluent.kafka.schemaregistry.storage.exceptions.StoreInitializationException) SchemaRegistryRequestForwardingException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryRequestForwardingException)

Aggregations

InvalidSchemaException (io.confluent.kafka.schemaregistry.exceptions.InvalidSchemaException)6 SchemaRegistryException (io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryException)5 SchemaRegistryStoreException (io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryStoreException)5 AvroSchema (io.confluent.kafka.schemaregistry.avro.AvroSchema)4 Schema (io.confluent.kafka.schemaregistry.client.rest.entities.Schema)4 IdDoesNotMatchException (io.confluent.kafka.schemaregistry.exceptions.IdDoesNotMatchException)3 IncompatibleSchemaException (io.confluent.kafka.schemaregistry.exceptions.IncompatibleSchemaException)3 OperationNotPermittedException (io.confluent.kafka.schemaregistry.exceptions.OperationNotPermittedException)3 SchemaRegistryRequestForwardingException (io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryRequestForwardingException)3 SchemaRegistryTimeoutException (io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryTimeoutException)3 UnknownLeaderException (io.confluent.kafka.schemaregistry.exceptions.UnknownLeaderException)3 PerformanceMetric (io.confluent.rest.annotations.PerformanceMetric)3 Operation (io.swagger.v3.oas.annotations.Operation)3 POST (javax.ws.rs.POST)3 ParsedSchema (io.confluent.kafka.schemaregistry.ParsedSchema)2 SchemaString (io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString)2 CompatibilityCheckResponse (io.confluent.kafka.schemaregistry.client.rest.entities.requests.CompatibilityCheckResponse)2 RestClientException (io.confluent.kafka.schemaregistry.client.rest.exceptions.RestClientException)2 IdGenerationException (io.confluent.kafka.schemaregistry.exceptions.IdGenerationException)2 ReferenceExistsException (io.confluent.kafka.schemaregistry.exceptions.ReferenceExistsException)2