This is an automated email from the ASF dual-hosted git repository. kbhatt pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/atlas.git
commit 1b41b980415961419bb4af8710bd82f34395779c Author: chaitali borole <chaitali.bor...@cloudera.com> AuthorDate: Mon Aug 10 20:01:00 2020 +0530 ATLAS-3892 : Basic search enhanced Feature - Search history Signed-off-by: kevalbhatt <kbh...@apache.org> --- .../org/apache/atlas/repository/Constants.java | 1 + .../atlas/model/discovery/SearchParameters.java | 5 + .../apache/atlas/discovery/SearchProcessor.java | 181 ++++++++++++++-- .../org/apache/atlas/util/SearchPredicateUtil.java | 58 ++++- .../atlas/discovery/EntitySearchProcessorTest.java | 238 +++++++++++++++++++++ 5 files changed, 468 insertions(+), 15 deletions(-) diff --git a/common/src/main/java/org/apache/atlas/repository/Constants.java b/common/src/main/java/org/apache/atlas/repository/Constants.java index a71787b..61abfca 100644 --- a/common/src/main/java/org/apache/atlas/repository/Constants.java +++ b/common/src/main/java/org/apache/atlas/repository/Constants.java @@ -188,6 +188,7 @@ public final class Constants { public static final String TERM_ASSIGNMENT_LABEL = "r:AtlasGlossarySemanticAssignment"; public static final String ATTRIBUTE_INDEX_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "index"); public static final String ATTRIBUTE_KEY_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "key"); + public static final String ATTRIBUTE_VALUE_DELIMITER = ","; public static final String VERTEX_ID_IN_IMPORT_KEY = "__vIdInImport"; public static final String EDGE_ID_IN_IMPORT_KEY = "__eIdInImport"; diff --git a/intg/src/main/java/org/apache/atlas/model/discovery/SearchParameters.java b/intg/src/main/java/org/apache/atlas/model/discovery/SearchParameters.java index fcc4494..367c5b8 100644 --- a/intg/src/main/java/org/apache/atlas/model/discovery/SearchParameters.java +++ b/intg/src/main/java/org/apache/atlas/model/discovery/SearchParameters.java @@ -443,6 +443,10 @@ public class SearchParameters implements Serializable { * Logical comparision operators can only be used with numbers or dates * IN, LIKE, startsWith, endsWith, CONTAINS can only be used with strings or text */ + + /** + * NOTE : The names added in the String array should always contain first value in lower case + */ public enum Operator { LT(new String[]{"<", "lt"}), GT(new String[]{">", "gt"}), @@ -460,6 +464,7 @@ public class SearchParameters implements Serializable { CONTAINS_ALL(new String[]{"containsAll", "CONTAINSALL", "contains_all", "CONTAINS_ALL"}), IS_NULL(new String[]{"isNull", "ISNULL", "is_null", "IS_NULL"}), NOT_NULL(new String[]{"notNull", "NOTNULL", "not_null", "NOT_NULL"}), + TIME_RANGE(new String[]{"timerange", "TIMERANGE","time_range","TIME_RANGE"}) ; static final Map<String, Operator> operatorsMap = new HashMap<>(); diff --git a/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java b/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java index c5e3d6f..da9dd66 100644 --- a/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java +++ b/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java @@ -17,6 +17,7 @@ */ package org.apache.atlas.discovery; +import com.google.common.annotations.VisibleForTesting; import org.apache.atlas.ApplicationProperties; import org.apache.atlas.AtlasException; import org.apache.atlas.SortOrder; @@ -46,6 +47,8 @@ import org.slf4j.LoggerFactory; import java.math.BigDecimal; import java.math.BigInteger; +import java.sql.Timestamp; +import java.time.LocalDateTime; import java.util.*; import java.util.regex.Pattern; @@ -121,6 +124,9 @@ public abstract class SearchProcessor { OPERATOR_MAP.put(SearchParameters.Operator.NOT_NULL, INDEX_SEARCH_PREFIX + "\"%s\":[* TO *]"); OPERATOR_PREDICATE_MAP.put(SearchParameters.Operator.NOT_NULL, getNotNullPredicateGenerator()); + + OPERATOR_MAP.put(SearchParameters.Operator.TIME_RANGE, INDEX_SEARCH_PREFIX + "\"%s\": [%s TO %s]"); + OPERATOR_PREDICATE_MAP.put(SearchParameters.Operator.TIME_RANGE, getInRangePredicateGenerator()); } protected final SearchContext context; @@ -523,6 +529,9 @@ public abstract class SearchProcessor { } } else if (StringUtils.isNotEmpty(criteria.getAttributeName())) { try { + if (criteria.getOperator() == SearchParameters.Operator.TIME_RANGE) { + criteria = processDateRange(criteria); + } ArrayList<String> orExpQuery = new ArrayList<>(); for (AtlasStructType structType : structTypes) { String name = structType.getVertexPropertyName(criteria.getAttributeName()); @@ -584,6 +593,10 @@ public abstract class SearchProcessor { String attrValue = criteria.getAttributeValue(); SearchParameters.Operator operator = criteria.getOperator(); + if (operator == SearchParameters.Operator.TIME_RANGE) { + FilterCriteria processedRangeCriteria = processDateRange(criteria); + attrValue = processedRangeCriteria.getAttributeValue(); + } //process attribute value and attribute operator for pipeSeperated fields if (isPipeSeparatedSystemAttribute(attrName)) { FilterCriteria processedCriteria = processPipeSeperatedSystemAttribute(attrName, operator, attrValue); @@ -610,6 +623,115 @@ public abstract class SearchProcessor { return null; } + @VisibleForTesting + public FilterCriteria processDateRange(FilterCriteria criteria) { + String attrName = criteria.getAttributeName(); + SearchParameters.Operator op = criteria.getOperator(); + String attrVal = criteria.getAttributeValue(); + FilterCriteria ret = new FilterCriteria(); + final LocalDateTime now = LocalDateTime.now(); + final LocalDateTime startTime; + final LocalDateTime endTime; + + switch (attrVal) { + case "LAST_7_DAYS": + startTime = now.minusDays(6).withHour(0).withMinute(0).withSecond(0).withNano(0); + endTime = startTime.plusDays(7).minusNanos(1); + break; + + case "LAST_30_DAYS": + startTime = now.minusDays(29).withHour(0).withMinute(0).withSecond(0).withNano(0); + endTime = startTime.plusDays(30).minusNanos(1); + break; + + case "LAST_MONTH": + startTime = now.minusMonths(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0); + endTime = startTime.plusMonths(1).minusNanos(1); + break; + + case "THIS_MONTH": + startTime = now.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0); + endTime = startTime.plusMonths(1).minusNanos(1); + break; + + case "TODAY": + startTime = now.withHour(0).withMinute(0).withSecond(0).withNano(0); + endTime = startTime.plusDays(1).minusNanos(1); + break; + + case "YESTERDAY": + startTime = now.minusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0); + endTime = startTime.plusDays(1).minusNanos(1); + break; + + case "THIS_YEAR": + startTime = now.withDayOfYear(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0); + endTime = startTime.plusYears(1).minusNanos(1); + break; + + case "LAST_YEAR": + startTime = now.minusYears(1).withDayOfYear(1).withHour(0).withMinute(0).withSecond(0).withNano(0); + endTime = startTime.plusYears(1).minusNanos(1); + break; + + case "THIS_QUARTER": + startTime = now.minusMonths(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0); + endTime = startTime.plusMonths(3).minusNanos(1); + break; + + case "LAST_QUARTER": + startTime = now.minusMonths(4).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0); + endTime = startTime.plusMonths(3).minusNanos(1); + break; + + case "LAST_3_MONTHS": + startTime = now.minusMonths(3).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0); + endTime = startTime.plusMonths(3).minusNanos(1); + break; + + case "LAST_6_MONTHS": + startTime = now.minusMonths(6).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0); + endTime = startTime.plusMonths(6).minusNanos(1); + break; + + case "LAST_12_MONTHS": + startTime = now.minusMonths(12).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0); + endTime = startTime.plusMonths(12).minusNanos(1); + break; + + default: + startTime = null; + endTime = null; + break; + } + + if (startTime == null || endTime == null) { + String[] rangeAttr = attrVal.split(ATTRIBUTE_VALUE_DELIMITER); + boolean numeric = true; + if (rangeAttr.length != 2) { + LOG.error("Separator invalid"); + } else { + try { + Long parsestartTime = Long.parseLong(String.valueOf(rangeAttr[0])); + Long parseendTime = Long.parseLong(String.valueOf(rangeAttr[1])); + } catch (NumberFormatException e) { + numeric = false; + if (!numeric) { + LOG.error("Attributes passed need to be LONG"); + } + } + } + }else { + attrVal = Timestamp.valueOf(startTime).getTime() + ATTRIBUTE_VALUE_DELIMITER + Timestamp.valueOf(endTime).getTime(); + } + + ret.setAttributeName(attrName); + ret.setOperator(op); + ret.setAttributeValue(attrVal); + + return ret; + } + private FilterCriteria processPipeSeperatedSystemAttribute(String attrName, SearchParameters.Operator op, String attrVal) { FilterCriteria ret = new FilterCriteria(); @@ -648,20 +770,32 @@ public abstract class SearchProcessor { return ret; } - private String toIndexExpression(AtlasStructType type, String attrName, SearchParameters.Operator op, String attrVal) { + private String toIndexExpression(AtlasStructType type, String attrName, SearchParameters.Operator op, String attrVal) throws AtlasBaseException{ String ret = EMPTY_STRING; try { if (OPERATOR_MAP.get(op) != null) { - String qualifiedName = type.getVertexPropertyName(attrName); - String escapeIndexQueryValue = AtlasAttribute.escapeIndexQueryValue(attrVal); - - // map '__customAttributes' 'CONTAINS' operator to 'EQ' operator (solr limitation for json serialized string search) - // map '__customAttributes' value from 'key1=value1' to '\"key1\":\"value1\"' (escape special characters and surround with quotes) - if (attrName.equals(CUSTOM_ATTRIBUTES_PROPERTY_KEY) && op == SearchParameters.Operator.CONTAINS) { - ret = String.format(OPERATOR_MAP.get(op), qualifiedName, getCustomAttributeIndexQueryValue(escapeIndexQueryValue, false)); + String rangeStart = ""; + String rangeEnd = ""; + String qualifiedName = type.getVertexPropertyName(attrName); + if (op == SearchParameters.Operator.TIME_RANGE) { + String[] parts = attrVal.split(ATTRIBUTE_VALUE_DELIMITER); + if (parts.length == 2) { + rangeStart = parts[0]; + rangeEnd = parts[1]; + String rangeStartIndexQueryValue = AtlasAttribute.escapeIndexQueryValue(rangeStart); + String rangeEndIndexQueryValue = AtlasAttribute.escapeIndexQueryValue(rangeEnd); + ret = String.format(OPERATOR_MAP.get(op), qualifiedName, rangeStartIndexQueryValue, rangeEndIndexQueryValue); + } } else { - ret = String.format(OPERATOR_MAP.get(op), qualifiedName, escapeIndexQueryValue); + // map '__customAttributes' 'CONTAINS' operator to 'EQ' operator (solr limitation for json serialized string search) + // map '__customAttributes' value from 'key1=value1' to '\"key1\":\"value1\"' (escape special characters and surround with quotes) + String escapeIndexQueryValue = AtlasAttribute.escapeIndexQueryValue(attrVal); + if (attrName.equals(CUSTOM_ATTRIBUTES_PROPERTY_KEY) && op == SearchParameters.Operator.CONTAINS) { + ret = String.format(OPERATOR_MAP.get(op), qualifiedName, getCustomAttributeIndexQueryValue(escapeIndexQueryValue, false)); + } else { + ret = String.format(OPERATOR_MAP.get(op), qualifiedName, escapeIndexQueryValue); + } } } } catch (AtlasBaseException ex) { @@ -695,7 +829,6 @@ public abstract class SearchProcessor { private Predicate toInMemoryPredicate(AtlasStructType type, String attrName, SearchParameters.Operator op, String attrVal) { Predicate ret = null; - AtlasAttribute attribute = type.getAttribute(attrName); ElementAttributePredicateGenerator predicate = OPERATOR_PREDICATE_MAP.get(op); @@ -703,6 +836,7 @@ public abstract class SearchProcessor { final AtlasType attrType = attribute.getAttributeType(); final Class attrClass; final Object attrValue; + Object attrValue2 = null; // Some operators support null comparison, thus the parsing has to be conditional switch (attrType.getTypeName()) { @@ -733,7 +867,21 @@ public abstract class SearchProcessor { case AtlasBaseTypeDef.ATLAS_TYPE_LONG: case AtlasBaseTypeDef.ATLAS_TYPE_DATE: attrClass = Long.class; - attrValue = StringUtils.isEmpty(attrVal) ? null : Long.parseLong(attrVal); + String rangeStart = ""; + String rangeEnd = ""; + if (op == SearchParameters.Operator.TIME_RANGE) { + String[] parts = attrVal.split(ATTRIBUTE_VALUE_DELIMITER); + if (parts.length == 2) { + rangeStart = parts[0]; + rangeEnd = parts[1]; + } + } + if (StringUtils.isNotEmpty(rangeStart) && StringUtils.isNotEmpty(rangeEnd)) { + attrValue = Long.parseLong(rangeStart); + attrValue2 = Long.parseLong(rangeEnd); + } else { + attrValue = StringUtils.isEmpty(attrVal) ? null : Long.parseLong(attrVal); + } break; case AtlasBaseTypeDef.ATLAS_TYPE_FLOAT: attrClass = Float.class; @@ -761,9 +909,14 @@ public abstract class SearchProcessor { } String vertexPropertyName = attribute.getVertexPropertyName(); - ret = predicate.generatePredicate( - StringUtils.isEmpty(vertexPropertyName) ? attribute.getQualifiedName() : vertexPropertyName, - attrValue, attrClass); + if (attrValue != null && attrValue2 != null) { + ret = predicate.generatePredicate(StringUtils.isEmpty(vertexPropertyName) ? attribute.getQualifiedName() : vertexPropertyName, + attrValue, attrValue2, attrClass); + } else { + ret = predicate.generatePredicate( + StringUtils.isEmpty(vertexPropertyName) ? attribute.getQualifiedName() : vertexPropertyName, + attrValue, attrClass); + } } return ret; diff --git a/repository/src/main/java/org/apache/atlas/util/SearchPredicateUtil.java b/repository/src/main/java/org/apache/atlas/util/SearchPredicateUtil.java index cf158cd..9c29756 100644 --- a/repository/src/main/java/org/apache/atlas/util/SearchPredicateUtil.java +++ b/repository/src/main/java/org/apache/atlas/util/SearchPredicateUtil.java @@ -179,6 +179,40 @@ public class SearchPredicateUtil { return ret; } + public static ElementAttributePredicateGenerator getInRangePredicateGenerator() { + if (LOG.isDebugEnabled()) { + LOG.debug("==> getInRangePredicateGenerator"); + } + + ElementAttributePredicateGenerator ret = new ElementAttributePredicateGenerator() { + + @Override + public Predicate generatePredicate(String attrName, Object attrVal, Class attrClass) { + return generatePredicate(attrName, attrVal, attrVal, attrClass); + } + + @Override + public Predicate generatePredicate(String attrName, Object attrVal, Object attrVal2, Class attrClass) { + final Predicate ret; + + if (attrName == null || attrClass == null || attrVal == null || attrVal2 == null) { + ret = ALWAYS_FALSE; + } else if (Long.class.isAssignableFrom(attrClass)) { + ret = LongPredicate.getInRangePredicate(attrName, attrClass, (Long) attrVal, (Long) attrVal2); + } else { + ret = ALWAYS_FALSE; + } + return ret; + } + }; + + if (LOG.isDebugEnabled()) { + LOG.debug("<== getInRangePredicateGenerator"); + } + + return ret; + } + public static ElementAttributePredicateGenerator getGTEPredicateGenerator() { if (LOG.isDebugEnabled()) { LOG.debug("==> getGTEPredicateGenerator"); @@ -768,6 +802,9 @@ public class SearchPredicateUtil { public interface ElementAttributePredicateGenerator { Predicate generatePredicate(String attrName, Object attrVal, Class attrClass); + default Predicate generatePredicate(String attrName, Object attrVal, Object attrVal2, Class attrClass) { + return generatePredicate(attrName, attrVal, attrClass); + } } static abstract class ElementAttributePredicate implements Predicate { @@ -969,16 +1006,27 @@ public class SearchPredicateUtil { static abstract class LongPredicate extends ElementAttributePredicate { final Long value; + final Long value2; LongPredicate(String attrName, Class attrClass, Long value) { super(attrName, attrClass); this.value = value; + this.value2 = null; + } - LongPredicate(String attrName, Class attrClass, Long value, boolean isNullValid) { + LongPredicate(String attrName, Class attrClass, Long value, Long value2, boolean isNullValid) { super(attrName, attrClass, isNullValid); this.value = value; + this.value2 = value2; + + } + + LongPredicate(String attrName, Class attrClass, Long value, boolean isNullValid) { + super(attrName, attrClass, isNullValid); + this.value = value; + this.value2 = null; } static ElementAttributePredicate getEQPredicate(String attrName, Class attrClass, Long value) { @@ -1028,6 +1076,14 @@ public class SearchPredicateUtil { } }; } + + static ElementAttributePredicate getInRangePredicate(String attrName, Class attrClass, Long rangeStart, Long rangeEnd) { + return new LongPredicate(attrName, attrClass, rangeStart, rangeEnd, false) { + protected boolean compareValue(Object vertexAttrVal) { + return ((Long) vertexAttrVal).compareTo(value) >= 0 && ((Long) vertexAttrVal).compareTo(value2) <= 0; + } + }; + } } static abstract class FloatPredicate extends ElementAttributePredicate { diff --git a/repository/src/test/java/org/apache/atlas/discovery/EntitySearchProcessorTest.java b/repository/src/test/java/org/apache/atlas/discovery/EntitySearchProcessorTest.java index 7b40c21..db107b3 100644 --- a/repository/src/test/java/org/apache/atlas/discovery/EntitySearchProcessorTest.java +++ b/repository/src/test/java/org/apache/atlas/discovery/EntitySearchProcessorTest.java @@ -35,16 +35,23 @@ import org.testng.annotations.Guice; import org.testng.annotations.Test; import javax.inject.Inject; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Calendar; +import java.util.GregorianCalendar; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @Guice(modules = TestModules.TestOnlyModule.class) public class EntitySearchProcessorTest extends BasicTestSetup { + private static final Logger LOG = LoggerFactory.getLogger(EntitySearchProcessorTest.class); + private final SimpleDateFormat formattedDate = new SimpleDateFormat("dd-MMM-yyyy"); @Inject private AtlasGraph graph; @@ -360,4 +367,235 @@ public class EntitySearchProcessorTest extends BasicTestSetup { AtlasGraphProvider.cleanup(); } + @Test + public void testLast7Days() throws AtlasBaseException { + SearchParameters.FilterCriteria ret = filtercriteriaDateRange("LAST_7_DAYS",typeRegistry,graph); + ret.setAttributeName("createTime"); + GregorianCalendar startDate = new GregorianCalendar(); + GregorianCalendar endDate = new GregorianCalendar(); + startDate.add(Calendar.DATE, -6); + + String[] dates = ret.getAttributeValue().split(","); + String attrValue1 = dates[0]; + String attrValue2 = dates[1]; + + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue1)))), formattedDate.format(startDate.getTime())); + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue2)))), formattedDate.format(endDate.getTime())); + } + + @Test + public void testLastMonth() throws AtlasBaseException { + SearchParameters.FilterCriteria ret = filtercriteriaDateRange("LAST_MONTH", typeRegistry,graph); + Calendar originalstartdate = Calendar.getInstance(); + Calendar originalenddate = Calendar.getInstance(); + + originalstartdate.add(Calendar.MONTH, -1); + originalstartdate.set(Calendar.DAY_OF_MONTH, originalstartdate.getActualMinimum(Calendar.DAY_OF_MONTH)); + originalenddate.add(Calendar.MONTH, -1); + originalenddate.set(Calendar.DAY_OF_MONTH, originalenddate.getActualMaximum(Calendar.DAY_OF_MONTH)); + + String[] dates = ret.getAttributeValue().split(","); + String attrValue1 = dates[0]; + String attrValue2 = dates[1]; + + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue1)))), formattedDate.format(originalstartdate.getTime())); + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue2)))), formattedDate.format(originalenddate.getTime())); + } + + @Test + public void testLast30Days() throws AtlasBaseException { + SearchParameters.FilterCriteria ret = filtercriteriaDateRange("LAST_30_DAYS", typeRegistry,graph); + GregorianCalendar startDate = new GregorianCalendar(); + GregorianCalendar endDate = new GregorianCalendar(); + startDate.add(Calendar.DATE, -29); + + String[] dates = ret.getAttributeValue().split(","); + String attrValue1 = dates[0]; + String attrValue2 = dates[1]; + + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue1)))), formattedDate.format(startDate.getTime())); + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue2)))), formattedDate.format(endDate.getTime())); + } + + @Test + public void testYesterday() throws AtlasBaseException { + SearchParameters.FilterCriteria ret = filtercriteriaDateRange("YESTERDAY", typeRegistry,graph); + GregorianCalendar yesterdayDate = new GregorianCalendar(); + yesterdayDate.add(Calendar.DATE, -1); + + String[] dates = ret.getAttributeValue().split(","); + String attrValue1 = dates[0]; + + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue1)))), formattedDate.format(yesterdayDate.getTime())); + } + + @Test + public void testThisMonth() throws AtlasBaseException { + SearchParameters.FilterCriteria ret = filtercriteriaDateRange("THIS_MONTH", typeRegistry,graph); + Calendar originalstartdate = Calendar.getInstance(); + Calendar originalenddate = Calendar.getInstance(); + + originalstartdate.set(Calendar.DAY_OF_MONTH, originalstartdate.getActualMinimum(Calendar.DAY_OF_MONTH)); + originalenddate.set(Calendar.DAY_OF_MONTH, originalenddate.getActualMaximum(Calendar.DAY_OF_MONTH)); + + String[] dates = ret.getAttributeValue().split(","); + String attrValue1 = dates[0]; + String attrValue2 = dates[1]; + + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue1)))), formattedDate.format(originalstartdate.getTime())); + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue2)))), formattedDate.format(originalenddate.getTime())); + } + + @Test + public void testThisQuarter() throws AtlasBaseException { + SearchParameters.FilterCriteria ret = filtercriteriaDateRange("THIS_QUARTER", typeRegistry,graph); + Calendar originalstartdate = Calendar.getInstance(); + Calendar originalenddate = Calendar.getInstance(); + originalstartdate.add(Calendar.MONTH, -1); + originalstartdate.set(Calendar.DAY_OF_MONTH, originalstartdate.getActualMinimum(Calendar.DAY_OF_MONTH)); + originalenddate.add(Calendar.MONTH, 1); + originalenddate.set(Calendar.DAY_OF_MONTH, originalenddate.getActualMaximum(Calendar.DAY_OF_MONTH)); + + String[] dates = ret.getAttributeValue().split(","); + String attrValue1 = dates[0]; + String attrValue2 = dates[1]; + + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue1)))), formattedDate.format(originalstartdate.getTime())); + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue2)))), formattedDate.format(originalenddate.getTime())); + } + + @Test + public void testLastQuarter() throws AtlasBaseException { + SearchParameters.FilterCriteria ret = filtercriteriaDateRange("LAST_QUARTER", typeRegistry,graph); + Calendar originalstartdate = Calendar.getInstance(); + Calendar originalenddate = Calendar.getInstance(); + originalstartdate.add(Calendar.MONTH, -4); + originalstartdate.set(Calendar.DAY_OF_MONTH, originalstartdate.getActualMinimum(Calendar.DAY_OF_MONTH)); + originalenddate.add(Calendar.MONTH, -2); + originalenddate.set(Calendar.DAY_OF_MONTH, originalenddate.getActualMaximum(Calendar.DAY_OF_MONTH)); + + String[] dates = ret.getAttributeValue().split(","); + String attrValue1 = dates[0]; + String attrValue2 = dates[1]; + + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue1)))), formattedDate.format(originalstartdate.getTime())); + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue2)))), formattedDate.format(originalenddate.getTime())); + } + + + @Test + public void testLast3Months() throws AtlasBaseException { + SearchParameters.FilterCriteria ret = filtercriteriaDateRange("LAST_3_MONTHS", typeRegistry,graph); + Calendar originalstartdate = Calendar.getInstance(); + Calendar originalenddate = Calendar.getInstance(); + + originalstartdate.add(Calendar.MONTH, -3); + originalstartdate.set(Calendar.DAY_OF_MONTH, originalstartdate.getActualMinimum(Calendar.DAY_OF_MONTH)); + originalenddate.add(Calendar.MONTH, -1); + originalenddate.set(Calendar.DAY_OF_MONTH, originalenddate.getActualMaximum(Calendar.DAY_OF_MONTH)); + + String[] dates = ret.getAttributeValue().split(","); + String attrValue1 = dates[0]; + String attrValue2 = dates[1]; + + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue1)))), formattedDate.format(originalstartdate.getTime())); + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue2)))), formattedDate.format(originalenddate.getTime())); + } + + @Test + public void testThisYear() throws AtlasBaseException { + SearchParameters.FilterCriteria ret = filtercriteriaDateRange("THIS_YEAR",typeRegistry,graph); + Calendar originalstartdate = Calendar.getInstance(); + Calendar originalenddate = Calendar.getInstance(); + + originalstartdate.set(Calendar.MONTH, 0); + originalstartdate.set(Calendar.DAY_OF_MONTH, originalstartdate.getActualMinimum(Calendar.DAY_OF_MONTH)); + + originalenddate.set(Calendar.MONTH, 11); + originalenddate.set(Calendar.DAY_OF_MONTH, originalenddate.getActualMaximum(Calendar.DAY_OF_MONTH)); + + String[] dates = ret.getAttributeValue().split(","); + String attrValue1 = dates[0]; + String attrValue2 = dates[1]; + + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue1)))), formattedDate.format(originalstartdate.getTime())); + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue2)))), formattedDate.format(originalenddate.getTime())); + } + + @Test + public void testLastYear() throws AtlasBaseException { + SearchParameters.FilterCriteria ret = filtercriteriaDateRange("LAST_YEAR",typeRegistry,graph); + Calendar originalstartdate = Calendar.getInstance(); + Calendar originalenddate = Calendar.getInstance(); + + originalstartdate.add(Calendar.YEAR, -1); + originalstartdate.set(Calendar.MONTH, 0); + originalstartdate.set(Calendar.DAY_OF_MONTH, originalstartdate.getActualMinimum(Calendar.DAY_OF_MONTH)); + + originalenddate.add(Calendar.YEAR, -1); + originalenddate.set(Calendar.MONTH, 11); + originalenddate.set(Calendar.DAY_OF_MONTH, originalenddate.getActualMaximum(Calendar.DAY_OF_MONTH)); + + String[] dates = ret.getAttributeValue().split(","); + String attrValue1 = dates[0]; + String attrValue2 = dates[1]; + + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue1)))), formattedDate.format(originalstartdate.getTime())); + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue2)))), formattedDate.format(originalenddate.getTime())); + } + + @Test + public void testLast12Months() throws AtlasBaseException { + SearchParameters.FilterCriteria ret = filtercriteriaDateRange("LAST_12_MONTHS",typeRegistry,graph); + Calendar originalstartdate = Calendar.getInstance(); + Calendar originalenddate = Calendar.getInstance(); + + originalstartdate.add(Calendar.MONTH, -12); + originalstartdate.set(Calendar.DAY_OF_MONTH, originalstartdate.getActualMinimum(Calendar.DAY_OF_MONTH)); + + originalenddate.add(Calendar.MONTH, -1); + originalenddate.set(Calendar.DAY_OF_MONTH, originalenddate.getActualMaximum(Calendar.DAY_OF_MONTH)); + + String[] dates = ret.getAttributeValue().split(","); + String attrValue1 = dates[0]; + String attrValue2 = dates[1]; + + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue1)))), formattedDate.format(originalstartdate.getTime())); + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue2)))), formattedDate.format(originalenddate.getTime())); + } + + @Test + public void testLast6Months() throws AtlasBaseException { + SearchParameters.FilterCriteria ret = filtercriteriaDateRange("LAST_6_MONTHS",typeRegistry,graph); + Calendar originalstartdate = Calendar.getInstance(); + Calendar originalenddate = Calendar.getInstance(); + + originalstartdate.add(Calendar.MONTH, -6); + originalstartdate.set(Calendar.DAY_OF_MONTH, originalstartdate.getActualMinimum(Calendar.DAY_OF_MONTH)); + + originalenddate.add(Calendar.MONTH, -1); + originalenddate.set(Calendar.DAY_OF_MONTH, originalenddate.getActualMaximum(Calendar.DAY_OF_MONTH)); + + String[] dates = ret.getAttributeValue().split(","); + String attrValue1 = dates[0]; + String attrValue2 = dates[1]; + + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue1)))), formattedDate.format(originalstartdate.getTime())); + assertEquals(formattedDate.format(new Date((Long.parseLong(attrValue2)))), formattedDate.format(originalenddate.getTime())); + } + + private static SearchParameters.FilterCriteria filtercriteriaDateRange(String attributeValue, AtlasTypeRegistry typeRegistry, AtlasGraph graph) throws AtlasBaseException { + SearchParameters params = new SearchParameters(); + params.setTypeName(HIVE_TABLE_TYPE); + SearchParameters.FilterCriteria filterCriteria = new SearchParameters.FilterCriteria(); + params.setEntityFilters(filterCriteria); + params.setLimit(20); + SearchContext context = new SearchContext(params, typeRegistry, graph, Collections.<String>emptySet()); + EntitySearchProcessor processor = new EntitySearchProcessor(context); + filterCriteria.setCondition(SearchParameters.FilterCriteria.Condition.AND); + filterCriteria.setOperator(SearchParameters.Operator.TIME_RANGE); + filterCriteria.setAttributeValue(attributeValue); + SearchParameters.FilterCriteria ret = processor.processDateRange(filterCriteria); + return ret; + } }