diff --git a/src/main/java/com/michelin/ns4kafka/controllers/SchemaController.java b/src/main/java/com/michelin/ns4kafka/controllers/SchemaController.java index cfae5c2d..3012f49c 100644 --- a/src/main/java/com/michelin/ns4kafka/controllers/SchemaController.java +++ b/src/main/java/com/michelin/ns4kafka/controllers/SchemaController.java @@ -25,12 +25,10 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.inject.Inject; import jakarta.validation.Valid; - import java.time.Instant; import java.util.Date; import java.util.List; import java.util.Optional; - import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -126,13 +124,16 @@ public Mono> apply(String namespace, @Valid @Body Schema sc .validateSchemaCompatibility(ns.getMetadata().getCluster(), schema) .flatMap(validationErrors -> { if (!validationErrors.isEmpty()) { - return Mono.error(new ResourceValidationException(validationErrors, schema.getKind(), + return Mono.error(new ResourceValidationException( + validationErrors, + schema.getKind(), schema.getMetadata().getName())); } if (dryrun) { return Mono.just(formatHttpResponse(schema, - latestSubjectOptional.isPresent() ? ApplyStatus.changed : ApplyStatus.created)); + latestSubjectOptional.isPresent() + ? ApplyStatus.changed : ApplyStatus.created)); } return schemaService diff --git a/src/test/java/com/michelin/ns4kafka/controllers/SchemaControllerTest.java b/src/test/java/com/michelin/ns4kafka/controllers/SchemaControllerTest.java index 2ff9d98a..60751760 100644 --- a/src/test/java/com/michelin/ns4kafka/controllers/SchemaControllerTest.java +++ b/src/test/java/com/michelin/ns4kafka/controllers/SchemaControllerTest.java @@ -3,8 +3,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.eq; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -82,7 +82,8 @@ void applyChanged() { when(namespaceService.findByName("myNamespace")).thenReturn(Optional.of(namespace)); when(schemaService.isNamespaceOwnerOfSubject(namespace, schema.getMetadata().getName())).thenReturn(true); - when(schemaService.validateSchemaCompatibility(eq("local"), any(Schema.class))).thenReturn(Mono.just(List.of())); + when(schemaService.validateSchemaCompatibility(eq("local"), any(Schema.class))) + .thenReturn(Mono.just(List.of())); when(schemaService.getLatestSubject(namespace, schema.getMetadata().getName())) .thenReturn(Mono.just(schema)); when(schemaService.register(namespace, schemaV2)).thenReturn(Mono.just(2)); @@ -183,8 +184,10 @@ void applyDryRunChanged() { Schema schemaV2 = buildSchemaV2(); when(namespaceService.findByName("myNamespace")).thenReturn(Optional.of(namespace)); - when(schemaService.isNamespaceOwnerOfSubject(namespace, schema.getMetadata().getName())).thenReturn(true); - when(schemaService.validateSchemaCompatibility(eq("local"), any(Schema.class))).thenReturn(Mono.just(List.of())); + when(schemaService.isNamespaceOwnerOfSubject(namespace, schema.getMetadata().getName())) + .thenReturn(true); + when(schemaService.validateSchemaCompatibility(eq("local"), any(Schema.class))) + .thenReturn(Mono.just(List.of())); when(schemaService.getLatestSubject(namespace, schema.getMetadata().getName())).thenReturn(Mono.just(schema)); StepVerifier.create(schemaController.apply("myNamespace", schemaV2, true)) @@ -451,24 +454,24 @@ private Schema buildSchema() { private Schema buildSchemaV2() { return Schema.builder() - .metadata(ObjectMeta.builder() - .name("prefix.subject-value") - .build()) - .spec(Schema.SchemaSpec.builder() - .id(1) - .version(2) - .schema( - "{\"namespace\":\"com.michelin.kafka.producer.showcase.avro\",\"type\":\"record\"," - + "\"name\":\"PersonAvro\"" - + ",\"fields\":[{\"name\":\"firstName\",\"type\":[\"null\",\"string\"],\"default\":null," - + "\"doc\":\"First name of the person\"},{\"name\":\"lastName\",\"type\":[\"null\",\"string\"]," - + "\"default\":null,\"doc\":\"Last name of the person\"}," - + "{\"name\":\"dateOfBirth\",\"type\":[\"null\",{\"type\":\"long\"," - + "\"logicalType\":\"timestamp-millis\"}],\"default\":null,\"doc\":\"Date of birth of the person\"}," - + "{\"name\":\"birthPlace\",\"type\":[\"null\",\"string\"]," - + "\"default\":null,\"doc\":\"Place of birth\"}]}") - .build()) - .build(); + .metadata(ObjectMeta.builder() + .name("prefix.subject-value") + .build()) + .spec(Schema.SchemaSpec.builder() + .id(1) + .version(2) + .schema( + "{\"namespace\":\"com.michelin.kafka.producer.showcase.avro\",\"type\":\"record\"," + + "\"name\":\"PersonAvro\"" + + ",\"fields\":[{\"name\":\"firstName\",\"type\":[\"null\",\"string\"],\"default\":null," + + "\"doc\":\"First name of the person\"},{\"name\":\"lastName\",\"type\":[\"null\"," + + "\"string\"],\"default\":null,\"doc\":\"Last name of the person\"}," + + "{\"name\":\"dateOfBirth\",\"type\":[\"null\",{\"type\":\"long\"," + + "\"logicalType\":\"timestamp-millis\"}],\"default\":null," + + "\"doc\":\"Date of birth of the person\"},{\"name\":\"birthPlace\",\"type\":[\"null\"," + + "\"string\"],\"default\":null,\"doc\":\"Place of birth\"}]}") + .build()) + .build(); } private SchemaList buildSchemaList() { diff --git a/src/test/java/com/michelin/ns4kafka/integration/SchemaTest.java b/src/test/java/com/michelin/ns4kafka/integration/SchemaTest.java index 3f6b2478..8da971c1 100644 --- a/src/test/java/com/michelin/ns4kafka/integration/SchemaTest.java +++ b/src/test/java/com/michelin/ns4kafka/integration/SchemaTest.java @@ -464,36 +464,20 @@ void registerSchema() { @Test void registerSameSchemaTwice() { Schema schema = Schema.builder() - .metadata(ObjectMeta.builder() - .name("ns1-subject3-value") - .build()) - .spec(Schema.SchemaSpec.builder() - .schema( - "{\"namespace\":\"com.michelin.kafka.producer.showcase.avro\",\"type\":\"record\"," - + "\"name\":\"PersonAvro\",\"fields\":[{\"name\":\"firstName\",\"type\":[\"null\",\"string\"]," - + "\"default\":null,\"doc\":\"First name of the person\"}," - + "{\"name\":\"lastName\",\"type\":[\"null\",\"string\"],\"default\":null," - + "\"doc\":\"Last name of the person\"},{\"name\":\"dateOfBirth\",\"type\":[\"null\"," - + "{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}],\"default\":null," - + "\"doc\":\"Date of birth of the person\"}]}") - .build()) - .build(); - - Schema sameSchemaWithSwappedFields = Schema.builder() - .metadata(ObjectMeta.builder() - .name("ns1-subject3-value") - .build()) - .spec(Schema.SchemaSpec.builder() - .schema( - "{\"namespace\":\"com.michelin.kafka.producer.showcase.avro\",\"type\":\"record\"," - + "\"name\":\"PersonAvro\",\"fields\":[ {\"name\":\"lastName\",\"type\":[\"null\",\"string\"]," - + "\"default\":null, \"doc\":\"Last name of the person\"}," - + "{\"name\":\"firstName\",\"type\":[\"null\",\"string\"], \"default\":null," - + "\"doc\":\"First name of the person\"}, {\"name\":\"dateOfBirth\",\"type\":[\"null\"," - + "{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}],\"default\":null," - + "\"doc\":\"Date of birth of the person\"}]}") - .build()) - .build(); + .metadata(ObjectMeta.builder() + .name("ns1-subject3-value") + .build()) + .spec(Schema.SchemaSpec.builder() + .schema( + "{\"namespace\":\"com.michelin.kafka.producer.showcase.avro\",\"type\":\"record\"," + + "\"name\":\"PersonAvro\",\"fields\":[{\"name\":\"firstName\",\"type\":[\"null\",\"string\"]," + + "\"default\":null,\"doc\":\"First name of the person\"}," + + "{\"name\":\"lastName\",\"type\":[\"null\",\"string\"],\"default\":null," + + "\"doc\":\"Last name of the person\"},{\"name\":\"dateOfBirth\",\"type\":[\"null\"," + + "{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}],\"default\":null," + + "\"doc\":\"Date of birth of the person\"}]}") + .build()) + .build(); // Apply schema var createResponse = @@ -514,6 +498,22 @@ void registerSameSchemaTwice() { .anyMatch(schemaList -> schemaList.getMetadata().getName().equals("ns1-subject3-value"))); // Apply the same schema with swapped fields + Schema sameSchemaWithSwappedFields = Schema.builder() + .metadata(ObjectMeta.builder() + .name("ns1-subject3-value") + .build()) + .spec(Schema.SchemaSpec.builder() + .schema( + "{\"namespace\":\"com.michelin.kafka.producer.showcase.avro\",\"type\":\"record\"," + + "\"name\":\"PersonAvro\",\"fields\":[ {\"name\":\"lastName\",\"type\":[\"null\",\"string\"]," + + "\"default\":null, \"doc\":\"Last name of the person\"}," + + "{\"name\":\"firstName\",\"type\":[\"null\",\"string\"], \"default\":null," + + "\"doc\":\"First name of the person\"}, {\"name\":\"dateOfBirth\",\"type\":[\"null\"," + + "{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}],\"default\":null," + + "\"doc\":\"Date of birth of the person\"}]}") + .build()) + .build(); + var createSwappedFieldsResponse = ns4KafkaClient.toBlocking().exchange(HttpRequest.create(HttpMethod.POST, "/api/namespaces/ns1/schemas") .bearerAuth(token) @@ -545,7 +545,7 @@ void registerSameSchemaTwice() { request.setSchema(sameSchemaWithSwappedFields.getSpec().getSchema()); schemaRegistryClient.toBlocking() - .exchange(HttpRequest.create(HttpMethod.POST,"/subjects/ns1-subject3-value/versions") + .exchange(HttpRequest.create(HttpMethod.POST, "/subjects/ns1-subject3-value/versions") .body(request), RegisterSchemaResponse.class); SchemaResponse schemaAfterPostOnRegistry = schemaRegistryClient.toBlocking()