Search in sources :

Example 6 with SchemaString

use of io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString in project schema-registry by confluentinc.

the class LeaderElectorTest method testRegistrationOnLeaderFollowerClusters.

@Test
public /**
 * Test registration of schemas and fetching by id when a 'leader cluster' and 'follower cluster'
 * is present. (follwer cluster == all nodes have leaderEligibility false)
 *
 * If only followers are alive, registration should fail. If both follower and leader cluster are
 * alive, registration should succeed.
 *
 * Fetching by id should succeed in all configurations.
 */
void testRegistrationOnLeaderFollowerClusters() throws Exception {
    int numFollowers = 4;
    int numLeaders = 4;
    int numSchemas = 5;
    String subject = "testSubject";
    List<String> schemas = TestUtils.getRandomCanonicalAvroString(numSchemas);
    List<Integer> ids = new ArrayList<Integer>();
    Set<RestApp> followerApps = new HashSet<RestApp>();
    RestApp aFollower = null;
    for (int i = 0; i < numFollowers; i++) {
        RestApp follower = new RestApp(choosePort(), zkConnect(), bootstrapServers(), KAFKASTORE_TOPIC, CompatibilityLevel.NONE.name, false, null);
        followerApps.add(follower);
        follower.start();
        aFollower = follower;
    }
    // Sanity check
    assertNotNull(aFollower);
    // Try to register schemas to a follower - should fail
    boolean successfullyRegistered = false;
    try {
        aFollower.restClient.registerSchema(schemas.get(0), subject);
        successfullyRegistered = true;
    } catch (RestClientException e) {
    // registration should fail
    }
    assertFalse("Should not be possible to register with no leaders present.", successfullyRegistered);
    // Make a leader-eligible 'cluster'
    final Set<RestApp> leaderApps = new HashSet<RestApp>();
    RestApp aLeader = null;
    for (int i = 0; i < numLeaders; i++) {
        RestApp leader = new RestApp(choosePort(), zkConnect(), bootstrapServers(), KAFKASTORE_TOPIC, CompatibilityLevel.NONE.name, true, null);
        leaderApps.add(leader);
        leader.start();
        aLeader = leader;
    }
    assertNotNull(aLeader);
    // Try to register to a leader cluster node - should succeed
    try {
        for (String schema : schemas) {
            ids.add(aLeader.restClient.registerSchema(schema, subject));
        }
    } catch (RestClientException e) {
        fail("It should be possible to register schemas when a leader cluster is present.");
    }
    // Try to register to a follower cluster node - should succeed
    String anotherSchema = TestUtils.getRandomCanonicalAvroString(1).get(0);
    try {
        ids.add(aFollower.restClient.registerSchema(anotherSchema, subject));
    } catch (RestClientException e) {
        fail("Should be possible register a schema through follower cluster.");
    }
    // Verify all ids can be fetched
    try {
        for (int id : ids) {
            waitUntilIdExists(aFollower.restClient, id, String.format("Should be possible to fetch id %d from this follower.", id));
            waitUntilIdExists(aLeader.restClient, id, String.format("Should be possible to fetch id %d from this leader.", id));
            SchemaString followerResponse = aFollower.restClient.getId(id);
            SchemaString leaderResponse = aLeader.restClient.getId(id);
            assertEquals("Leader and follower responded with different schemas when queried with the same id.", followerResponse.getSchemaString(), leaderResponse.getSchemaString());
        }
    } catch (RestClientException e) {
        fail("Expected ids were not found in the schema registry.");
    }
    // Stop everything in the leader cluster
    while (leaderApps.size() > 0) {
        RestApp leader = findLeader(leaderApps);
        leaderApps.remove(leader);
        leader.stop();
        waitUntilLeaderElectionCompletes(leaderApps);
    }
    // Try to register a new schema - should fail
    anotherSchema = TestUtils.getRandomCanonicalAvroString(1).get(0);
    successfullyRegistered = false;
    try {
        aFollower.restClient.registerSchema(anotherSchema, subject);
        successfullyRegistered = true;
    } catch (RestClientException e) {
    // should fail
    }
    assertFalse("Should not be possible to register with no leaders present.", successfullyRegistered);
    // Try fetching preregistered ids from followers - should succeed
    try {
        for (int id : ids) {
            SchemaString schemaString = aFollower.restClient.getId(id);
        }
        List<Integer> versions = aFollower.restClient.getAllVersions(subject);
        assertEquals("Number of ids should match number of versions.", ids.size(), versions.size());
    } catch (RestClientException e) {
        fail("Should be possible to fetch registered schemas even with no leaders present.");
    }
    for (RestApp follower : followerApps) {
        follower.stop();
    }
}
Also used : SchemaString(io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString) ArrayList(java.util.ArrayList) RestClientException(io.confluent.kafka.schemaregistry.client.rest.exceptions.RestClientException) SchemaString(io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 7 with SchemaString

use of io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString in project schema-registry by confluentinc.

the class RestApiTest method testSchemaReferencesMultipleLevels.

@Test
public void testSchemaReferencesMultipleLevels() throws Exception {
    String root = "[\"myavro.BudgetDecreased\",\"myavro.BudgetUpdated\"]";
    String ref1 = "{\n" + "  \"type\" : \"record\",\n" + "  \"name\" : \"BudgetDecreased\",\n" + "  \"namespace\" : \"myavro\",\n" + "  \"fields\" : [ {\n" + "    \"name\" : \"buyerId\",\n" + "    \"type\" : \"long\"\n" + "  }, {\n" + "    \"name\" : \"currency\",\n" + "    \"type\" : {\n" + "      \"type\" : \"myavro.currencies.Currency\"" + "    }\n" + "  }, {\n" + "    \"name\" : \"amount\",\n" + "    \"type\" : \"double\"\n" + "  } ]\n" + "}";
    String ref2 = "{\n" + "  \"type\" : \"record\",\n" + "  \"name\" : \"BudgetUpdated\",\n" + "  \"namespace\" : \"myavro\",\n" + "  \"fields\" : [ {\n" + "    \"name\" : \"buyerId\",\n" + "    \"type\" : \"long\"\n" + "  }, {\n" + "    \"name\" : \"currency\",\n" + "    \"type\" : {\n" + "      \"type\" : \"myavro.currencies.Currency\"" + "    }\n" + "  }, {\n" + "    \"name\" : \"updatedValue\",\n" + "    \"type\" : \"double\"\n" + "  } ]\n" + "}";
    String sharedRef = "{\n" + "      \"type\" : \"enum\",\n" + "      \"name\" : \"Currency\",\n" + "      \"namespace\" : \"myavro.currencies\",\n" + "      \"symbols\" : [ \"EUR\", \"USD\" ]\n" + "    }\n";
    TestUtils.registerAndVerifySchema(restApp.restClient, new AvroSchema(sharedRef).canonicalString(), 1, "shared");
    RegisterSchemaRequest request = new RegisterSchemaRequest();
    request.setSchema(ref1);
    SchemaReference ref = new SchemaReference("myavro.currencies.Currency", "shared", 1);
    request.setReferences(Collections.singletonList(ref));
    int registeredId = restApp.restClient.registerSchema(request, "ref1", false);
    assertEquals("Registering a new schema should succeed", 2, registeredId);
    request = new RegisterSchemaRequest();
    request.setSchema(ref2);
    ref = new SchemaReference("myavro.currencies.Currency", "shared", 1);
    request.setReferences(Collections.singletonList(ref));
    registeredId = restApp.restClient.registerSchema(request, "ref2", false);
    assertEquals("Registering a new schema should succeed", 3, registeredId);
    request = new RegisterSchemaRequest();
    request.setSchema(root);
    SchemaReference r1 = new SchemaReference("myavro.BudgetDecreased", "ref1", 1);
    SchemaReference r2 = new SchemaReference("myavro.BudgetUpdated", "ref2", 1);
    request.setReferences(Arrays.asList(r1, r2));
    registeredId = restApp.restClient.registerSchema(request, "root", false);
    assertEquals("Registering a new schema should succeed", 4, registeredId);
    SchemaString schemaString = restApp.restClient.getId(4);
    // the newly registered schema should be immediately readable on the leader
    assertEquals("Registered schema should be found", root, schemaString.getSchemaString());
    assertEquals("Schema references should be found", Arrays.asList(r1, r2), schemaString.getReferences());
}
Also used : SchemaReference(io.confluent.kafka.schemaregistry.client.rest.entities.SchemaReference) AvroSchema(io.confluent.kafka.schemaregistry.avro.AvroSchema) SchemaString(io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString) SchemaString(io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString) RegisterSchemaRequest(io.confluent.kafka.schemaregistry.client.rest.entities.requests.RegisterSchemaRequest) Test(org.junit.Test)

Example 8 with SchemaString

use of io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString in project schema-registry by confluentinc.

the class RestApiTest method testRegisterBadDefault.

@Test
public void testRegisterBadDefault() throws Exception {
    String subject = "testSubject";
    String schemaString = "{\"type\":\"record\"," + "\"name\":\"myrecord\"," + "\"fields\":" + "[{\"type\":\"string\",\"default\":null,\"name\":" + "\"f" + "\"}]}";
    String schema = AvroUtils.parseSchema(schemaString).canonicalString();
    try {
        restApp.restClient.testCompatibility(schema, subject, "latest");
        fail("Testing compatibility for schema with invalid default should fail with " + Errors.INVALID_SCHEMA_ERROR_CODE + " (invalid schema)");
    } catch (RestClientException rce) {
        assertEquals("Invalid schema", Errors.INVALID_SCHEMA_ERROR_CODE, rce.getErrorCode());
    }
    try {
        restApp.restClient.registerSchema(schema, subject);
        fail("Registering schema with invalid default should fail with " + Errors.INVALID_SCHEMA_ERROR_CODE + " (invalid schema)");
    } catch (RestClientException rce) {
        assertEquals("Invalid schema", Errors.INVALID_SCHEMA_ERROR_CODE, rce.getErrorCode());
    }
}
Also used : RestClientException(io.confluent.kafka.schemaregistry.client.rest.exceptions.RestClientException) SchemaString(io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString) Test(org.junit.Test)

Example 9 with SchemaString

use of io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString in project schema-registry by confluentinc.

the class RestApiTest method getProtobufSchemaWithDependencies.

public static Map<String, String> getProtobufSchemaWithDependencies() {
    Map<String, String> schemas = new HashMap<>();
    String meta = ResourceLoader.DEFAULT.toString("confluent/meta.proto");
    schemas.put("confluent/meta.proto", meta);
    String reference = "syntax = \"proto3\";\npackage io.confluent.kafka.serializers.protobuf.test;\n\n" + "message ReferencedMessage {\n  string ref_id = 1;\n  bool is_active = 2;\n}\n";
    schemas.put("ref.proto", reference);
    String schemaString = "syntax = \"proto3\";\n" + "package io.confluent.kafka.serializers.protobuf.test;\n" + "\n" + "import \"ref.proto\";\n" + "import \"confluent/meta.proto\";\n" + "\n" + "message ReferrerMessage {\n" + "  option (confluent.message_meta) = {\n" + "    doc: \"ReferrerMessage\"\n" + "  };\n" + "\n" + "  string root_id = 1;\n" + "  .io.confluent.kafka.serializers.protobuf.test.ReferencedMessage ref = 2 [(confluent.field_meta) = {\n" + "    doc: \"ReferencedMessage\"\n" + "  }];\n" + "}\n";
    schemas.put("root.proto", schemaString);
    return schemas;
}
Also used : HashMap(java.util.HashMap) SchemaString(io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString) ByteString(com.google.protobuf.ByteString)

Example 10 with SchemaString

use of io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString in project schema-registry by confluentinc.

the class SchemasResource method getSchema.

@GET
@Path("/ids/{id}")
@Operation(summary = "Get the schema string identified by the input ID.", responses = { @ApiResponse(responseCode = "404", description = "Error code 40403 -- Schema not found\n"), @ApiResponse(responseCode = "500", description = "Error code 50001 -- Error in the backend data store\n") })
@PerformanceMetric("schemas.ids.get-schema")
public SchemaString getSchema(@Parameter(description = "Globally unique identifier of the schema", required = true) @PathParam("id") Integer id, @Parameter(description = "Name of the subject") @QueryParam("subject") String subject, @Parameter(description = "Desired output format, dependent on schema type") @DefaultValue("") @QueryParam("format") String format, @Parameter(description = "Whether to fetch the maximum schema identifier that exists") @DefaultValue("false") @QueryParam("fetchMaxId") boolean fetchMaxId) {
    SchemaString schema;
    String errorMessage = "Error while retrieving schema with id " + id + " from the schema " + "registry";
    try {
        schema = schemaRegistry.get(id, subject, format, fetchMaxId);
    } catch (SchemaRegistryStoreException e) {
        log.debug(errorMessage, e);
        throw Errors.storeException(errorMessage, e);
    } catch (SchemaRegistryException e) {
        throw Errors.schemaRegistryException(errorMessage, e);
    }
    if (schema == null) {
        throw Errors.schemaNotFoundException(id);
    }
    return schema;
}
Also used : SchemaString(io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString) SchemaRegistryStoreException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryStoreException) SchemaRegistryException(io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryException) SchemaString(io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString) Path(javax.ws.rs.Path) PerformanceMetric(io.confluent.rest.annotations.PerformanceMetric) GET(javax.ws.rs.GET) Operation(io.swagger.v3.oas.annotations.Operation)

