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);
     }
 

Reply via email to