Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a feature that flattens custom result index when enabled #1401

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ public class ADIndexManagement extends IndexManagement<ADIndex> {
// The index name pattern to query all AD result, history and current AD result
public static final String ALL_AD_RESULTS_INDEX_PATTERN = ".opendistro-anomaly-results*";

// private static final ObjectMapper objectMapper = new ObjectMapper();

/**
* Constructor function
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ public static AnomalyDetector parse(
case RESULT_INDEX_FIELD_TTL:
customResultIndexTTL = onlyParseNumberValue(parser);
break;
case FLATTEN_RESULT_INDEX_MAPPING:
case FLATTEN_CUSTOM_RESULT_INDEX:
flattenResultIndexMapping = onlyParseBooleanValue(parser);
break;
case BREAKING_UI_CHANGE_TIME:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ public static Forecaster parse(
case RESULT_INDEX_FIELD_TTL:
customResultIndexTTL = parser.intValue();
break;
case FLATTEN_RESULT_INDEX_MAPPING:
case FLATTEN_CUSTOM_RESULT_INDEX:
flattenResultIndexMapping = parser.booleanValue();
break;
case BREAKING_UI_CHANGE_TIME:
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/org/opensearch/timeseries/model/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +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_custom_result_index";
public static final String FLATTEN_CUSTOM_RESULT_INDEX = "flatten_custom_result_index";
// Changing categorical field, feature attributes, interval, windowDelay, time field, horizon, indices,
// result index would force us to display results only from the most recent update. Otherwise,
// the UI appear cluttered and unclear.
Expand Down Expand Up @@ -533,7 +533,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.field(RESULT_INDEX_FIELD_TTL, customResultIndexTTL);
}
if (flattenResultIndexMapping != null) {
builder.field(FLATTEN_RESULT_INDEX_MAPPING, flattenResultIndexMapping);
builder.field(FLATTEN_CUSTOM_RESULT_INDEX, flattenResultIndexMapping);
}
if (lastUIBreakingChangeTime != null) {
builder.field(BREAKING_UI_CHANGE_TIME, lastUIBreakingChangeTime.toEpochMilli());
Expand Down Expand Up @@ -746,8 +746,8 @@ public Integer getCustomResultIndexTTL() {
return customResultIndexTTL;
}

public Boolean getFlattenResultIndexMapping() {
return flattenResultIndexMapping;
public boolean getFlattenResultIndexMapping() {
return flattenResultIndexMapping != null ? flattenResultIndexMapping : false;
}

public Instant getLastBreakingUIChangeTime() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ private BytesReference createPipelineDefinition(String indexName) throws IOExcep
XContentBuilder pipelineBuilder = XContentFactory.jsonBuilder();
pipelineBuilder.startObject();
{
pipelineBuilder.field("description", "Ingest pipeline for anomaly detector with result index: " + indexName);
pipelineBuilder.field("description", "Ingest pipeline for flattening result index: " + indexName);
pipelineBuilder.startArray("processors");
{
pipelineBuilder.startObject();
Expand Down Expand Up @@ -578,8 +578,8 @@ private void handleFlattenResultIndexMappingUpdate(Config existingConfig, Action
if (config.getCustomResultIndexOrAlias() == null) {
return;
}
if (Boolean.TRUE.equals(existingConfig.getFlattenResultIndexMapping())
&& Boolean.FALSE.equals(config.getFlattenResultIndexMapping())
if (existingConfig.getFlattenResultIndexMapping()
&& !config.getFlattenResultIndexMapping()
&& existingConfig.getCustomResultIndexOrAlias() != null) {
String pipelineId = timeSeriesIndices.getFlattenResultIndexIngestPipelineId(config.getId());
client.admin().cluster().deletePipeline(new DeletePipelineRequest(pipelineId), new ActionListener<AcknowledgedResponse>() {
Expand Down Expand Up @@ -611,8 +611,8 @@ public void onFailure(Exception e) {
}
}
});
} else if (Boolean.FALSE.equals(existingConfig.getFlattenResultIndexMapping())
&& Boolean.TRUE.equals(config.getFlattenResultIndexMapping())
} else if (!existingConfig.getFlattenResultIndexMapping()
&& config.getFlattenResultIndexMapping()
&& existingConfig.getCustomResultIndexOrAlias() != null) {
listener.onFailure(new OpenSearchStatusException(CommonMessages.CAN_NOT_CHANGE_FLATTEN_RESULT_INDEX, RestStatus.BAD_REQUEST));
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,71 @@ public void testUpdateAnomalyDetector_disableFlattenResultIndex_shouldDeletePipe
assertEquals("Expected 404 response but got: " + statusCode, 404, statusCode);
}

public void testUpdateAnomalyDetectorFlattenResultIndexField() throws Exception {
TestHelpers.createIndexWithTimeField(client(), INDEX_NAME, TIME_FIELD, false);
String testIndexData = "{\"keyword-field\": \"field-1\", \"ip-field\": \"1.2.3.4\", \"timestamp\": 1}";
TestHelpers.ingestDataToIndex(client(), INDEX_NAME, TestHelpers.toHttpEntity(testIndexData));
AnomalyDetector detector = TestHelpers
.randomDetector(
ImmutableList.of(TestHelpers.randomFeature("feature_bytes", "agg", true)),
INDEX_NAME,
5,
TIME_FIELD,
null,
ADCommonName.CUSTOM_RESULT_INDEX_PREFIX + "test"
);
Response response = TestHelpers
.makeRequest(client(), "POST", TestHelpers.AD_BASE_DETECTORS_URI, ImmutableMap.of(), TestHelpers.toHttpEntity(detector), null);
assertEquals("Create anomaly detector failed", RestStatus.CREATED, TestHelpers.restStatus(response));
Map<String, Object> responseMap = entityAsMap(response);
String id = (String) responseMap.get("_id");
List<Feature> features = detector.getFeatureAttributes();
long expectedFeatures = features.stream().filter(Feature::getEnabled).count();
AnomalyDetector newDetector = new AnomalyDetector(
id,
null,
detector.getName(),
detector.getDescription(),
detector.getTimeField(),
detector.getIndices(),
features,
detector.getFilterQuery(),
detector.getInterval(),
detector.getWindowDelay(),
detector.getShingleSize(),
detector.getUiMetadata(),
detector.getSchemaVersion(),
detector.getLastUpdateTime(),
detector.getCategoryFields(),
detector.getUser(),
detector.getCustomResultIndexOrAlias(),
TestHelpers.randomImputationOption(features),
randomIntBetween(1, 10000),
randomInt(TimeSeriesSettings.MAX_SHINGLE_SIZE / 2),
randomIntBetween(1, 1000),
detector.getRules(),
null,
null,
null,
true,
detector.getLastBreakingUIChangeTime()
);

Exception ex = expectThrows(
ResponseException.class,
() -> TestHelpers
.makeRequest(
client(),
"PUT",
TestHelpers.AD_BASE_DETECTORS_URI + "/" + id + "?refresh=true",
ImmutableMap.of(),
TestHelpers.toHttpEntity(newDetector),
null
)
);
assertThat(ex.getMessage(), containsString(CommonMessages.CAN_NOT_CHANGE_FLATTEN_RESULT_INDEX));
}

public void testCreateAnomalyDetector() throws Exception {
AnomalyDetector detector = createIndexAndGetAnomalyDetector(INDEX_NAME);
updateClusterSettings(ADEnabledSetting.AD_ENABLED, false);
Expand Down
Loading