Aggregations

SchemaString (io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString)21 Test (org.junit.Test)14 RestClientException (io.confluent.kafka.schemaregistry.client.rest.exceptions.RestClientException)10 SchemaReference (io.confluent.kafka.schemaregistry.client.rest.entities.SchemaReference)5 Schema (io.confluent.kafka.schemaregistry.client.rest.entities.Schema)4 RegisterSchemaRequest (io.confluent.kafka.schemaregistry.client.rest.entities.requests.RegisterSchemaRequest)4 ArrayList (java.util.ArrayList)4 ByteString (com.google.protobuf.ByteString)3 AvroSchema (io.confluent.kafka.schemaregistry.avro.AvroSchema)3 HashMap (java.util.HashMap)3 ParsedSchema (io.confluent.kafka.schemaregistry.ParsedSchema)2 SchemaRegistryStoreException (io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryStoreException)2 JsonSchema (io.confluent.kafka.schemaregistry.json.JsonSchema)2 IOException (java.io.IOException)2 HashSet (java.util.HashSet)2 List (java.util.List)2 EasyMock.anyString (org.easymock.EasyMock.anyString)2 FakeTicker (com.google.common.testing.FakeTicker)1 CachedSchemaRegistryClient (io.confluent.kafka.schemaregistry.client.CachedSchemaRegistryClient)1 SchemaRegistryException (io.confluent.kafka.schemaregistry.exceptions.SchemaRegistryException)1