Repository: atlas Updated Branches: refs/heads/branch-1.0 32699ab53 -> 32a87a314
ATLAS-2730: added validation of TimeBoundry values in classifications Signed-off-by: Madhan Neethiraj <mad...@apache.org> (cherry picked from commit e73a80998ee39aab54eee637aee7ccb99e4156c1) Project: http://git-wip-us.apache.org/repos/asf/atlas/repo Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/047f31be Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/047f31be Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/047f31be Branch: refs/heads/branch-1.0 Commit: 047f31beb4a40c8b784c64a2203a1348be91a440 Parents: 32699ab Author: nixonrodrigues <ni...@apache.org> Authored: Fri Jun 1 12:46:47 2018 +0530 Committer: Madhan Neethiraj <mad...@apache.org> Committed: Tue Jun 5 07:52:37 2018 -0700 ---------------------------------------------------------------------- intg/pom.xml | 6 ++ .../java/org/apache/atlas/AtlasErrorCode.java | 3 + .../atlas/type/AtlasClassificationType.java | 87 ++++++++++++++++++++ .../atlas/type/TestAtlasClassificationType.java | 32 ++++++- pom.xml | 1 + .../store/graph/v2/AtlasEntityStoreV2.java | 5 ++ 6 files changed, 131 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/atlas/blob/047f31be/intg/pom.xml ---------------------------------------------------------------------- diff --git a/intg/pom.xml b/intg/pom.xml index 03e4325..089dbfb 100644 --- a/intg/pom.xml +++ b/intg/pom.xml @@ -47,6 +47,12 @@ </dependency> <dependency> + <groupId>commons-validator</groupId> + <artifactId>commons-validator</artifactId> + <version>${commons-validator.version}</version> + </dependency> + + <dependency> <groupId>com.fasterxml.jackson.jaxrs</groupId> <artifactId>jackson-jaxrs-base</artifactId> <version>${jackson.version}</version> http://git-wip-us.apache.org/repos/asf/atlas/blob/047f31be/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java index 06b4345..f0585eb 100644 --- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java +++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java @@ -148,6 +148,9 @@ public enum AtlasErrorCode { MISSING_CATEGORY_DISPLAY_NAME(400, "ATLAS-400-00-082", "Category name is empty/null"), INVALID_DISPLAY_NAME(400, "ATLAS-400-00-083", "name cannot contain following special chars ('@', '.')"), TERM_HAS_ENTITY_ASSOCIATION(400, "ATLAS-400-00-086", "Term (guid={0}) can't be deleted as it has been assigned to {1} entities."), + INVALID_TIMEBOUNDRY_START_TIME(400, "ATLAS-400-00-87B", "Invalid startTime {0}"), + INVALID_TIMEBOUNDRY_END_TIME(400, "ATLAS-400-00-87C", "Invalid endTime {0}"), + INVALID_TIMEBOUNDRY_DATERANGE(400, "ATLAS-400-00-87D", "Invalid dateRange: startTime {0} must be before endTime {1}"), UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to perform {1}"), http://git-wip-us.apache.org/repos/asf/atlas/blob/047f31be/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java b/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java index abacd78..1adb362 100644 --- a/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java +++ b/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java @@ -20,11 +20,13 @@ package org.apache.atlas.type; import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.exception.AtlasBaseException; +import org.apache.atlas.model.TimeBoundary; import org.apache.atlas.model.instance.AtlasClassification; import org.apache.atlas.model.typedef.AtlasClassificationDef; import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; +import org.apache.commons.validator.routines.DateValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -302,6 +304,10 @@ public class AtlasClassificationType extends AtlasStructType { } } + if (!validateTimeBoundaries(obj, null)) { + return false; + } + return super.isValidValue(obj); } @@ -328,6 +334,10 @@ public class AtlasClassificationType extends AtlasStructType { } } + if (!validateTimeBoundaries(obj, null)) { + return false; + } + return super.isValidValueForUpdate(obj); } @@ -381,6 +391,8 @@ public class AtlasClassificationType extends AtlasStructType { ret = superType.validateValue(obj, objName, messages) && ret; } + ret = validateTimeBoundaries(obj, messages) && ret; + ret = super.validateValue(obj, objName, messages) && ret; } @@ -396,6 +408,8 @@ public class AtlasClassificationType extends AtlasStructType { ret = superType.validateValueForUpdate(obj, objName, messages) && ret; } + ret = validateTimeBoundaries(obj, messages) && ret; + ret = super.validateValueForUpdate(obj, objName, messages) && ret; } @@ -516,4 +530,77 @@ public class AtlasClassificationType extends AtlasStructType { } } } + + private boolean validateTimeBoundaries(Object classificationObj, List<String> messages) { + boolean ret = true; + AtlasClassification classification = null; + + if (classificationObj instanceof AtlasClassification) { + classification = (AtlasClassification) classificationObj; + } else if (classificationObj instanceof Map) { + classification = new AtlasClassification((Map) classificationObj); + } + + if (classification != null && classification.getValidityPeriods() != null) { + for (TimeBoundary timeBoundary : classification.getValidityPeriods()) { + if (timeBoundary != null) { + ret = validateTimeBoundry(timeBoundary, messages) && ret; + } + } + } + + return ret; + } + + private boolean validateTimeBoundry(TimeBoundary timeBoundary, List<String> messages) { + boolean ret = true; + DateValidator dateValidator = DateValidator.getInstance(); + Date startDate = null; + Date endDate = null; + final TimeZone timezone; + + if (StringUtils.isNotEmpty(timeBoundary.getTimeZone())) { + timezone = TimeZone.getTimeZone(timeBoundary.getTimeZone()); + } else { + timezone = java.util.TimeZone.getDefault(); + } + + if (StringUtils.isNotEmpty(timeBoundary.getStartTime())) { + startDate = dateValidator.validate(timeBoundary.getStartTime(), TimeBoundary.TIME_FORMAT, timezone); + + if (startDate == null) { + addValidationMessageIfNotPresent(new AtlasBaseException(AtlasErrorCode.INVALID_TIMEBOUNDRY_START_TIME, timeBoundary.getStartTime()), messages); + + ret = false; + } + } + + if (StringUtils.isNotEmpty(timeBoundary.getEndTime())) { + endDate = dateValidator.validate(timeBoundary.getEndTime(), TimeBoundary.TIME_FORMAT, timezone); + + if (endDate == null) { + addValidationMessageIfNotPresent(new AtlasBaseException(AtlasErrorCode.INVALID_TIMEBOUNDRY_END_TIME, timeBoundary.getEndTime()), messages); + + ret = false; + } + } + + if (startDate != null && endDate != null) { + if (endDate.before(startDate)) { + addValidationMessageIfNotPresent(new AtlasBaseException(AtlasErrorCode.INVALID_TIMEBOUNDRY_DATERANGE, timeBoundary.getStartTime(), timeBoundary.getEndTime()), messages); + + ret = false; + } + } + + return ret; + } + + private void addValidationMessageIfNotPresent(AtlasBaseException excp, List<String> messages) { + String msg = excp.getMessage(); + + if (messages != null && !messages.contains(msg)) { + messages.add(msg); + } + } } http://git-wip-us.apache.org/repos/asf/atlas/blob/047f31be/intg/src/test/java/org/apache/atlas/type/TestAtlasClassificationType.java ---------------------------------------------------------------------- diff --git a/intg/src/test/java/org/apache/atlas/type/TestAtlasClassificationType.java b/intg/src/test/java/org/apache/atlas/type/TestAtlasClassificationType.java index 0badfcf..1ade5f7 100644 --- a/intg/src/test/java/org/apache/atlas/type/TestAtlasClassificationType.java +++ b/intg/src/test/java/org/apache/atlas/type/TestAtlasClassificationType.java @@ -21,6 +21,7 @@ import java.util.*; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.ModelTestUtil; +import org.apache.atlas.model.TimeBoundary; import org.apache.atlas.model.instance.AtlasClassification; import org.apache.atlas.model.typedef.AtlasBaseTypeDef; import org.apache.atlas.model.typedef.AtlasClassificationDef; @@ -39,9 +40,28 @@ public class TestAtlasClassificationType { { classificationType = getClassificationType(ModelTestUtil.getClassificationDefWithSuperTypes()); - AtlasClassification invalidValue1 = classificationType.createDefaultValue(); - AtlasClassification invalidValue2 = classificationType.createDefaultValue(); - Map<String, Object> invalidValue3 = classificationType.createDefaultValue().getAttributes(); + AtlasClassification invalidValue1 = classificationType.createDefaultValue(); + AtlasClassification invalidValue2 = classificationType.createDefaultValue(); + Map<String, Object> invalidValue3 = classificationType.createDefaultValue().getAttributes(); + AtlasClassification validValueTB1 = classificationType.createDefaultValue(); + AtlasClassification validValueTB2 = classificationType.createDefaultValue(); + AtlasClassification validValueTB3 = classificationType.createDefaultValue(); + AtlasClassification invalidValueTB1 = classificationType.createDefaultValue(); + AtlasClassification invalidValueTB2 = classificationType.createDefaultValue(); + AtlasClassification invalidValueTB3 = classificationType.createDefaultValue(); + TimeBoundary validTB1 = new TimeBoundary("2018/07/07 04:38:55"); // valid start-time + TimeBoundary validTB2 = new TimeBoundary(null, "2018/07/08 04:38:55"); // valid end-time + TimeBoundary validTB3 = new TimeBoundary("2018/07/07 04:38:55", "2018/07/08 04:38:55"); // valid start and end times + TimeBoundary invalidTB1 = new TimeBoundary("2018-07-07 04:38:55"); // invalid start-time + TimeBoundary invalidTB2 = new TimeBoundary(null, "2018-07-08 04:38:55"); // invalid end-time + TimeBoundary invalidTB3 = new TimeBoundary("2018/07/08 04:38:55", "2018/07/07 04:38:55"); // invalid time-ranger + + validValueTB1.addValityPeriod(validTB1); + validValueTB2.addValityPeriod(validTB2); + validValueTB3.addValityPeriod(validTB3); + invalidValueTB1.addValityPeriod(invalidTB1); + invalidValueTB2.addValityPeriod(invalidTB2); + invalidValueTB3.addValityPeriod(invalidTB3); // invalid value for int invalidValue1.setAttribute(ModelTestUtil.getDefaultAttributeName(AtlasBaseTypeDef.ATLAS_TYPE_INT), "xyz"); @@ -53,6 +73,9 @@ public class TestAtlasClassificationType { validValues.add(null); validValues.add(classificationType.createDefaultValue()); validValues.add(classificationType.createDefaultValue().getAttributes()); // Map<String, Object> + validValues.add(validValueTB1); + validValues.add(validValueTB2); + validValues.add(validValueTB3); invalidValues.add(invalidValue1); invalidValues.add(invalidValue2); invalidValues.add(invalidValue3); @@ -62,6 +85,9 @@ public class TestAtlasClassificationType { invalidValues.add(new HashSet()); // incorrect datatype invalidValues.add(new ArrayList()); // incorrect datatype invalidValues.add(new String[] {}); // incorrect datatype + invalidValues.add(invalidValueTB1); + invalidValues.add(invalidValueTB2); + invalidValues.add(invalidValueTB3); } @Test http://git-wip-us.apache.org/repos/asf/atlas/blob/047f31be/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 1741651..fbf2f9c 100644 --- a/pom.xml +++ b/pom.xml @@ -583,6 +583,7 @@ <commons-collections.version>3.2.2</commons-collections.version> <commons-logging.version>1.1.3</commons-logging.version> <commons-lang.version>2.6</commons-lang.version> + <commons-validator.version>1.4.0</commons-validator.version> <javax-inject.version>1</javax-inject.version> <jettison.version>1.3.7</jettison.version> <paranamer.version>2.7</paranamer.version> http://git-wip-us.apache.org/repos/asf/atlas/blob/047f31be/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java index 5e33cf5..40593be 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java @@ -403,6 +403,7 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore { } GraphTransactionInterceptor.lockObjectAndReleasePostCommit(guid); + for (AtlasClassification classification : classifications) { validateAndNormalize(classification); } @@ -436,6 +437,10 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore { GraphTransactionInterceptor.lockObjectAndReleasePostCommit(guid); + for (AtlasClassification classification : classifications) { + validateAndNormalize(classification); + } + entityGraphMapper.updateClassifications(new EntityMutationContext(), guid, classifications); }