Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Can't start AD job if detector has no feature #76

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -155,12 +155,15 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
.field(DESCRIPTION_FIELD, description)
.field(TIMEFIELD_FIELD, timeField)
.field(INDICES_FIELD, indices.toArray())
.field(FEATURE_ATTRIBUTES_FIELD, featureAttributes.toArray())
.field(FILTER_QUERY_FIELD, filterQuery)
.field(DETECTION_INTERVAL_FIELD, detectionInterval)
.field(WINDOW_DELAY_FIELD, windowDelay)
.field(SCHEMA_VERSION_FIELD, schemaVersion);

if (featureAttributes != null) {
xContentBuilder.field(FEATURE_ATTRIBUTES_FIELD, featureAttributes.toArray());
}

if (uiMetadata != null && !uiMetadata.isEmpty()) {
xContentBuilder.field(UI_METADATA_FIELD, uiMetadata);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ private void onGetAnomalyDetectorResponse(GetResponse response) throws IOExcepti
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
AnomalyDetector detector = AnomalyDetector.parse(parser, response.getId(), response.getVersion());

if (detector.getFeatureAttributes().size() == 0) {
channel.sendResponse(new BytesRestResponse(RestStatus.BAD_REQUEST, "Can't start detector job as no features configured"));
return;
}

IntervalTimeConfiguration interval = (IntervalTimeConfiguration) detector.getDetectionInterval();
Schedule schedule = new IntervalSchedule(Instant.now(), (int) interval.getInterval(), interval.getUnit());
Duration duration = Duration.of(interval.getInterval(), interval.getUnit());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,19 @@ public static NamedXContentRegistry xContentRegistry() {
}

public static AnomalyDetector randomAnomalyDetector(Map<String, Object> uiMetadata, Instant lastUpdateTime) throws IOException {
return randomAnomalyDetector(ImmutableList.of(randomFeature()), uiMetadata, lastUpdateTime);
}

public static AnomalyDetector randomAnomalyDetector(List<Feature> features, Map<String, Object> uiMetadata, Instant lastUpdateTime)
throws IOException {
return new AnomalyDetector(
randomAlphaOfLength(10),
randomLong(),
randomAlphaOfLength(20),
randomAlphaOfLength(30),
randomAlphaOfLength(5),
ImmutableList.of(randomAlphaOfLength(10).toLowerCase()),
ImmutableList.of(randomFeature()),
features,
randomQuery(),
randomIntervalTimeConfiguration(),
randomIntervalTimeConfiguration(),
Expand Down Expand Up @@ -344,4 +349,16 @@ public static ThreadPool createThreadPool() {
when(pool.getThreadContext()).thenReturn(createThreadContext());
return pool;
}

public static void createIndex(RestClient client, String indexName, HttpEntity data) throws IOException {
TestHelpers
.makeRequest(
client,
"POST",
"/" + indexName + "/_doc/" + randomAlphaOfLength(5) + "?refresh=true",
ImmutableMap.of(),
data,
null
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import java.io.IOException;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Locale;

public class AnomalyDetectorTests extends ESTestCase {
Expand Down Expand Up @@ -234,4 +235,19 @@ public void testNullDetectionInterval() throws Exception {
)
);
}

public void testNullFeatures() throws IOException {
AnomalyDetector detector = TestHelpers.randomAnomalyDetector(null, null, Instant.now().truncatedTo(ChronoUnit.SECONDS));
String detectorString = TestHelpers.xContentBuilderToString(detector.toXContent(TestHelpers.builder(), ToXContent.EMPTY_PARAMS));
AnomalyDetector parsedDetector = AnomalyDetector.parse(TestHelpers.parser(detectorString));
assertEquals(0, parsedDetector.getFeatureAttributes().size());
}

public void testEmptyFeatures() throws IOException {
AnomalyDetector detector = TestHelpers
.randomAnomalyDetector(ImmutableList.of(), null, Instant.now().truncatedTo(ChronoUnit.SECONDS));
String detectorString = TestHelpers.xContentBuilderToString(detector.toXContent(TestHelpers.builder(), ToXContent.EMPTY_PARAMS));
AnomalyDetector parsedDetector = AnomalyDetector.parse(TestHelpers.parser(detectorString));
assertEquals(0, parsedDetector.getFeatureAttributes().size());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.amazon.opendistroforelasticsearch.ad.model.AnomalyDetectorExecutionInput;
import com.amazon.opendistroforelasticsearch.ad.model.AnomalyDetectorJob;
import com.amazon.opendistroforelasticsearch.ad.model.AnomalyResult;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.NStringEntity;
Expand Down Expand Up @@ -75,15 +76,7 @@ public void testCreateAnomalyDetectorWithEmptyIndices() throws Exception {
public void testCreateAnomalyDetector() throws IOException {
AnomalyDetector detector = TestHelpers.randomAnomalyDetector(TestHelpers.randomUiMetadata(), null);
String indexName = detector.getIndices().get(0);
TestHelpers
.makeRequest(
client(),
"POST",
"/" + indexName + "/_doc/" + randomAlphaOfLength(5) + "?refresh=true",
ImmutableMap.of(),
toHttpEntity("{\"name\": \"test\"}"),
null
);
TestHelpers.createIndex(client(), indexName, toHttpEntity("{\"name\": \"test\"}"));

Response response = TestHelpers
.makeRequest(client(), "POST", TestHelpers.AD_BASE_DETECTORS_URI, ImmutableMap.of(), toHttpEntity(detector), null);
Expand Down Expand Up @@ -615,4 +608,45 @@ public void testStartDisabledAdjob() throws IOException {
assertEquals("Fail to start AD job", RestStatus.OK, restStatus(startAdJobResponse));
}

public void testStartAdjobWithNullFeatures() throws Exception {
AnomalyDetector detectorWithoutFeature = TestHelpers.randomAnomalyDetector(null, null, Instant.now());
String indexName = detectorWithoutFeature.getIndices().get(0);
TestHelpers.createIndex(client(), indexName, toHttpEntity("{\"name\": \"test\"}"));
AnomalyDetector detector = createAnomalyDetector(detectorWithoutFeature, true);
TestHelpers
.assertFailWith(
ResponseException.class,
"Can't start detector job as no features configured",
() -> TestHelpers
.makeRequest(
client(),
"POST",
TestHelpers.AD_BASE_DETECTORS_URI + "/" + detector.getDetectorId() + "/_start",
ImmutableMap.of(),
"",
null
)
);
}

public void testStartAdjobWithEmptyFeatures() throws Exception {
AnomalyDetector detectorWithoutFeature = TestHelpers.randomAnomalyDetector(ImmutableList.of(), null, Instant.now());
String indexName = detectorWithoutFeature.getIndices().get(0);
TestHelpers.createIndex(client(), indexName, toHttpEntity("{\"name\": \"test\"}"));
AnomalyDetector detector = createAnomalyDetector(detectorWithoutFeature, true);
TestHelpers
.assertFailWith(
ResponseException.class,
"Can't start detector job as no features configured",
() -> TestHelpers
.makeRequest(
client(),
"POST",
TestHelpers.AD_BASE_DETECTORS_URI + "/" + detector.getDetectorId() + "/_start",
ImmutableMap.of(),
"",
null
)
);
}
}