Include schema type to schema objects. By default it's AVRO
This commit is contained in:
parent
239f7e1158
commit
a617a09bc5
3 changed files with 56 additions and 31 deletions
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Add table
Reference in a new issue