Include schema type to schema objects. By default it's AVRO

This commit is contained in:
Ildar Almakaev 2021-03-04 15:02:09 +03:00
parent 239f7e1158
commit a617a09bc5
3 changed files with 56 additions and 31 deletions

View file

@ -1,10 +1,16 @@
package com.provectus.kafka.ui.cluster.model.schemaregistry; package com.provectus.kafka.ui.cluster.model.schemaregistry;
import lombok.AllArgsConstructor; import com.provectus.kafka.ui.model.NewSchemaSubject;
import com.provectus.kafka.ui.model.SchemaType;
import lombok.Data; import lombok.Data;
@Data @Data
@AllArgsConstructor
public class InternalNewSchema { public class InternalNewSchema {
private String schema; private String schema;
private SchemaType schemaType;
public InternalNewSchema(NewSchemaSubject schemaSubject) {
this.schema = schemaSubject.getSchema();
this.schemaType = schemaSubject.getSchemaType();
}
} }

View file

@ -10,10 +10,7 @@ import com.provectus.kafka.ui.cluster.model.schemaregistry.InternalCompatibility
import com.provectus.kafka.ui.cluster.model.schemaregistry.InternalCompatibilityLevel; import com.provectus.kafka.ui.cluster.model.schemaregistry.InternalCompatibilityLevel;
import com.provectus.kafka.ui.cluster.model.schemaregistry.InternalNewSchema; import com.provectus.kafka.ui.cluster.model.schemaregistry.InternalNewSchema;
import com.provectus.kafka.ui.cluster.model.schemaregistry.SubjectIdResponse; import com.provectus.kafka.ui.cluster.model.schemaregistry.SubjectIdResponse;
import com.provectus.kafka.ui.model.CompatibilityCheckResponse; import com.provectus.kafka.ui.model.*;
import com.provectus.kafka.ui.model.CompatibilityLevel;
import com.provectus.kafka.ui.model.NewSchemaSubject;
import com.provectus.kafka.ui.model.SchemaSubject;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -37,6 +34,10 @@ import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
@Log4j2 @Log4j2
@RequiredArgsConstructor @RequiredArgsConstructor
public class SchemaRegistryService { public class SchemaRegistryService {
public static final String NO_SUCH_SCHEMA_VERSION = "No such schema %s with version %s";
public static final String NO_SUCH_SCHEMA = "No such schema %s";
public static final String NO_SUCH_CLUSTER = "No such cluster";
private static final String URL_SUBJECTS = "/subjects"; private static final String URL_SUBJECTS = "/subjects";
private static final String URL_SUBJECT = "/subjects/{schemaName}"; private static final String URL_SUBJECT = "/subjects/{schemaName}";
private static final String URL_SUBJECT_VERSIONS = "/subjects/{schemaName}/versions"; private static final String URL_SUBJECT_VERSIONS = "/subjects/{schemaName}/versions";
@ -62,7 +63,7 @@ public class SchemaRegistryService {
.bodyToMono(String[].class) .bodyToMono(String[].class)
.doOnError(log::error) .doOnError(log::error)
) )
.orElse(Mono.error(new NotFoundException("No such cluster"))); .orElse(Mono.error(new NotFoundException(NO_SUCH_CLUSTER)));
} }
public Flux<SchemaSubject> getAllVersionsBySubject(String clusterName, String subject) { public Flux<SchemaSubject> getAllVersionsBySubject(String clusterName, String subject) {
@ -76,9 +77,9 @@ public class SchemaRegistryService {
.uri(cluster.getSchemaRegistry() + URL_SUBJECT_VERSIONS, schemaName) .uri(cluster.getSchemaRegistry() + URL_SUBJECT_VERSIONS, schemaName)
.retrieve() .retrieve()
.onStatus(NOT_FOUND::equals, .onStatus(NOT_FOUND::equals,
throwIfNotFoundStatus(formatted("No such schema %s")) throwIfNotFoundStatus(formatted(NO_SUCH_SCHEMA))
).bodyToFlux(Integer.class) ).bodyToFlux(Integer.class)
).orElse(Flux.error(new NotFoundException("No such cluster"))); ).orElse(Flux.error(new NotFoundException(NO_SUCH_CLUSTER)));
} }
public Mono<SchemaSubject> getSchemaSubjectByVersion(String clusterName, String schemaName, Integer version) { public Mono<SchemaSubject> getSchemaSubjectByVersion(String clusterName, String schemaName, Integer version) {
@ -95,8 +96,9 @@ public class SchemaRegistryService {
.uri(cluster.getSchemaRegistry() + URL_SUBJECT_BY_VERSION, schemaName, version) .uri(cluster.getSchemaRegistry() + URL_SUBJECT_BY_VERSION, schemaName, version)
.retrieve() .retrieve()
.onStatus(NOT_FOUND::equals, .onStatus(NOT_FOUND::equals,
throwIfNotFoundStatus(formatted("No such schema %s with version %s", schemaName, version)) throwIfNotFoundStatus(formatted(NO_SUCH_SCHEMA_VERSION, schemaName, version))
).bodyToMono(SchemaSubject.class) ).bodyToMono(SchemaSubject.class)
.map(this::withSchemaType)
.zipWith(getSchemaCompatibilityInfoOrGlobal(clusterName, schemaName)) .zipWith(getSchemaCompatibilityInfoOrGlobal(clusterName, schemaName))
.map(tuple -> { .map(tuple -> {
SchemaSubject schema = tuple.getT1(); SchemaSubject schema = tuple.getT1();
@ -105,7 +107,21 @@ public class SchemaRegistryService {
return schema; return schema;
}) })
) )
.orElse(Mono.error(new NotFoundException("No such cluster"))); .orElse(Mono.error(new NotFoundException(NO_SUCH_CLUSTER)));
}
/**
* If {@link SchemaSubject#getSchemaType()} is null, then AVRO, otherwise, adds the schema type as is.
*/
@NotNull
private SchemaSubject withSchemaType(SchemaSubject s) {
SchemaType schemaType = Objects.nonNull(s.getSchemaType()) ? s.getSchemaType() : SchemaType.AVRO;
return new SchemaSubject()
.schema(s.getSchema())
.subject(s.getSubject())
.version(s.getVersion())
.id(s.getId())
.schemaType(schemaType);
} }
public Mono<ResponseEntity<Void>> deleteSchemaSubjectByVersion(String clusterName, String schemaName, Integer version) { public Mono<ResponseEntity<Void>> deleteSchemaSubjectByVersion(String clusterName, String schemaName, Integer version) {
@ -122,9 +138,9 @@ public class SchemaRegistryService {
.uri(cluster.getSchemaRegistry() + URL_SUBJECT_BY_VERSION, schemaName, version) .uri(cluster.getSchemaRegistry() + URL_SUBJECT_BY_VERSION, schemaName, version)
.retrieve() .retrieve()
.onStatus(NOT_FOUND::equals, .onStatus(NOT_FOUND::equals,
throwIfNotFoundStatus(formatted("No such schema %s with version %s", schemaName, version)) throwIfNotFoundStatus(formatted(NO_SUCH_SCHEMA_VERSION, schemaName, version))
).toBodilessEntity() ).toBodilessEntity()
).orElse(Mono.error(new NotFoundException("No such cluster"))); ).orElse(Mono.error(new NotFoundException(NO_SUCH_CLUSTER)));
} }
public Mono<ResponseEntity<Void>> deleteSchemaSubjectEntirely(String clusterName, String schemaName) { public Mono<ResponseEntity<Void>> deleteSchemaSubjectEntirely(String clusterName, String schemaName) {
@ -132,10 +148,10 @@ public class SchemaRegistryService {
.map(cluster -> webClient.delete() .map(cluster -> webClient.delete()
.uri(cluster.getSchemaRegistry() + URL_SUBJECT, schemaName) .uri(cluster.getSchemaRegistry() + URL_SUBJECT, schemaName)
.retrieve() .retrieve()
.onStatus(NOT_FOUND::equals, throwIfNotFoundStatus(formatted("No such schema %s", schemaName)) .onStatus(NOT_FOUND::equals, throwIfNotFoundStatus(formatted(NO_SUCH_SCHEMA, schemaName))
) )
.toBodilessEntity()) .toBodilessEntity())
.orElse(Mono.error(new NotFoundException("No such cluster"))); .orElse(Mono.error(new NotFoundException(NO_SUCH_CLUSTER)));
} }
/** /**
@ -145,7 +161,7 @@ public class SchemaRegistryService {
public Mono<SchemaSubject> registerNewSchema(String clusterName, Mono<NewSchemaSubject> newSchemaSubject) { public Mono<SchemaSubject> registerNewSchema(String clusterName, Mono<NewSchemaSubject> newSchemaSubject) {
return newSchemaSubject return newSchemaSubject
.flatMap(schema -> { .flatMap(schema -> {
Mono<InternalNewSchema> newSchema = Mono.just(new InternalNewSchema(schema.getSchema())); Mono<InternalNewSchema> newSchema = Mono.just(new InternalNewSchema(schema));
String subject = schema.getSubject(); String subject = schema.getSubject();
return clustersStorage.getClusterByName(clusterName) return clustersStorage.getClusterByName(clusterName)
.map(KafkaCluster::getSchemaRegistry) .map(KafkaCluster::getSchemaRegistry)
@ -153,7 +169,7 @@ public class SchemaRegistryService {
.flatMap(s -> submitNewSchema(subject, newSchema, schemaRegistryUrl)) .flatMap(s -> submitNewSchema(subject, newSchema, schemaRegistryUrl))
.flatMap(resp -> getLatestSchemaVersionBySubject(clusterName, subject)) .flatMap(resp -> getLatestSchemaVersionBySubject(clusterName, subject))
) )
.orElse(Mono.error(new NotFoundException("No such cluster"))); .orElse(Mono.error(new NotFoundException(NO_SUCH_CLUSTER)));
}); });
} }
@ -203,9 +219,9 @@ public class SchemaRegistryService {
.body(BodyInserters.fromPublisher(compatibilityLevel, CompatibilityLevel.class)) .body(BodyInserters.fromPublisher(compatibilityLevel, CompatibilityLevel.class))
.retrieve() .retrieve()
.onStatus(NOT_FOUND::equals, .onStatus(NOT_FOUND::equals,
throwIfNotFoundStatus(formatted("No such schema %s", schemaName))) throwIfNotFoundStatus(formatted(NO_SUCH_SCHEMA, schemaName)))
.bodyToMono(Void.class); .bodyToMono(Void.class);
}).orElse(Mono.error(new NotFoundException("No such cluster"))); }).orElse(Mono.error(new NotFoundException(NO_SUCH_CLUSTER)));
} }
public Mono<Void> updateSchemaCompatibility(String clusterName, Mono<CompatibilityLevel> compatibilityLevel) { public Mono<Void> updateSchemaCompatibility(String clusterName, Mono<CompatibilityLevel> compatibilityLevel) {
@ -241,24 +257,14 @@ public class SchemaRegistryService {
.contentType(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromPublisher(newSchemaSubject, NewSchemaSubject.class)) .body(BodyInserters.fromPublisher(newSchemaSubject, NewSchemaSubject.class))
.retrieve() .retrieve()
.onStatus(NOT_FOUND::equals, throwIfNotFoundStatus(formatted("No such schema %s", schemaName))) .onStatus(NOT_FOUND::equals, throwIfNotFoundStatus(formatted(NO_SUCH_SCHEMA, schemaName)))
.bodyToMono(InternalCompatibilityCheck.class) .bodyToMono(InternalCompatibilityCheck.class)
.map(mapper::toCompatibilityCheckResponse) .map(mapper::toCompatibilityCheckResponse)
.log() .log()
).orElse(Mono.error(new NotFoundException("No such cluster"))); ).orElse(Mono.error(new NotFoundException(NO_SUCH_CLUSTER)));
} }
public String formatted(String str, Object... args) { public String formatted(String str, Object... args) {
return new Formatter().format(str, args).toString(); return new Formatter().format(str, args).toString();
} }
public static String extractRecordType(String schema) {
if (schema.contains("record")) {
return "AVRO";
} else if (schema.contains("proto")) {
return "PROTO";
} else if (schema.contains("json")) {
return "JSON";
} else return schema;
}
} }

View file

@ -1338,12 +1338,15 @@ components:
type: string type: string
compatibilityLevel: compatibilityLevel:
type: string type: string
schemaType:
$ref: '#/components/schemas/SchemaType'
required: required:
- id - id
- subject - subject
- version - version
- schema - schema
- compatibilityLevel - compatibilityLevel
- schemaType
NewSchemaSubject: NewSchemaSubject:
type: object type: object
@ -1352,9 +1355,12 @@ components:
type: string type: string
schema: schema:
type: string type: string
schemaType:
$ref: '#/components/schemas/SchemaType'
required: required:
- subject - subject
- schema - schema
- schemaType
CompatibilityLevel: CompatibilityLevel:
type: object type: object
@ -1372,6 +1378,13 @@ components:
required: required:
- compatibility - compatibility
SchemaType:
type: string
enum:
- AVRO
- JSON
- PROTOBUF
CompatibilityCheckResponse: CompatibilityCheckResponse:
type: object type: object
properties: properties: