All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.atlasmap.core.DefaultAtlasValidationService Maven / Gradle / Ivy

/**
 * Copyright (C) 2017 Red Hat, Inc.
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.atlasmap.core; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; import io.atlasmap.api.AtlasValidationService; import io.atlasmap.spi.AtlasValidator; import io.atlasmap.v2.AtlasMapping; import io.atlasmap.v2.BaseMapping; import io.atlasmap.v2.DataSource; import io.atlasmap.v2.Field; import io.atlasmap.v2.FieldGroup; import io.atlasmap.v2.LookupTable; import io.atlasmap.v2.LookupTables; import io.atlasmap.v2.Mapping; import io.atlasmap.v2.MappingType; import io.atlasmap.v2.Mappings; import io.atlasmap.v2.Validation; import io.atlasmap.v2.ValidationScope; import io.atlasmap.v2.ValidationStatus; import io.atlasmap.validators.CompositeValidator; import io.atlasmap.validators.LookupTableNameValidator; import io.atlasmap.validators.NonNullValidator; import io.atlasmap.validators.NotEmptyValidator; import io.atlasmap.validators.PositiveIntegerValidator; import io.atlasmap.validators.StringPatternValidator; public class DefaultAtlasValidationService implements AtlasValidationService { enum Validators { MAPPING_NAME (() -> { StringPatternValidator namePattern = new StringPatternValidator( ValidationScope.ALL, "Mapping name must not contain spaces nor special characters other than period (.) and underscore (_), but was '%s'", "[^A-Za-z0-9_.]"); NonNullValidator nameNotNull = new NonNullValidator( ValidationScope.ALL, "Mapping name must not be null nor empty"); return new CompositeValidator(namePattern, nameNotNull); }), DATASOURCE_TARGET_URI (() -> new NonNullValidator(ValidationScope.DATA_SOURCE, "DataSource target uri must not be null nor empty") ), DATASOURCE_SOURCE_URI (() -> new NonNullValidator(ValidationScope.DATA_SOURCE, "DataSource source uri must not be null nor empty") ), MAPPINGS_NOT_NULL (() -> new NonNullValidator(ValidationScope.MAPPING, "Field mappings must not be null") ), MAPPINGS_NOT_EMPTY (() -> new NotEmptyValidator(ValidationScope.MAPPING, "Field mappings should not be empty") ), COMBINE_INPUT_NOT_NULL (() -> new NonNullValidator(ValidationScope.MAPPING, "Source field should not be null") ), COMBINE_INPUT_FIELD_NOT_EMPTY (() -> new NotEmptyValidator(ValidationScope.MAPPING, "Source field should not be empty") ), COMBINE_OUTPUT_NOT_NULL (() -> new NonNullValidator(ValidationScope.MAPPING, "Target element must not be null") ), COMBINE_OUTPUT_FIELD_NOT_EMPTY (() -> new NotEmptyValidator(ValidationScope.MAPPING, "Target field must not be empty") ), COMBINE_INPUT_FIELD_NOT_NULL (() -> new NonNullValidator( ValidationScope.MAPPING, "Source fields should not be null") ), COMBINE_INPUT_FIELD_FIELD_ACTION_INDEX_POSITIVE (() -> new PositiveIntegerValidator( ValidationScope.MAPPING, "MapAction index must exists and be greater than or equal to zero (0), but was '%s'") ), MAP_INPUT_NOT_NULL (() -> new NonNullValidator(ValidationScope.MAPPING, "Source field must not be null") ), MAP_INPUT_FIELD_NOT_EMPTY (() -> new NotEmptyValidator(ValidationScope.MAPPING, "Source field must not be empty") ), MAP_OUTPUT_NOT_NULL (() -> new NonNullValidator(ValidationScope.MAPPING, "Target field should not be null") ), MAP_OUTPUT_FIELD_NOT_EMPTY (() -> new NotEmptyValidator(ValidationScope.MAPPING, "Target field should not be empty") ), SEPARATE_INPUT_NOT_NULL (() -> new NonNullValidator(ValidationScope.MAPPING, "Source field must not be null") ), SEPARATE_INPUT_FIELD_NOT_NULL (() -> new NonNullValidator(ValidationScope.MAPPING, "Source field must not be null") ), SEPARATE_INPUT_FIELD_NOT_EMPTY (() -> new NotEmptyValidator(ValidationScope.MAPPING, "Source field must not be empty") ), SEPARATE_OUTPUT_NOT_NULL (() -> new NonNullValidator(ValidationScope.MAPPING, "Target field should not be null") ), SEPARATE_OUTPUT_FIELD_NOT_NULL (() -> new NonNullValidator(ValidationScope.MAPPING, "Target fields should not be null") ), SEPARATE_OUTPUT_FIELD_NOT_EMPTY (() -> new NotEmptyValidator(ValidationScope.MAPPING, "Target fields should not be empty") ), SEPARATE_OUTPUT_FIELD_FIELD_ACTION_NOT_EMPTY (() -> new NotEmptyValidator(ValidationScope.MAPPING, "Field actions cannot be null or empty") ), SEPARATE_OUTPUT_FIELD_FIELD_ACTION_INDEX_POSITIVE (() -> new PositiveIntegerValidator(ValidationScope.MAPPING, "MapAction index must exists and be greater than or equal to zero (0), but was '%s'") ), LOOKUPTABLE_NAME_CHECK_FOR_DUPLICATE (() -> new LookupTableNameValidator("LookupTables contain duplicated LookupTable names '%s'.") ); private final AtlasValidator validator; private Validators(Supplier s) { validator = s.get(); } public AtlasValidator get() { return validator; } } @Override public List validateMapping(AtlasMapping mapping) { List validations = new ArrayList<>(); Validators.MAPPING_NAME.get().validate(mapping.getName(), validations, null); List dataSources = mapping.getDataSource(); for (DataSource ds : dataSources) { switch (ds.getDataSourceType()) { case SOURCE: Validators.DATASOURCE_SOURCE_URI.get().validate(ds.getUri(), validations, ds.getId()); break; case TARGET: Validators.DATASOURCE_TARGET_URI.get().validate(ds.getUri(), validations, ds.getId()); break; default: throw new IllegalArgumentException(String.format("Unknown DataSource type '%s'", ds.getDataSourceType())); } } validateFieldMappings(mapping.getMappings(), mapping.getLookupTables(), validations); return validations; } private void validateFieldMappings(Mappings mappings, LookupTables lookupTables, List validations) { Validators.MAPPINGS_NOT_NULL.get().validate(mappings, validations, null); if (mappings != null) { Validators.MAPPINGS_NOT_EMPTY.get().validate(mappings.getMapping(), validations, null, ValidationStatus.WARN); List fieldMappings = mappings.getMapping(); if (fieldMappings != null && !fieldMappings.isEmpty()) { List mapFieldMappings = fieldMappings.stream() .filter(p -> p.getMappingType() == MappingType.MAP).map(p -> (Mapping) p) .collect(Collectors.toList()); List combineFieldMappings = fieldMappings.stream() .filter(p -> p.getMappingType() == MappingType.COMBINE).map(p -> (Mapping) p) .collect(Collectors.toList()); List separateFieldMappings = fieldMappings.stream() .filter(p -> p.getMappingType() == MappingType.SEPARATE).map(p -> (Mapping) p) .collect(Collectors.toList()); List lookupFieldMappings = fieldMappings.stream() .filter(p -> p.getMappingType() == MappingType.LOOKUP).map(p -> (Mapping) p) .collect(Collectors.toList()); Set usedIds = new HashSet<>(); validateMapMapping(mapFieldMappings, validations, usedIds); validateCombineMapping(combineFieldMappings, validations, usedIds); validateSeparateMapping(separateFieldMappings, validations, usedIds); validateLookupTables(lookupFieldMappings, lookupTables, validations, usedIds); } } } private void validateLookupTables(List lookupFieldMappings, LookupTables lookupTables, List validations, Set usedIds) { if (lookupTables != null && lookupTables.getLookupTable() != null && !lookupTables.getLookupTable().isEmpty()) { // check for duplicate names Validators.LOOKUPTABLE_NAME_CHECK_FOR_DUPLICATE.get().validate(lookupTables, validations, null); if (lookupFieldMappings.isEmpty()) { Validation validation = new Validation(); validation.setScope(ValidationScope.LOOKUP_TABLE); validation.setMessage("LookupTables are defined but no LookupFields are utilized."); validation.setStatus(ValidationStatus.WARN); validations.add(validation); } else { validateLookupFieldMapping(lookupFieldMappings, lookupTables, validations, usedIds); } } } // mapping field validations private void validateLookupFieldMapping(List fieldMappings, LookupTables lookupTables, List validations, Set usedIds) { Set lookupFieldMappingTableNameRefs = fieldMappings.stream().map(Mapping::getLookupTableName) .collect(Collectors.toSet()); Set tableNames = lookupTables.getLookupTable().stream().map(LookupTable::getName) .collect(Collectors.toSet()); if (!lookupFieldMappingTableNameRefs.isEmpty() && !tableNames.isEmpty()) { Set disjoint = Stream.concat(lookupFieldMappingTableNameRefs.stream(), tableNames.stream()) .collect(Collectors.toMap(Function.identity(), t -> true, (a, b) -> null)).keySet(); if (!disjoint.isEmpty()) { boolean isInFieldList = !lookupFieldMappingTableNameRefs.stream().filter(disjoint::contains) .collect(Collectors.toList()).isEmpty(); boolean isInTableNameList = !tableNames.stream().filter(disjoint::contains).collect(Collectors.toList()) .isEmpty(); // which list has the disjoin.... if its the lookup fields then ERROR if (isInFieldList) { Validation validation = new Validation(); validation.setScope(ValidationScope.LOOKUP_TABLE); validation.setMessage( "One ore more LookupFieldMapping references a non existent LookupTable name in the mapping: " + disjoint.toString()); validation.setStatus(ValidationStatus.ERROR); validations.add(validation); } // check that if a name exists in table names that at least one field mapping // uses it, else WARN if (isInTableNameList) { Validation validation = new Validation(); validation.setScope(ValidationScope.LOOKUP_TABLE); validation.setMessage("A LookupTable is defined but not used by any LookupField: " + disjoint.toString()); validation.setStatus(ValidationStatus.WARN); validations.add(validation); } } } for (Mapping fieldMapping : fieldMappings) { String mappingId = fieldMapping.getId(); validateMappingId(mappingId, usedIds, validations); if (fieldMapping.getInputField() != null) { Validators.MAP_INPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getInputField(), validations, mappingId); } Validators.MAP_OUTPUT_NOT_NULL.get().validate(fieldMapping.getOutputField(), validations, mappingId, ValidationStatus.WARN); if (fieldMapping.getOutputField() != null) { Validators.MAP_OUTPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getOutputField(), validations, mappingId, ValidationStatus.WARN); } } } private void validateMapMapping(List fieldMappings, List validations, Set usedIds) { for (Mapping fieldMapping : fieldMappings) { String mappingId = fieldMapping.getId(); FieldGroup sourceFieldGroup = fieldMapping.getInputFieldGroup(); List sourceFields = sourceFieldGroup != null ? sourceFieldGroup.getField() : fieldMapping.getInputField(); validateMappingId(mappingId, usedIds, validations); Validators.MAP_INPUT_NOT_NULL.get().validate(sourceFields, validations, mappingId); if (fieldMapping.getInputField() != null) { Validators.MAP_INPUT_FIELD_NOT_EMPTY.get().validate(sourceFields, validations, mappingId); } Validators.MAP_OUTPUT_NOT_NULL.get().validate(fieldMapping.getOutputField(), validations, mappingId, ValidationStatus.WARN); if (fieldMapping.getOutputField() != null) { Validators.MAP_OUTPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getOutputField(), validations, mappingId, ValidationStatus.WARN); } } } private void validateSeparateMapping(List fieldMappings, List validations, Set usedIds) { for (Mapping fieldMapping : fieldMappings) { String mappingId = fieldMapping.getId(); validateMappingId(mappingId, usedIds, validations); Validators.SEPARATE_INPUT_NOT_NULL.get().validate(fieldMapping.getInputField(), validations, mappingId); if (fieldMapping.getInputField() != null) { Validators.SEPARATE_INPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getInputField(), validations, mappingId); // source must be a String type } Validators.SEPARATE_OUTPUT_NOT_NULL.get().validate(fieldMapping.getOutputField(), validations, mappingId, ValidationStatus.WARN); Validators.SEPARATE_OUTPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getOutputField(), validations, mappingId, ValidationStatus.WARN); if (fieldMapping.getOutputField() != null) { for (Field field : fieldMapping.getOutputField()) { Validators.SEPARATE_OUTPUT_FIELD_NOT_NULL.get().validate(field, validations, mappingId); if (field.getIndex() == null || field.getIndex() < 0) { Validators.SEPARATE_OUTPUT_FIELD_FIELD_ACTION_INDEX_POSITIVE.get().validate(field.getIndex(), validations, mappingId); } } } } } private void validateCombineMapping(List fieldMappings, List validations, Set usedIds) { for (Mapping fieldMapping : fieldMappings) { String mappingId = fieldMapping.getId(); validateMappingId(mappingId, usedIds, validations); Validators.COMBINE_OUTPUT_NOT_NULL.get().validate(fieldMapping.getOutputField(), validations, mappingId); if (fieldMapping.getOutputField() != null) { Validators.COMBINE_OUTPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getOutputField(), validations, mappingId); // source must be a String type } Validators.COMBINE_INPUT_NOT_NULL.get().validate(fieldMapping.getInputField(), validations, mappingId, ValidationStatus.WARN); Validators.COMBINE_INPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getInputField(), validations, mappingId, ValidationStatus.WARN); if (fieldMapping.getInputField() != null) { for (Field field : fieldMapping.getInputField()) { Validators.COMBINE_INPUT_FIELD_NOT_NULL.get().validate(field, validations, mappingId); if (field.getIndex() == null || field.getIndex() < 0) { Validators.COMBINE_INPUT_FIELD_FIELD_ACTION_INDEX_POSITIVE.get().validate(field.getIndex(), validations, mappingId); } } } } } private void validateMappingId(String id, Set usedIds, List validations) { if (id == null) { return; } if (usedIds.contains(id)) { Validation validation = new Validation(); validation.setScope(ValidationScope.MAPPING); validation.setMessage(String.format("Duplicated mapping ID '%s' is found", id)); validation.setStatus(ValidationStatus.WARN); validations.add(validation); } else { usedIds.add(id); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy