diff --git a/src/main/java/org/opensearch/ad/model/ADTask.java b/src/main/java/org/opensearch/ad/model/ADTask.java index d51d39022..19fc87682 100644 --- a/src/main/java/org/opensearch/ad/model/ADTask.java +++ b/src/main/java/org/opensearch/ad/model/ADTask.java @@ -344,7 +344,8 @@ public static ADTask parse(XContentParser parser, String taskId) throws IOExcept detector.getRules(), detector.getCustomResultIndexMinSize(), detector.getCustomResultIndexMinAge(), - detector.getCustomResultIndexTTL() + detector.getCustomResultIndexTTL(), + detector.getFlattenResultIndexMapping() ); return new Builder() .taskId(parsedTaskId) diff --git a/src/main/java/org/opensearch/ad/model/AnomalyDetector.java b/src/main/java/org/opensearch/ad/model/AnomalyDetector.java index f5de3bba6..d88ffa653 100644 --- a/src/main/java/org/opensearch/ad/model/AnomalyDetector.java +++ b/src/main/java/org/opensearch/ad/model/AnomalyDetector.java @@ -150,6 +150,7 @@ public Integer getShingleSize(Integer customShingleSize) { * @param customResultIndexMinSize custom result index lifecycle management min size condition * @param customResultIndexMinAge custom result index lifecycle management min age condition * @param customResultIndexTTL custom result index lifecycle management ttl + * @param flattenResultIndexMapping flag to indicate whether to flatten result index mapping or not */ public AnomalyDetector( String detectorId, @@ -176,7 +177,8 @@ public AnomalyDetector( List rules, Integer customResultIndexMinSize, Integer customResultIndexMinAge, - Integer customResultIndexTTL + Integer customResultIndexTTL, + Boolean flattenResultIndexMapping ) { super( detectorId, @@ -203,7 +205,8 @@ public AnomalyDetector( historyIntervals, customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); checkAndThrowValidationErrors(ValidationAspect.DETECTOR); @@ -280,6 +283,7 @@ public AnomalyDetector(StreamInput input) throws IOException { this.customResultIndexMinSize = input.readOptionalInt(); this.customResultIndexMinAge = input.readOptionalInt(); this.customResultIndexTTL = input.readOptionalInt(); + this.flattenResultIndexMapping = input.readOptionalBoolean(); } public XContentBuilder toXContent(XContentBuilder builder) throws IOException { @@ -345,6 +349,7 @@ public void writeTo(StreamOutput output) throws IOException { output.writeOptionalInt(customResultIndexMinSize); output.writeOptionalInt(customResultIndexMinAge); output.writeOptionalInt(customResultIndexTTL); + output.writeOptionalBoolean(flattenResultIndexMapping); } @Override @@ -441,6 +446,7 @@ public static AnomalyDetector parse( Integer customResultIndexMinSize = null; Integer customResultIndexMinAge = null; Integer customResultIndexTTL = null; + Boolean flattenResultIndexMapping = null; ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser); while (parser.nextToken() != XContentParser.Token.END_OBJECT) { @@ -575,6 +581,9 @@ public static AnomalyDetector parse( case RESULT_INDEX_FIELD_TTL: customResultIndexTTL = onlyParseNumberValue(parser); break; + case FLATTEN_RESULT_INDEX_MAPPING: + flattenResultIndexMapping = onlyParseBooleanValue(parser); + break; default: parser.skipChildren(); break; @@ -605,7 +614,8 @@ public static AnomalyDetector parse( rules, customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); detector.setDetectionDateRange(detectionDateRange); return detector; @@ -692,4 +702,11 @@ private static Integer onlyParseNumberValue(XContentParser parser) throws IOExce } return null; } + + private static Boolean onlyParseBooleanValue(XContentParser parser) throws IOException { + if (parser.currentToken() == XContentParser.Token.VALUE_BOOLEAN) { + return parser.booleanValue(); + } + return null; + } } diff --git a/src/main/java/org/opensearch/ad/rest/handler/AbstractAnomalyDetectorActionHandler.java b/src/main/java/org/opensearch/ad/rest/handler/AbstractAnomalyDetectorActionHandler.java index 1219107c4..7c86610a4 100644 --- a/src/main/java/org/opensearch/ad/rest/handler/AbstractAnomalyDetectorActionHandler.java +++ b/src/main/java/org/opensearch/ad/rest/handler/AbstractAnomalyDetectorActionHandler.java @@ -244,7 +244,8 @@ protected AnomalyDetector copyConfig(User user, Config config) { detector.getRules(), config.getCustomResultIndexMinSize(), config.getCustomResultIndexMinAge(), - config.getCustomResultIndexTTL() + config.getCustomResultIndexTTL(), + config.getFlattenResultIndexMapping() ); } diff --git a/src/main/java/org/opensearch/forecast/model/ForecastTask.java b/src/main/java/org/opensearch/forecast/model/ForecastTask.java index 33bd114ab..bb6a53d50 100644 --- a/src/main/java/org/opensearch/forecast/model/ForecastTask.java +++ b/src/main/java/org/opensearch/forecast/model/ForecastTask.java @@ -342,7 +342,8 @@ public static ForecastTask parse(XContentParser parser, String taskId) throws IO forecaster.getHistoryIntervals(), forecaster.getCustomResultIndexMinSize(), forecaster.getCustomResultIndexMinAge(), - forecaster.getCustomResultIndexTTL() + forecaster.getCustomResultIndexTTL(), + forecaster.getFlattenResultIndexMapping() ); return new Builder() .taskId(parsedTaskId) diff --git a/src/main/java/org/opensearch/forecast/model/Forecaster.java b/src/main/java/org/opensearch/forecast/model/Forecaster.java index 8feb24795..0cac28d8b 100644 --- a/src/main/java/org/opensearch/forecast/model/Forecaster.java +++ b/src/main/java/org/opensearch/forecast/model/Forecaster.java @@ -134,7 +134,8 @@ public Forecaster( Integer historyIntervals, Integer customResultIndexMinSize, Integer customResultIndexMinAge, - Integer customResultIndexTTL + Integer customResultIndexTTL, + Boolean flattenResultIndexMapping ) { super( forecasterId, @@ -161,7 +162,8 @@ public Forecaster( historyIntervals, customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); checkAndThrowValidationErrors(ValidationAspect.FORECASTER); @@ -303,6 +305,7 @@ public static Forecaster parse( Integer customResultIndexMinSize = null; Integer customResultIndexMinAge = null; Integer customResultIndexTTL = null; + Boolean flattenResultIndexMapping = null; ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser); while (parser.nextToken() != XContentParser.Token.END_OBJECT) { @@ -431,6 +434,9 @@ public static Forecaster parse( case RESULT_INDEX_FIELD_TTL: customResultIndexTTL = parser.intValue(); break; + case FLATTEN_RESULT_INDEX_MAPPING: + flattenResultIndexMapping = parser.booleanValue(); + break; default: parser.skipChildren(); break; @@ -461,7 +467,8 @@ public static Forecaster parse( historyIntervals, customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); return forecaster; } diff --git a/src/main/java/org/opensearch/forecast/rest/handler/AbstractForecasterActionHandler.java b/src/main/java/org/opensearch/forecast/rest/handler/AbstractForecasterActionHandler.java index 15e30ef76..58033c199 100644 --- a/src/main/java/org/opensearch/forecast/rest/handler/AbstractForecasterActionHandler.java +++ b/src/main/java/org/opensearch/forecast/rest/handler/AbstractForecasterActionHandler.java @@ -257,7 +257,8 @@ protected Config copyConfig(User user, Config config) { config.getHistoryIntervals(), config.getCustomResultIndexMinSize(), config.getCustomResultIndexMinAge(), - config.getCustomResultIndexTTL() + config.getCustomResultIndexTTL(), + config.getFlattenResultIndexMapping() ); } diff --git a/src/main/java/org/opensearch/timeseries/model/Config.java b/src/main/java/org/opensearch/timeseries/model/Config.java index 2da4c3a77..8c0586cde 100644 --- a/src/main/java/org/opensearch/timeseries/model/Config.java +++ b/src/main/java/org/opensearch/timeseries/model/Config.java @@ -79,6 +79,7 @@ public abstract class Config implements Writeable, ToXContentObject { public static final String RESULT_INDEX_FIELD_MIN_SIZE = "result_index_min_size"; public static final String RESULT_INDEX_FIELD_MIN_AGE = "result_index_min_age"; public static final String RESULT_INDEX_FIELD_TTL = "result_index_ttl"; + public static final String FLATTEN_RESULT_INDEX_MAPPING = "flatten_result_index_mapping"; protected String id; protected Long version; @@ -118,6 +119,7 @@ public abstract class Config implements Writeable, ToXContentObject { protected Integer customResultIndexMinSize; protected Integer customResultIndexMinAge; protected Integer customResultIndexTTL; + protected Boolean flattenResultIndexMapping; public static String INVALID_RESULT_INDEX_NAME_SIZE = "Result index name size must contains less than " + MAX_RESULT_INDEX_NAME_SIZE @@ -148,7 +150,8 @@ protected Config( Integer historyIntervals, Integer customResultIndexMinSize, Integer customResultIndexMinAge, - Integer customResultIndexTTL + Integer customResultIndexTTL, + Boolean flattenResultIndexMapping ) { if (Strings.isBlank(name)) { errorMessage = CommonMessages.EMPTY_NAME; @@ -287,6 +290,7 @@ protected Config( this.customResultIndexMinSize = Strings.trimToNull(resultIndex) == null ? null : customResultIndexMinSize; this.customResultIndexMinAge = Strings.trimToNull(resultIndex) == null ? null : customResultIndexMinAge; this.customResultIndexTTL = Strings.trimToNull(resultIndex) == null ? null : customResultIndexTTL; + this.flattenResultIndexMapping = Strings.trimToNull(resultIndex) == null ? null : flattenResultIndexMapping; } public int suggestHistory() { @@ -330,6 +334,7 @@ public Config(StreamInput input) throws IOException { this.customResultIndexMinSize = input.readOptionalInt(); this.customResultIndexMinAge = input.readOptionalInt(); this.customResultIndexTTL = input.readOptionalInt(); + this.flattenResultIndexMapping = input.readOptionalBoolean(); } /* @@ -382,6 +387,7 @@ public void writeTo(StreamOutput output) throws IOException { output.writeOptionalInt(customResultIndexMinSize); output.writeOptionalInt(customResultIndexMinAge); output.writeOptionalInt(customResultIndexTTL); + output.writeOptionalBoolean(flattenResultIndexMapping); } public boolean invalidShingleSizeRange(Integer shingleSizeToTest) { @@ -438,7 +444,8 @@ public boolean equals(Object o) { && Objects.equal(historyIntervals, config.historyIntervals) && Objects.equal(customResultIndexMinSize, config.customResultIndexMinSize) && Objects.equal(customResultIndexMinAge, config.customResultIndexMinAge) - && Objects.equal(customResultIndexTTL, config.customResultIndexTTL); + && Objects.equal(customResultIndexTTL, config.customResultIndexTTL) + && Objects.equal(flattenResultIndexMapping, config.flattenResultIndexMapping); } @Generated @@ -465,7 +472,8 @@ public int hashCode() { historyIntervals, customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); } @@ -514,6 +522,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws if (customResultIndexTTL != null) { builder.field(RESULT_INDEX_FIELD_TTL, customResultIndexTTL); } + if (flattenResultIndexMapping != null) { + builder.field(FLATTEN_RESULT_INDEX_MAPPING, flattenResultIndexMapping); + } return builder; } @@ -722,6 +733,10 @@ public Integer getCustomResultIndexTTL() { return customResultIndexTTL; } + public Boolean getFlattenResultIndexMapping() { + return flattenResultIndexMapping; + } + /** * Identifies redundant feature names. * @@ -774,6 +789,7 @@ public String toString() { .append("customResultIndexMinSize", customResultIndexMinSize) .append("customResultIndexMinAge", customResultIndexMinAge) .append("customResultIndexTTL", customResultIndexTTL) + .append("flattenResultIndexMapping", flattenResultIndexMapping) .toString(); } } diff --git a/src/test/java/org/opensearch/action/admin/indices/mapping/get/IndexAnomalyDetectorActionHandlerTests.java b/src/test/java/org/opensearch/action/admin/indices/mapping/get/IndexAnomalyDetectorActionHandlerTests.java index 97540f7f8..990dfd907 100644 --- a/src/test/java/org/opensearch/action/admin/indices/mapping/get/IndexAnomalyDetectorActionHandlerTests.java +++ b/src/test/java/org/opensearch/action/admin/indices/mapping/get/IndexAnomalyDetectorActionHandlerTests.java @@ -858,7 +858,8 @@ public void doE null, detector.getCustomResultIndexMinSize(), detector.getCustomResultIndexMinAge(), - detector.getCustomResultIndexTTL() + detector.getCustomResultIndexTTL(), + detector.getFlattenResultIndexMapping() ); try { listener.onResponse((Response) TestHelpers.createGetResponse(clone, clone.getId(), CommonName.CONFIG_INDEX)); diff --git a/src/test/java/org/opensearch/ad/AnomalyDetectorRestTestCase.java b/src/test/java/org/opensearch/ad/AnomalyDetectorRestTestCase.java index 5500d28cc..627be0240 100644 --- a/src/test/java/org/opensearch/ad/AnomalyDetectorRestTestCase.java +++ b/src/test/java/org/opensearch/ad/AnomalyDetectorRestTestCase.java @@ -314,7 +314,8 @@ public ToXContentObject[] getConfig(String detectorId, BasicHeader header, boole null, detector.getCustomResultIndexMinSize(), detector.getCustomResultIndexMinAge(), - detector.getCustomResultIndexTTL() + detector.getCustomResultIndexTTL(), + detector.getFlattenResultIndexMapping() ), detectorJob, historicalAdTask, @@ -640,7 +641,8 @@ protected AnomalyDetector cloneDetector(AnomalyDetector anomalyDetector, String null, anomalyDetector.getCustomResultIndexMinSize(), anomalyDetector.getCustomResultIndexMinAge(), - anomalyDetector.getCustomResultIndexTTL() + anomalyDetector.getCustomResultIndexTTL(), + anomalyDetector.getFlattenResultIndexMapping() ); return detector; } diff --git a/src/test/java/org/opensearch/ad/model/AnomalyDetectorTests.java b/src/test/java/org/opensearch/ad/model/AnomalyDetectorTests.java index ec0b174b9..911c94295 100644 --- a/src/test/java/org/opensearch/ad/model/AnomalyDetectorTests.java +++ b/src/test/java/org/opensearch/ad/model/AnomalyDetectorTests.java @@ -343,6 +343,7 @@ public void testInvalidShingleSize() throws Exception { null, null, null, + null, null ) ); @@ -379,6 +380,7 @@ public void testNullDetectorName() throws Exception { null, null, null, + null, null ) ); @@ -415,6 +417,7 @@ public void testBlankDetectorName() throws Exception { null, null, null, + null, null ) ); @@ -451,6 +454,7 @@ public void testNullTimeField() throws Exception { null, null, null, + null, null ) ); @@ -487,6 +491,7 @@ public void testNullIndices() throws Exception { null, null, null, + null, null ) ); @@ -523,6 +528,7 @@ public void testEmptyIndices() throws Exception { null, null, null, + null, null ) ); @@ -559,6 +565,7 @@ public void testNullDetectionInterval() throws Exception { null, null, null, + null, null ) ); @@ -594,6 +601,7 @@ public void testInvalidRecency() { null, null, null, + null, null ) ); @@ -630,6 +638,7 @@ public void testInvalidDetectionInterval() { null, null, null, + null, null ) ); @@ -666,6 +675,7 @@ public void testInvalidWindowDelay() { null, null, null, + null, null ) ); @@ -715,6 +725,7 @@ public void testGetShingleSize() throws IOException { null, null, null, + null, null ); assertEquals((int) anomalyDetector.getShingleSize(), 5); @@ -749,6 +760,7 @@ public void testGetShingleSizeReturnsDefaultValue() throws IOException { null, null, null, + null, null ); // seasonalityIntervals is not null and custom shingle size is null, use seasonalityIntervals to deterine shingle size @@ -779,6 +791,7 @@ public void testGetShingleSizeReturnsDefaultValue() throws IOException { null, null, null, + null, null ); // seasonalityIntervals is null and custom shingle size is null, use default shingle size @@ -811,6 +824,7 @@ public void testNullFeatureAttributes() throws IOException { null, null, null, + null, null ); assertNotNull(anomalyDetector.getFeatureAttributes()); @@ -843,6 +857,7 @@ public void testValidateResultIndex() throws IOException { null, null, null, + null, null ); String errorMessage = anomalyDetector.validateCustomResultIndex("abc"); @@ -931,6 +946,21 @@ public void testParseAnomalyDetector_withCustomIndex_withCustomResultIndexTTL() assertEquals(30, (int) parsedDetector.getCustomResultIndexTTL()); } + public void testParseAnomalyDetector_withCustomIndex_withFlattenResultIndexMapping() throws IOException { + String detectorString = "{\"name\":\"AhtYYGWTgqkzairTchcs\",\"description\":\"iIiAVPMyFgnFlEniLbMyfJxyoGvJAl\"," + + "\"time_field\":\"HmdFH\",\"indices\":[\"ffsBF\"],\"filter_query\":{\"bool\":{\"filter\":[{\"exists\":" + + "{\"field\":\"value\",\"boost\":1}}],\"adjust_pure_negative\":true,\"boost\":1}},\"window_delay\":" + + "{\"period\":{\"interval\":2,\"unit\":\"Minutes\"}},\"shingle_size\":8,\"schema_version\":-512063255," + + "\"feature_attributes\":[{\"feature_id\":\"OTYJs\",\"feature_name\":\"eYYCM\",\"feature_enabled\":false," + + "\"aggregation_query\":{\"XzewX\":{\"value_count\":{\"field\":\"ok\"}}}}],\"recency_emphasis\":3342," + + "\"history\":62,\"last_update_time\":1717192049845,\"category_field\":[\"Tcqcb\"],\"result_index\":" + + "\"opensearch-ad-plugin-result-test\",\"imputation_option\":{\"method\":\"FIXED_VALUES\",\"defaultFill\"" + + ":[],\"integerSensitive\":false},\"suggested_seasonality\":64,\"detection_interval\":{\"period\":" + + "{\"interval\":5,\"unit\":\"Minutes\"}},\"detector_type\":\"MULTI_ENTITY\",\"rules\":[],\"flatten_result_index_mapping\":true}"; + AnomalyDetector parsedDetector = AnomalyDetector.parse(TestHelpers.parser(detectorString), "id", 1L, null, null); + assertEquals(true, (boolean) parsedDetector.getFlattenResultIndexMapping()); + } + public void testSerializeAndDeserializeAnomalyDetector() throws IOException { // register writer and reader for type Feature Writeable.WriteableRegistry.registerWriter(Feature.class, (o, v) -> { @@ -994,6 +1024,7 @@ public void testNullFixedValue() throws IOException { null, null, null, + null, null ) ); diff --git a/src/test/java/org/opensearch/ad/rest/ADRestTestUtils.java b/src/test/java/org/opensearch/ad/rest/ADRestTestUtils.java index 7ffa7170d..0ffe7b5d7 100644 --- a/src/test/java/org/opensearch/ad/rest/ADRestTestUtils.java +++ b/src/test/java/org/opensearch/ad/rest/ADRestTestUtils.java @@ -225,6 +225,7 @@ public static Response createAnomalyDetector( null, null, null, + null, null ); diff --git a/src/test/java/org/opensearch/ad/rest/AnomalyDetectorRestApiIT.java b/src/test/java/org/opensearch/ad/rest/AnomalyDetectorRestApiIT.java index 05b075533..5a95a2cc1 100644 --- a/src/test/java/org/opensearch/ad/rest/AnomalyDetectorRestApiIT.java +++ b/src/test/java/org/opensearch/ad/rest/AnomalyDetectorRestApiIT.java @@ -158,6 +158,7 @@ public void testCreateAnomalyDetectorWithDuplicateName() throws Exception { null, null, null, + null, null ); @@ -269,6 +270,7 @@ public void testUpdateAnomalyDetectorCategoryField() throws Exception { null, null, null, + null, null ); Exception ex = expectThrows( @@ -335,6 +337,7 @@ public void testUpdateAnomalyDetector() throws Exception { null, null, null, + null, null ); @@ -406,6 +409,7 @@ public void testUpdateAnomalyDetectorNameToExisting() throws Exception { null, null, null, + null, null ); @@ -454,6 +458,7 @@ public void testUpdateAnomalyDetectorNameToNew() throws Exception { null, null, null, + null, null ); @@ -508,6 +513,7 @@ public void testUpdateAnomalyDetectorWithNotExistingIndex() throws Exception { null, null, null, + null, null ); @@ -879,6 +885,7 @@ public void testUpdateAnomalyDetectorWithRunningAdJob() throws Exception { null, null, null, + null, null ); diff --git a/src/test/java/org/opensearch/ad/rest/HistoricalAnalysisRestApiIT.java b/src/test/java/org/opensearch/ad/rest/HistoricalAnalysisRestApiIT.java index f428aea16..505ed36b0 100644 --- a/src/test/java/org/opensearch/ad/rest/HistoricalAnalysisRestApiIT.java +++ b/src/test/java/org/opensearch/ad/rest/HistoricalAnalysisRestApiIT.java @@ -348,7 +348,8 @@ private AnomalyDetector randomAnomalyDetector(AnomalyDetector detector) { null, detector.getCustomResultIndexMinSize(), detector.getCustomResultIndexMinAge(), - detector.getCustomResultIndexTTL() + detector.getCustomResultIndexTTL(), + detector.getFlattenResultIndexMapping() ); } diff --git a/src/test/java/org/opensearch/ad/rest/SecureADRestIT.java b/src/test/java/org/opensearch/ad/rest/SecureADRestIT.java index 3f38e8913..d83514ef2 100644 --- a/src/test/java/org/opensearch/ad/rest/SecureADRestIT.java +++ b/src/test/java/org/opensearch/ad/rest/SecureADRestIT.java @@ -303,6 +303,7 @@ public void testUpdateApiFilterByEnabledForAdmin() throws IOException { null, null, null, + null, null ); // User client has admin all access, and has "opensearch" backend role so client should be able to update detector @@ -357,6 +358,7 @@ public void testUpdateApiFilterByEnabled() throws IOException { null, null, null, + null, null ); enableFilterBy(); diff --git a/src/test/java/org/opensearch/ad/transport/AnomalyResultTransportActionTests.java b/src/test/java/org/opensearch/ad/transport/AnomalyResultTransportActionTests.java index b1deb5025..7c8d4f3c2 100644 --- a/src/test/java/org/opensearch/ad/transport/AnomalyResultTransportActionTests.java +++ b/src/test/java/org/opensearch/ad/transport/AnomalyResultTransportActionTests.java @@ -226,6 +226,7 @@ private AnomalyDetector randomDetector(List indices, List featu null, null, null, + null, null ); } @@ -256,6 +257,7 @@ private AnomalyDetector randomHCDetector(List indices, List fea null, null, null, + null, null ); } diff --git a/src/test/java/org/opensearch/ad/transport/ForwardADTaskRequestTests.java b/src/test/java/org/opensearch/ad/transport/ForwardADTaskRequestTests.java index 913fc64c0..266b3b009 100644 --- a/src/test/java/org/opensearch/ad/transport/ForwardADTaskRequestTests.java +++ b/src/test/java/org/opensearch/ad/transport/ForwardADTaskRequestTests.java @@ -85,6 +85,7 @@ public void testNullDetectorIdAndTaskAction() throws IOException { null, null, null, + null, null ); ForwardADTaskRequest request = new ForwardADTaskRequest(detector, null, null, null, null, Version.V_2_1_0); diff --git a/src/test/java/org/opensearch/ad/transport/ValidateAnomalyDetectorTransportActionTests.java b/src/test/java/org/opensearch/ad/transport/ValidateAnomalyDetectorTransportActionTests.java index 494c8580d..53f6f0ab5 100644 --- a/src/test/java/org/opensearch/ad/transport/ValidateAnomalyDetectorTransportActionTests.java +++ b/src/test/java/org/opensearch/ad/transport/ValidateAnomalyDetectorTransportActionTests.java @@ -404,6 +404,7 @@ public void testValidateAnomalyDetectorWithInvalidDetectorName() throws IOExcept null, null, null, + null, null ); ingestTestDataValidate(anomalyDetector.getIndices().get(0), Instant.now().minus(1, ChronoUnit.DAYS), 1, "error"); @@ -452,6 +453,7 @@ public void testValidateAnomalyDetectorWithDetectorNameTooLong() throws IOExcept null, null, null, + null, null ); ingestTestDataValidate(anomalyDetector.getIndices().get(0), Instant.now().minus(1, ChronoUnit.DAYS), 1, "error"); diff --git a/src/test/java/org/opensearch/forecast/model/ForecasterTests.java b/src/test/java/org/opensearch/forecast/model/ForecasterTests.java index dd31136ad..380137345 100644 --- a/src/test/java/org/opensearch/forecast/model/ForecasterTests.java +++ b/src/test/java/org/opensearch/forecast/model/ForecasterTests.java @@ -59,6 +59,7 @@ public class ForecasterTests extends AbstractTimeSeriesTest { Integer customResultIndexMinSize = null; Integer customResultIndexMinAge = null; Integer customResultIndexTTL = null; + Boolean flattenResultIndexMapping = null; public void testForecasterConstructor() { ImputationOption imputationOption = TestHelpers.randomImputationOption(features); @@ -88,7 +89,8 @@ public void testForecasterConstructor() { randomIntBetween(1, 1000), customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); assertEquals(forecasterId, forecaster.getId()); @@ -141,7 +143,8 @@ public void testForecasterConstructorWithNullForecastInterval() { randomIntBetween(1, 1000), customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); }); @@ -179,7 +182,8 @@ public void testNegativeInterval() { randomIntBetween(1, 1000), customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); }); @@ -217,7 +221,8 @@ public void testMaxCategoryFieldsLimits() { randomIntBetween(1, 1000), customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); }); @@ -255,7 +260,8 @@ public void testBlankName() { randomIntBetween(1, 1000), customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); }); @@ -293,7 +299,8 @@ public void testInvalidCustomResultIndex() { randomIntBetween(1, 1000), customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); }); @@ -330,7 +337,8 @@ public void testValidCustomResultIndex() { randomIntBetween(1, 1000), customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); assertEquals(resultIndex, forecaster.getCustomResultIndexOrAlias()); @@ -365,7 +373,8 @@ public void testInvalidHorizon() { randomIntBetween(1, 1000), customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); }); @@ -466,4 +475,22 @@ public void testValidCustomResultIndex_withIndexConditions() throws IOException Forecaster parsedForecaster = Forecaster.parse(TestHelpers.parser(forecasterString)); assertEquals(forecaster, parsedForecaster); } + + public void testParseNullCustomResultIndex_nullFlattenResultIndexMapping() throws IOException { + Forecaster forecaster = TestHelpers.ForecasterBuilder.newInstance().setFlattenResultIndexMapping(null).build(); + String forecasterString = TestHelpers + .xContentBuilderToString(forecaster.toXContent(TestHelpers.builder(), ToXContent.EMPTY_PARAMS)); + LOG.info(forecasterString); + Forecaster parsedForecaster = Forecaster.parse(TestHelpers.parser(forecasterString)); + assertEquals(forecaster, parsedForecaster); + } + + public void testValidCustomResultIndex_withFlattenResultIndexMapping() throws IOException { + Forecaster forecaster = TestHelpers.ForecasterBuilder.newInstance().setFlattenResultIndexMapping(true).build(); + String forecasterString = TestHelpers + .xContentBuilderToString(forecaster.toXContent(TestHelpers.builder(), ToXContent.EMPTY_PARAMS)); + LOG.info(forecasterString); + Forecaster parsedForecaster = Forecaster.parse(TestHelpers.parser(forecasterString)); + assertEquals(forecaster, parsedForecaster); + } } diff --git a/src/test/java/org/opensearch/timeseries/TestHelpers.java b/src/test/java/org/opensearch/timeseries/TestHelpers.java index 99e2c7c64..2c75febc0 100644 --- a/src/test/java/org/opensearch/timeseries/TestHelpers.java +++ b/src/test/java/org/opensearch/timeseries/TestHelpers.java @@ -339,6 +339,7 @@ public static AnomalyDetector randomAnomalyDetector( new ArrayList(), null, null, + null, null ); } @@ -393,6 +394,7 @@ public static AnomalyDetector randomDetector( null, null, null, + null, null ); } @@ -458,6 +460,7 @@ public static AnomalyDetector randomAnomalyDetectorUsingCategoryFields( null, null, null, + null, null ); } @@ -498,6 +501,7 @@ public static AnomalyDetector randomAnomalyDetector(String timefield, String ind null, null, null, + null, null ); } @@ -530,6 +534,7 @@ public static AnomalyDetector randomAnomalyDetectorWithEmptyFeature() throws IOE null, null, null, + null, null ); } @@ -569,6 +574,7 @@ public static AnomalyDetector randomAnomalyDetectorWithInterval(TimeConfiguratio null, null, null, + null, null ); } @@ -746,6 +752,7 @@ public AnomalyDetector build() { null, null, null, + null, null ); } @@ -782,6 +789,7 @@ public static AnomalyDetector randomAnomalyDetectorWithInterval(TimeConfiguratio null, null, null, + null, null ); } @@ -1764,6 +1772,7 @@ public static class ForecasterBuilder { Integer customResultIndexMinSize; Integer customResultIndexMinAge; Integer customResultIndexTTL; + Boolean flattenResultIndexMapping; ForecasterBuilder() throws IOException { forecasterId = randomAlphaOfLength(10); @@ -1788,6 +1797,7 @@ public static class ForecasterBuilder { customResultIndexMinSize = null; customResultIndexMinAge = null; customResultIndexTTL = null; + flattenResultIndexMapping = null; } public static ForecasterBuilder newInstance() throws IOException { @@ -1894,6 +1904,11 @@ public ForecasterBuilder setCustomResultIndexTTL(Integer customResultIndexTTL) { return this; } + public ForecasterBuilder setFlattenResultIndexMapping(Boolean flattenResultIndexMapping) { + this.flattenResultIndexMapping = flattenResultIndexMapping; + return this; + } + public ForecasterBuilder setNullImputationOption() { this.imputationOption = null; return this; @@ -1930,7 +1945,8 @@ public Forecaster build() { randomIntBetween(1, 1000), customResultIndexMinSize, customResultIndexMinAge, - customResultIndexTTL + customResultIndexTTL, + flattenResultIndexMapping ); } } @@ -1963,6 +1979,7 @@ public static Forecaster randomForecaster() throws IOException { randomIntBetween(1, 1000), null, null, + null, null ); }