SchemaElementDefinitionValidator { public ValidationResult validate(final SchemaElementDefinition elementDef) { final ValidationResult result = new ValidationResult(); final ElementFilter validator = elementDef.getValidator(); final ElementAggregator aggregator = elementDef.getFullAggregator(); result.add(validateAggregator(aggregator, elementDef)); result.add(validateComponentTypes(elementDef)); result.add(validateFunctionArgumentTypes(validator, elementDef)); result.add(validateFunctionArgumentTypes(aggregator, elementDef)); result.add(validateRequiredParameters(elementDef)); result.add(validatePropertyNames(elementDef)); return result; }  ValidationResult validate(final SchemaElementDefinition elementDef);  }
@Test public void shouldValidateAndReturnTrueWhenAggregationIsDisabled() { final SchemaElementDefinition elementDef = mock(SchemaElementDefinition.class); final SchemaElementDefinitionValidator validator = new SchemaElementDefinitionValidator(); final Map<String, String> properties = new HashMap<>(); properties.put(TestPropertyNames.PROP_1, "int"); properties.put(TestPropertyNames.PROP_2, "string"); final BinaryOperator<Integer> function1 = mock(BinaryOperator.class); final ElementAggregator aggregator = new ElementAggregator.Builder() .select(TestPropertyNames.PROP_1) .execute(function1) .build(); given(elementDef.getIdentifiers()).willReturn(new HashSet<>()); given(elementDef.getProperties()).willReturn(properties.keySet()); given(elementDef.getPropertyMap()).willReturn(properties); given(elementDef.getValidator()).willReturn(mock(ElementFilter.class)); given(elementDef.getFullAggregator()).willReturn(aggregator); given(elementDef.getPropertyClass(TestPropertyNames.PROP_1)).willReturn((Class) Integer.class); given(elementDef.getPropertyClass(TestPropertyNames.PROP_2)).willReturn((Class) String.class); given(elementDef.isAggregate()).willReturn(false); final ValidationResult result = validator.validate(elementDef); assertTrue(result.isValid()); }
@Test public void shouldValidateAndReturnTrueWhenAggregatorIsValid() { final SchemaElementDefinitionValidator validator = new SchemaElementDefinitionValidator(); final BinaryOperator<Integer> function1 = mock(BinaryOperator.class); final BinaryOperator function2 = mock(BinaryOperator.class); final Schema schema = new Schema.Builder() .entity(TestGroups.ENTITY, new SchemaEntityDefinition.Builder() .vertex("int1") .property(TestPropertyNames.PROP_1, "int1") .property(TestPropertyNames.PROP_2, "int2") .build()) .type("int1", new TypeDefinition.Builder() .clazz(Integer.class) .aggregateFunction(function1) .build()) .type("int2", new TypeDefinition.Builder() .clazz(Integer.class) .aggregateFunction(function2) .build()) .build(); final ValidationResult result = validator.validate(schema.getEntity(TestGroups.ENTITY)); assertTrue(result.isValid()); }
@Test public void shouldValidateAndReturnFalseWhenAggregatorIsInvalid() { final SchemaElementDefinition elementDef = mock(SchemaElementDefinition.class); final SchemaElementDefinitionValidator validator = new SchemaElementDefinitionValidator(); final Map<String, String> properties = new HashMap<>(); properties.put(TestPropertyNames.PROP_1, "int"); properties.put(TestPropertyNames.PROP_2, "string"); final BinaryOperator<Integer> function1 = mock(BinaryOperator.class); final ElementAggregator aggregator = new ElementAggregator.Builder() .select(TestPropertyNames.PROP_1) .execute(function1) .build(); given(elementDef.getIdentifiers()).willReturn(new HashSet<>()); given(elementDef.getProperties()).willReturn(properties.keySet()); given(elementDef.getPropertyMap()).willReturn(properties); given(elementDef.getValidator()).willReturn(mock(ElementFilter.class)); given(elementDef.getFullAggregator()).willReturn(aggregator); given(elementDef.getPropertyClass(TestPropertyNames.PROP_1)).willReturn((Class) Integer.class); given(elementDef.getPropertyClass(TestPropertyNames.PROP_2)).willReturn((Class) String.class); given(elementDef.isAggregate()).willReturn(true); final ValidationResult result = validator.validate(elementDef); assertFalse(result.isValid()); assertTrue(result.getErrorString().contains("No aggregator found for properties")); verify(elementDef, Mockito.atLeastOnce()).getPropertyClass(TestPropertyNames.PROP_1); verify(elementDef, Mockito.atLeastOnce()).getPropertyClass(TestPropertyNames.PROP_2); }
@Test public void shouldValidateAndReturnFalseWhenNoAggregatorByGroupBysSet() { Set<String> groupBys = new HashSet<>(); groupBys.add("int"); final SchemaElementDefinition elementDef = mock(SchemaElementDefinition.class); final SchemaElementDefinitionValidator validator = new SchemaElementDefinitionValidator(); final Map<String, String> properties = new HashMap<>(); properties.put(TestPropertyNames.PROP_1, "int"); properties.put(TestPropertyNames.PROP_2, "string"); given(elementDef.getGroupBy()).willReturn(groupBys); given(elementDef.getProperties()).willReturn(properties.keySet()); given(elementDef.getPropertyMap()).willReturn(properties); given(elementDef.getValidator()).willReturn(mock(ElementFilter.class)); given(elementDef.getPropertyClass(TestPropertyNames.PROP_1)).willReturn((Class) Integer.class); given(elementDef.getPropertyClass(TestPropertyNames.PROP_2)).willReturn((Class) String.class); given(elementDef.isAggregate()).willReturn(false); final ValidationResult result = validator.validate(elementDef); assertFalse(result.isValid()); assertEquals("Validation errors: \nGroups with aggregation disabled should not have groupBy properties.", result.getErrorString()); verify(elementDef, Mockito.atLeastOnce()).getPropertyClass(TestPropertyNames.PROP_1); verify(elementDef, Mockito.atLeastOnce()).getPropertyClass(TestPropertyNames.PROP_2); }
@Test public void shouldValidateAndReturnTrueWhenNoPropertiesSoAggregatorIsValid() { final SchemaElementDefinition elementDef = mock(SchemaElementDefinition.class); final SchemaElementDefinitionValidator validator = new SchemaElementDefinitionValidator(); given(elementDef.getIdentifiers()).willReturn(new HashSet<>()); given(elementDef.getPropertyMap()).willReturn(Collections.emptyMap()); given(elementDef.getValidator()).willReturn(mock(ElementFilter.class)); given(elementDef.getFullAggregator()).willReturn(null); given(elementDef.isAggregate()).willReturn(true); final ValidationResult result = validator.validate(elementDef); assertTrue(result.isValid()); }
@Test public void shouldValidateAndReturnFalseWhenAggregatorProvidedWithNoProperties() { final SchemaElementDefinitionValidator validator = new SchemaElementDefinitionValidator(); final BinaryOperator<Integer> function1 = mock(BinaryOperator.class); final Schema schema = new Schema.Builder() .entity(TestGroups.ENTITY, new SchemaEntityDefinition.Builder() .vertex("id") .aggregator(new ElementAggregator.Builder() .select(IdentifierType.VERTEX.name()) .execute(function1) .build()) .build()) .type("id", new TypeDefinition.Builder() .clazz(String.class) .build()) .build(); final ValidationResult result = validator.validate(schema.getElement(TestGroups.ENTITY)); assertFalse(result.isValid()); assertEquals(com.google.common.collect.Sets.newHashSet("Groups with no properties should not have any aggregators"), result.getErrors()); }
@Test public void shouldValidateAndReturnFalseWhenAggregatorHasIdentifierInSelection() { final SchemaElementDefinitionValidator validator = new SchemaElementDefinitionValidator(); final BinaryOperator<Integer> function1 = mock(BinaryOperator.class); final Schema schema = new Schema.Builder() .entity(TestGroups.ENTITY, new SchemaEntityDefinition.Builder() .vertex("id") .property(TestPropertyNames.STRING, "string") .aggregator(new ElementAggregator.Builder() .select(IdentifierType.VERTEX.name()) .execute(function1) .build()) .build()) .type("id", new TypeDefinition.Builder() .clazz(String.class) .build()) .type("string", new TypeDefinition.Builder() .clazz(String.class) .aggregateFunction(function1) .build()) .build(); final ValidationResult result = validator.validate(schema.getElement(TestGroups.ENTITY)); assertFalse(result.isValid()); assertEquals(com.google.common.collect.Sets.newHashSet("Identifiers cannot be selected for aggregation: " + IdentifierType.VERTEX.name()), result.getErrors()); }
@Test public void shouldValidateAndReturnFalseWhenVisibilityIsAggregatedWithOtherProperty() { final SchemaElementDefinitionValidator validator = new SchemaElementDefinitionValidator(); final BinaryOperator<Integer> function1 = mock(BinaryOperator.class); final Schema schema = new Schema.Builder() .entity(TestGroups.ENTITY, new SchemaEntityDefinition.Builder() .vertex("id") .property(TestPropertyNames.STRING, "string") .property(TestPropertyNames.VISIBILITY, "string") .aggregator(new ElementAggregator.Builder() .select(TestPropertyNames.STRING, TestPropertyNames.VISIBILITY) .execute(function1) .build()) .build()) .visibilityProperty(TestPropertyNames.VISIBILITY) .type("id", new TypeDefinition.Builder() .clazz(String.class) .build()) .type("string", new TypeDefinition.Builder() .clazz(String.class) .aggregateFunction(function1) .build()) .build(); final ValidationResult result = validator.validate(schema.getElement(TestGroups.ENTITY)); assertFalse(result.isValid()); assertEquals(com.google.common.collect.Sets.newHashSet( "The visibility property must be aggregated by itself. It is currently aggregated in the tuple: [stringProperty, visibility], by aggregate function: " + function1.getClass().getName() ), result.getErrors()); }
@Test public void shouldValidateAndReturnTrueWhenTimestampIsAggregatedWithANonGroupByProperty() { final SchemaElementDefinitionValidator validator = new SchemaElementDefinitionValidator(); final BinaryOperator<Integer> function1 = mock(BinaryOperator.class); final Schema schema = new Schema.Builder() .entity(TestGroups.ENTITY, new SchemaEntityDefinition.Builder() .vertex("id") .property(TestPropertyNames.STRING, "string") .property(TestPropertyNames.TIMESTAMP, "string") .aggregator(new ElementAggregator.Builder() .select(TestPropertyNames.STRING, TestPropertyNames.TIMESTAMP) .execute(function1) .build()) .build()) .timestampProperty(TestPropertyNames.TIMESTAMP) .type("id", new TypeDefinition.Builder() .clazz(String.class) .build()) .type("string", new TypeDefinition.Builder() .clazz(String.class) .aggregateFunction(function1) .build()) .build(); final ValidationResult result = validator.validate(schema.getElement(TestGroups.ENTITY)); assertTrue(result.isValid()); }
@Test public void shouldValidateAndReturnFalseWhenTimestampIsAggregatedWithAGroupByProperty() { final SchemaElementDefinitionValidator validator = new SchemaElementDefinitionValidator(); final BinaryOperator<Integer> function1 = mock(BinaryOperator.class); final Schema schema = new Schema.Builder() .entity(TestGroups.ENTITY, new SchemaEntityDefinition.Builder() .vertex("id") .property(TestPropertyNames.STRING, "string") .property(TestPropertyNames.TIMESTAMP, "string") .groupBy(TestPropertyNames.STRING) .aggregator(new ElementAggregator.Builder() .select(TestPropertyNames.STRING, TestPropertyNames.TIMESTAMP) .execute(function1) .build()) .build()) .timestampProperty(TestPropertyNames.TIMESTAMP) .type("id", new TypeDefinition.Builder() .clazz(String.class) .build()) .type("string", new TypeDefinition.Builder() .clazz(String.class) .aggregateFunction(function1) .build()) .build(); final ValidationResult result = validator.validate(schema.getElement(TestGroups.ENTITY)); assertFalse(result.isValid()); assertEquals(com.google.common.collect.Sets.newHashSet( "groupBy properties and non-groupBy properties (including timestamp) must be not be aggregated using the same BinaryOperator. Selection tuple: [stringProperty, timestamp], is aggregated by: " + function1.getClass().getName() ), result.getErrors()); }
@Test public void shouldValidateAndReturnFalseWhenGroupByIsAggregatedWithNonGroupByProperty() { final SchemaElementDefinitionValidator validator = new SchemaElementDefinitionValidator(); final BinaryOperator<Integer> function1 = mock(BinaryOperator.class); final Schema schema = new Schema.Builder() .entity(TestGroups.ENTITY, new SchemaEntityDefinition.Builder() .vertex("id") .property(TestPropertyNames.PROP_1, "string") .property(TestPropertyNames.PROP_2, "string") .groupBy(TestPropertyNames.PROP_1) .aggregator(new ElementAggregator.Builder() .select(TestPropertyNames.PROP_1, TestPropertyNames.PROP_2) .execute(function1) .build()) .build()) .type("id", new TypeDefinition.Builder() .clazz(String.class) .build()) .type("string", new TypeDefinition.Builder() .clazz(String.class) .aggregateFunction(function1) .build()) .build(); final ValidationResult result = validator.validate(schema.getElement(TestGroups.ENTITY)); assertFalse(result.isValid()); assertEquals(com.google.common.collect.Sets.newHashSet( "groupBy properties and non-groupBy properties (including timestamp) must be not be aggregated using the same BinaryOperator. Selection tuple: [property1, property2], is aggregated by: " + function1.getClass().getName() ), result.getErrors()); }
@Test public void shouldValidateAndReturnFalseWhenAggregatorHasNoFunction() { final SchemaElementDefinitionValidator validator = new SchemaElementDefinitionValidator(); final BinaryOperator<Integer> function1 = mock(BinaryOperator.class); final Schema schema = new Schema.Builder() .entity(TestGroups.ENTITY, new SchemaEntityDefinition.Builder() .vertex("id") .property(TestPropertyNames.PROP_1, "string") .aggregator(new ElementAggregator.Builder() .select(TestPropertyNames.PROP_1) .execute(null) .build()) .build()) .type("id", new TypeDefinition.Builder() .clazz(String.class) .build()) .type("string", new TypeDefinition.Builder() .clazz(String.class) .build()) .build(); final ValidationResult result = validator.validate(schema.getElement(TestGroups.ENTITY)); assertFalse(result.isValid()); assertEquals(com.google.common.collect.Sets.newHashSet( "ElementAggregator contains a null function." ), result.getErrors()); }
@Test public void shouldValidateAndReturnFalseWhenAggregatorSelectionHasUnknownProperty() { final SchemaElementDefinitionValidator validator = new SchemaElementDefinitionValidator(); final BinaryOperator<Integer> function1 = mock(BinaryOperator.class); final Schema schema = new Schema.Builder() .entity(TestGroups.ENTITY, new SchemaEntityDefinition.Builder() .vertex("id") .property(TestPropertyNames.STRING, "string") .aggregator(new ElementAggregator.Builder() .select(TestPropertyNames.STRING, TestPropertyNames.PROP_1) .execute(function1) .build()) .build()) .type("id", new TypeDefinition.Builder() .clazz(String.class) .build()) .type("string", new TypeDefinition.Builder() .clazz(String.class) .aggregateFunction(function1) .build()) .build(); final ValidationResult result = validator.validate(schema.getElement(TestGroups.ENTITY)); assertFalse(result.isValid()); assertEquals(com.google.common.collect.Sets.newHashSet( "Unknown property used in an aggregator: " + TestPropertyNames.PROP_1 ), result.getErrors()); }