use of org.zalando.nakadi.exceptions.InvalidEventTypeException in project nakadi by zalando.
the class SchemaEvolutionServiceTest method compatibilityModeMigrationAllowedChanges.
@Test
public void compatibilityModeMigrationAllowedChanges() throws Exception {
final EventTypeTestBuilder builder = EventTypeTestBuilder.builder().compatibilityMode(CompatibilityMode.FORWARD);
final EventType oldEventType = builder.build();
final EventType newEventType = builder.compatibilityMode(CompatibilityMode.COMPATIBLE).build();
Mockito.doReturn(Optional.empty()).when(evolutionConstraint).validate(oldEventType, newEventType);
final List<SchemaChange.Type> allowedChanges = Lists.newArrayList(DESCRIPTION_CHANGED, TITLE_CHANGED, PROPERTIES_ADDED, REQUIRED_ARRAY_EXTENDED, ADDITIONAL_PROPERTIES_CHANGED, ADDITIONAL_ITEMS_CHANGED);
final List<SchemaChange.Type> notAllowedChanges = Lists.newArrayList(ID_CHANGED, SCHEMA_REMOVED, TYPE_CHANGED, NUMBER_OF_ITEMS_CHANGED, PROPERTY_REMOVED, DEPENDENCY_ARRAY_CHANGED, DEPENDENCY_SCHEMA_CHANGED, COMPOSITION_METHOD_CHANGED, ATTRIBUTE_VALUE_CHANGED, ENUM_ARRAY_CHANGED, SUB_SCHEMA_CHANGED, DEPENDENCY_SCHEMA_REMOVED, REQUIRED_ARRAY_CHANGED);
allowedChanges.forEach(changeType -> {
Mockito.doReturn(MINOR).when(forwardChanges).get(any());
Mockito.doReturn(Lists.newArrayList(new SchemaChange(changeType, "#/"))).when(schemaDiff).collectChanges(any(), any());
final EventType eventType;
try {
eventType = service.evolve(oldEventType, newEventType);
assertThat(eventType.getSchema().getVersion(), is(equalTo(new Version("1.1.0"))));
} catch (final InvalidEventTypeException e) {
fail();
}
});
notAllowedChanges.forEach(changeType -> {
Mockito.doReturn(Lists.newArrayList(new SchemaChange(changeType, "#/"))).when(schemaDiff).collectChanges(any(), any());
try {
service.evolve(oldEventType, newEventType);
fail();
} catch (final InvalidEventTypeException e) {
}
});
}
use of org.zalando.nakadi.exceptions.InvalidEventTypeException in project nakadi by zalando.
the class SchemaEvolutionService method checkEvolutionIncompatibilities.
private void checkEvolutionIncompatibilities(final EventType from, final EventTypeBase to) throws InvalidEventTypeException {
final List<SchemaEvolutionIncompatibility> incompatibilities = schemaEvolutionConstraints.stream().map(c -> c.validate(from, to)).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
if (incompatibilities.isEmpty()) {
return;
}
// There is a special case of incompatibility - change of category from NONE to BUSINESS, with adding metadata.
// Let's check that it is the case.
// This solution is not scalable, but without huge refactoring it is the simplest one.
final boolean categoryChanged = incompatibilities.stream().anyMatch(v -> v instanceof SchemaEvolutionIncompatibility.CategoryIncompatibility);
if (categoryChanged) {
final boolean metadataChanged = incompatibilities.stream().anyMatch(v -> v instanceof SchemaEvolutionIncompatibility.MetadataIncompatibility);
final int expectedIncompatibilities = 1 + (metadataChanged ? 1 : 0);
if (incompatibilities.size() == expectedIncompatibilities) {
// Now let's check, that it is really change from NONE to BUSINESS and some other conditions.
if (from.getCategory() == EventCategory.UNDEFINED && to.getCategory() == EventCategory.BUSINESS) {
if (to.getEnrichmentStrategies().contains(EnrichmentStrategyDescriptor.METADATA_ENRICHMENT) && to.getCompatibilityMode() != CompatibilityMode.COMPATIBLE) {
// Finally, we are allowing this step.
return;
}
}
}
throw new InvalidEventTypeException("Category change is allowed only from 'undefined' to 'business'. " + "'enrichment_strategies' should be properly set as well");
}
throw new InvalidEventTypeException(incompatibilities.stream().map(SchemaEvolutionIncompatibility::getReason).collect(Collectors.joining("; ")));
}
use of org.zalando.nakadi.exceptions.InvalidEventTypeException in project nakadi by zalando.
the class EventTypeService method validateSchema.
private void validateSchema(final EventTypeBase eventType) throws InvalidEventTypeException {
try {
final String eventTypeSchema = eventType.getSchema().getSchema();
JsonUtils.checkEventTypeSchemaValid(eventTypeSchema);
final JSONObject schemaAsJson = new JSONObject(eventTypeSchema);
final Schema schema = SchemaLoader.load(schemaAsJson);
if (eventType.getCategory() == EventCategory.BUSINESS && schema.definesProperty("#/metadata")) {
throw new InvalidEventTypeException("\"metadata\" property is reserved");
}
if (featureToggleService.isFeatureEnabled(CHECK_PARTITIONS_KEYS)) {
validatePartitionKeys(schema, eventType);
}
if (eventType.getCompatibilityMode() == CompatibilityMode.COMPATIBLE) {
validateJsonSchemaConstraints(schemaAsJson);
}
} catch (final JSONException e) {
throw new InvalidEventTypeException("schema must be a valid json");
} catch (final SchemaException e) {
throw new InvalidEventTypeException("schema must be a valid json-schema");
}
}
Aggregations