Commit e73a8099 by nixonrodrigues Committed by Madhan Neethiraj

ATLAS-2730: added validation of TimeBoundry values in classifications

parent 86af9e3b
...@@ -47,6 +47,12 @@ ...@@ -47,6 +47,12 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>${commons-validator.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId> <groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId> <artifactId>jackson-jaxrs-base</artifactId>
<version>${jackson.version}</version> <version>${jackson.version}</version>
......
...@@ -148,6 +148,9 @@ public enum AtlasErrorCode { ...@@ -148,6 +148,9 @@ public enum AtlasErrorCode {
MISSING_CATEGORY_DISPLAY_NAME(400, "ATLAS-400-00-082", "Category name is empty/null"), 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 ('@', '.')"), 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."), 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}"), UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to perform {1}"),
......
...@@ -20,11 +20,13 @@ package org.apache.atlas.type; ...@@ -20,11 +20,13 @@ package org.apache.atlas.type;
import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TimeBoundary;
import org.apache.atlas.model.instance.AtlasClassification; import org.apache.atlas.model.instance.AtlasClassification;
import org.apache.atlas.model.typedef.AtlasClassificationDef; import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef; import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.validator.routines.DateValidator;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -302,6 +304,10 @@ public class AtlasClassificationType extends AtlasStructType { ...@@ -302,6 +304,10 @@ public class AtlasClassificationType extends AtlasStructType {
} }
} }
if (!validateTimeBoundaries(obj, null)) {
return false;
}
return super.isValidValue(obj); return super.isValidValue(obj);
} }
...@@ -328,6 +334,10 @@ public class AtlasClassificationType extends AtlasStructType { ...@@ -328,6 +334,10 @@ public class AtlasClassificationType extends AtlasStructType {
} }
} }
if (!validateTimeBoundaries(obj, null)) {
return false;
}
return super.isValidValueForUpdate(obj); return super.isValidValueForUpdate(obj);
} }
...@@ -381,6 +391,8 @@ public class AtlasClassificationType extends AtlasStructType { ...@@ -381,6 +391,8 @@ public class AtlasClassificationType extends AtlasStructType {
ret = superType.validateValue(obj, objName, messages) && ret; ret = superType.validateValue(obj, objName, messages) && ret;
} }
ret = validateTimeBoundaries(obj, messages) && ret;
ret = super.validateValue(obj, objName, messages) && ret; ret = super.validateValue(obj, objName, messages) && ret;
} }
...@@ -396,6 +408,8 @@ public class AtlasClassificationType extends AtlasStructType { ...@@ -396,6 +408,8 @@ public class AtlasClassificationType extends AtlasStructType {
ret = superType.validateValueForUpdate(obj, objName, messages) && ret; ret = superType.validateValueForUpdate(obj, objName, messages) && ret;
} }
ret = validateTimeBoundaries(obj, messages) && ret;
ret = super.validateValueForUpdate(obj, objName, messages) && ret; ret = super.validateValueForUpdate(obj, objName, messages) && ret;
} }
...@@ -516,4 +530,77 @@ public class AtlasClassificationType extends AtlasStructType { ...@@ -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);
}
}
} }
...@@ -21,6 +21,7 @@ import java.util.*; ...@@ -21,6 +21,7 @@ import java.util.*;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.ModelTestUtil; import org.apache.atlas.model.ModelTestUtil;
import org.apache.atlas.model.TimeBoundary;
import org.apache.atlas.model.instance.AtlasClassification; import org.apache.atlas.model.instance.AtlasClassification;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef; import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
import org.apache.atlas.model.typedef.AtlasClassificationDef; import org.apache.atlas.model.typedef.AtlasClassificationDef;
...@@ -42,6 +43,25 @@ public class TestAtlasClassificationType { ...@@ -42,6 +43,25 @@ public class TestAtlasClassificationType {
AtlasClassification invalidValue1 = classificationType.createDefaultValue(); AtlasClassification invalidValue1 = classificationType.createDefaultValue();
AtlasClassification invalidValue2 = classificationType.createDefaultValue(); AtlasClassification invalidValue2 = classificationType.createDefaultValue();
Map<String, Object> invalidValue3 = classificationType.createDefaultValue().getAttributes(); 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 // invalid value for int
invalidValue1.setAttribute(ModelTestUtil.getDefaultAttributeName(AtlasBaseTypeDef.ATLAS_TYPE_INT), "xyz"); invalidValue1.setAttribute(ModelTestUtil.getDefaultAttributeName(AtlasBaseTypeDef.ATLAS_TYPE_INT), "xyz");
...@@ -53,6 +73,9 @@ public class TestAtlasClassificationType { ...@@ -53,6 +73,9 @@ public class TestAtlasClassificationType {
validValues.add(null); validValues.add(null);
validValues.add(classificationType.createDefaultValue()); validValues.add(classificationType.createDefaultValue());
validValues.add(classificationType.createDefaultValue().getAttributes()); // Map<String, Object> validValues.add(classificationType.createDefaultValue().getAttributes()); // Map<String, Object>
validValues.add(validValueTB1);
validValues.add(validValueTB2);
validValues.add(validValueTB3);
invalidValues.add(invalidValue1); invalidValues.add(invalidValue1);
invalidValues.add(invalidValue2); invalidValues.add(invalidValue2);
invalidValues.add(invalidValue3); invalidValues.add(invalidValue3);
...@@ -62,6 +85,9 @@ public class TestAtlasClassificationType { ...@@ -62,6 +85,9 @@ public class TestAtlasClassificationType {
invalidValues.add(new HashSet()); // incorrect datatype invalidValues.add(new HashSet()); // incorrect datatype
invalidValues.add(new ArrayList()); // incorrect datatype invalidValues.add(new ArrayList()); // incorrect datatype
invalidValues.add(new String[] {}); // incorrect datatype invalidValues.add(new String[] {}); // incorrect datatype
invalidValues.add(invalidValueTB1);
invalidValues.add(invalidValueTB2);
invalidValues.add(invalidValueTB3);
} }
@Test @Test
......
...@@ -583,6 +583,7 @@ ...@@ -583,6 +583,7 @@
<commons-collections.version>3.2.2</commons-collections.version> <commons-collections.version>3.2.2</commons-collections.version>
<commons-logging.version>1.1.3</commons-logging.version> <commons-logging.version>1.1.3</commons-logging.version>
<commons-lang.version>2.6</commons-lang.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> <javax-inject.version>1</javax-inject.version>
<jettison.version>1.3.7</jettison.version> <jettison.version>1.3.7</jettison.version>
<paranamer.version>2.7</paranamer.version> <paranamer.version>2.7</paranamer.version>
......
...@@ -403,6 +403,7 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore { ...@@ -403,6 +403,7 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
} }
GraphTransactionInterceptor.lockObjectAndReleasePostCommit(guid); GraphTransactionInterceptor.lockObjectAndReleasePostCommit(guid);
for (AtlasClassification classification : classifications) { for (AtlasClassification classification : classifications) {
validateAndNormalize(classification); validateAndNormalize(classification);
} }
...@@ -436,6 +437,10 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore { ...@@ -436,6 +437,10 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
GraphTransactionInterceptor.lockObjectAndReleasePostCommit(guid); GraphTransactionInterceptor.lockObjectAndReleasePostCommit(guid);
for (AtlasClassification classification : classifications) {
validateAndNormalize(classification);
}
entityGraphMapper.updateClassifications(new EntityMutationContext(), guid, classifications); entityGraphMapper.updateClassifications(new EntityMutationContext(), guid, classifications);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment