Search in sources :

Example 6 with InvalidEventTypeException

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) {
        }
    });
}
Also used : EventType(org.zalando.nakadi.domain.EventType) InvalidEventTypeException(org.zalando.nakadi.exceptions.InvalidEventTypeException) EventType(org.zalando.nakadi.domain.EventType) Version(org.zalando.nakadi.domain.Version) SchemaChange(org.zalando.nakadi.domain.SchemaChange) EventTypeTestBuilder(org.zalando.nakadi.utils.EventTypeTestBuilder) Test(org.junit.Test)

Example 7 with InvalidEventTypeException

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("; ")));
}
Also used : EventCategory(org.zalando.nakadi.domain.EventCategory) DateTimeZone(org.joda.time.DateTimeZone) PATCH(org.zalando.nakadi.domain.Version.Level.PATCH) SchemaEvolutionIncompatibility(org.zalando.nakadi.validation.schema.SchemaEvolutionIncompatibility) EnrichmentStrategyDescriptor(org.zalando.nakadi.domain.EnrichmentStrategyDescriptor) ForbiddenAttributeIncompatibility(org.zalando.nakadi.validation.schema.ForbiddenAttributeIncompatibility) ArrayList(java.util.ArrayList) Lists(com.google.common.collect.Lists) JSONObject(org.json.JSONObject) SchemaDiff(org.zalando.nakadi.validation.schema.diff.SchemaDiff) Map(java.util.Map) SchemaLoader(org.everit.json.schema.loader.SchemaLoader) ADDITIONAL_ITEMS_CHANGED(org.zalando.nakadi.domain.SchemaChange.Type.ADDITIONAL_ITEMS_CHANGED) ADDITIONAL_PROPERTIES_CHANGED(org.zalando.nakadi.domain.SchemaChange.Type.ADDITIONAL_PROPERTIES_CHANGED) EventType(org.zalando.nakadi.domain.EventType) ValidationException(org.everit.json.schema.ValidationException) REQUIRED_ARRAY_EXTENDED(org.zalando.nakadi.domain.SchemaChange.Type.REQUIRED_ARRAY_EXTENDED) DateTime(org.joda.time.DateTime) MAJOR(org.zalando.nakadi.domain.Version.Level.MAJOR) NO_CHANGES(org.zalando.nakadi.domain.Version.Level.NO_CHANGES) SchemaEvolutionConstraint(org.zalando.nakadi.validation.schema.SchemaEvolutionConstraint) Collectors(java.util.stream.Collectors) BinaryOperator(java.util.function.BinaryOperator) Version(org.zalando.nakadi.domain.Version) List(java.util.List) TITLE_CHANGED(org.zalando.nakadi.domain.SchemaChange.Type.TITLE_CHANGED) SchemaChange(org.zalando.nakadi.domain.SchemaChange) EventTypeBase(org.zalando.nakadi.domain.EventTypeBase) CompatibilityMode(org.zalando.nakadi.domain.CompatibilityMode) Schema(org.everit.json.schema.Schema) Optional(java.util.Optional) DESCRIPTION_CHANGED(org.zalando.nakadi.domain.SchemaChange.Type.DESCRIPTION_CHANGED) PROPERTIES_ADDED(org.zalando.nakadi.domain.SchemaChange.Type.PROPERTIES_ADDED) InvalidEventTypeException(org.zalando.nakadi.exceptions.InvalidEventTypeException) InvalidEventTypeException(org.zalando.nakadi.exceptions.InvalidEventTypeException) Optional(java.util.Optional) SchemaEvolutionIncompatibility(org.zalando.nakadi.validation.schema.SchemaEvolutionIncompatibility) SchemaEvolutionConstraint(org.zalando.nakadi.validation.schema.SchemaEvolutionConstraint)

Example 8 with InvalidEventTypeException

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");
    }
}
Also used : SchemaException(org.everit.json.schema.SchemaException) InvalidEventTypeException(org.zalando.nakadi.exceptions.InvalidEventTypeException) JSONObject(org.json.JSONObject) Schema(org.everit.json.schema.Schema) JSONException(org.json.JSONException)

Aggregations

InvalidEventTypeException (org.zalando.nakadi.exceptions.InvalidEventTypeException)8 EventType (org.zalando.nakadi.domain.EventType)7 Test (org.junit.Test)6 TestUtils.buildDefaultEventType (org.zalando.nakadi.utils.TestUtils.buildDefaultEventType)5 TestUtils.invalidProblem (org.zalando.nakadi.utils.TestUtils.invalidProblem)5 Problem (org.zalando.problem.Problem)5 ThrowableProblem (org.zalando.problem.ThrowableProblem)5 Schema (org.everit.json.schema.Schema)2 Matchers.containsString (org.hamcrest.Matchers.containsString)2 JSONObject (org.json.JSONObject)2 Matchers.anyString (org.mockito.Matchers.anyString)2 SchemaChange (org.zalando.nakadi.domain.SchemaChange)2 Version (org.zalando.nakadi.domain.Version)2 Lists (com.google.common.collect.Lists)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Map (java.util.Map)1 Optional (java.util.Optional)1 BinaryOperator (java.util.function.BinaryOperator)1 Collectors (java.util.stream.Collectors)1