diff --git a/src/main/java/org/opensearch/securityanalytics/transport/TransportGetAlertsAction.java b/src/main/java/org/opensearch/securityanalytics/transport/TransportGetAlertsAction.java index 454eb09d4..4598e89c5 100644 --- a/src/main/java/org/opensearch/securityanalytics/transport/TransportGetAlertsAction.java +++ b/src/main/java/org/opensearch/securityanalytics/transport/TransportGetAlertsAction.java @@ -10,6 +10,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.lucene.search.join.ScoreMode; +import org.opensearch.OpenSearchStatusException; import org.opensearch.action.ActionListener; import org.opensearch.action.search.SearchRequest; import org.opensearch.action.search.SearchResponse; @@ -20,6 +21,7 @@ import org.opensearch.common.xcontent.NamedXContentRegistry; import org.opensearch.index.query.NestedQueryBuilder; import org.opensearch.index.query.QueryBuilders; +import org.opensearch.rest.RestStatus; import org.opensearch.search.builder.SearchSourceBuilder; import org.opensearch.securityanalytics.action.GetAlertsAction; import org.opensearch.securityanalytics.action.GetAlertsRequest; @@ -28,6 +30,7 @@ import org.opensearch.securityanalytics.alerts.AlertsService; import org.opensearch.securityanalytics.model.Detector; import org.opensearch.securityanalytics.util.DetectorUtils; +import org.opensearch.securityanalytics.util.SecurityAnalyticsException; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportService; @@ -87,6 +90,16 @@ protected void doExecute(Task task, GetAlertsRequest request, ActionListener detectors = DetectorUtils.getDetectors(searchResponse, xContentRegistry); + if (detectors.size() == 0) { + actionListener.onFailure( + SecurityAnalyticsException.wrap( + new OpenSearchStatusException( + "No detectors found for provided type", RestStatus.NOT_FOUND + ) + ) + ); + return; + } alertsService.getAlerts( detectors, request.getDetectorType(), diff --git a/src/main/java/org/opensearch/securityanalytics/transport/TransportGetFindingsAction.java b/src/main/java/org/opensearch/securityanalytics/transport/TransportGetFindingsAction.java index f279e4397..ac7b6e8ab 100644 --- a/src/main/java/org/opensearch/securityanalytics/transport/TransportGetFindingsAction.java +++ b/src/main/java/org/opensearch/securityanalytics/transport/TransportGetFindingsAction.java @@ -35,6 +35,7 @@ import org.opensearch.securityanalytics.settings.SecurityAnalyticsSettings; import org.opensearch.securityanalytics.util.DetectorIndices; import org.opensearch.securityanalytics.util.DetectorUtils; +import org.opensearch.securityanalytics.util.SecurityAnalyticsException; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; @@ -119,6 +120,16 @@ protected void doExecute(Task task, GetFindingsRequest request, ActionListener detectors = DetectorUtils.getDetectors(searchResponse, xContentRegistry); + if (detectors.size() == 0) { + actionListener.onFailure( + SecurityAnalyticsException.wrap( + new OpenSearchStatusException( + "No detectors found for provided type", RestStatus.NOT_FOUND + ) + ) + ); + return; + } findingsService.getFindings( detectors, request.getDetectorType(), diff --git a/src/main/java/org/opensearch/securityanalytics/transport/TransportGetIndexMappingsAction.java b/src/main/java/org/opensearch/securityanalytics/transport/TransportGetIndexMappingsAction.java index e3857a74a..b638e87b5 100644 --- a/src/main/java/org/opensearch/securityanalytics/transport/TransportGetIndexMappingsAction.java +++ b/src/main/java/org/opensearch/securityanalytics/transport/TransportGetIndexMappingsAction.java @@ -4,16 +4,19 @@ */ package org.opensearch.securityanalytics.transport; +import org.opensearch.OpenSearchStatusException; import org.opensearch.action.ActionListener; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; import org.opensearch.cluster.metadata.IndexMetadata; import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.inject.Inject; +import org.opensearch.rest.RestStatus; import org.opensearch.securityanalytics.action.GetIndexMappingsAction; import org.opensearch.securityanalytics.mapper.MapperService; import org.opensearch.securityanalytics.action.GetIndexMappingsRequest; import org.opensearch.securityanalytics.action.GetIndexMappingsResponse; +import org.opensearch.securityanalytics.util.SecurityAnalyticsException; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; @@ -44,7 +47,13 @@ protected void doExecute(Task task, GetIndexMappingsRequest request, ActionListe this.threadPool.getThreadContext().stashContext(); IndexMetadata index = clusterService.state().metadata().index(request.getIndexName()); if (index == null) { - actionListener.onFailure(new IllegalStateException("Could not find index [" + request.getIndexName() + "]")); + actionListener.onFailure( + SecurityAnalyticsException.wrap( + new OpenSearchStatusException( + "Could not find index [" + request.getIndexName() + "]", RestStatus.NOT_FOUND + ) + ) + ); return; } mapperService.getMappingAction(request.getIndexName(), actionListener); diff --git a/src/main/java/org/opensearch/securityanalytics/transport/TransportGetMappingsViewAction.java b/src/main/java/org/opensearch/securityanalytics/transport/TransportGetMappingsViewAction.java index 9a0bfa16b..2ec636d4e 100644 --- a/src/main/java/org/opensearch/securityanalytics/transport/TransportGetMappingsViewAction.java +++ b/src/main/java/org/opensearch/securityanalytics/transport/TransportGetMappingsViewAction.java @@ -4,12 +4,14 @@ */ package org.opensearch.securityanalytics.transport; +import org.opensearch.OpenSearchStatusException; import org.opensearch.action.ActionListener; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; import org.opensearch.cluster.metadata.IndexMetadata; import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.inject.Inject; +import org.opensearch.rest.RestStatus; import org.opensearch.securityanalytics.action.GetIndexMappingsAction; import org.opensearch.securityanalytics.action.GetIndexMappingsRequest; import org.opensearch.securityanalytics.action.GetIndexMappingsResponse; @@ -17,6 +19,7 @@ import org.opensearch.securityanalytics.action.GetMappingsViewRequest; import org.opensearch.securityanalytics.action.GetMappingsViewResponse; import org.opensearch.securityanalytics.mapper.MapperService; +import org.opensearch.securityanalytics.util.SecurityAnalyticsException; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; @@ -46,7 +49,13 @@ protected void doExecute(Task task, GetMappingsViewRequest request, ActionListen this.threadPool.getThreadContext().stashContext(); IndexMetadata index = clusterService.state().metadata().index(request.getIndexName()); if (index == null) { - actionListener.onFailure(new IllegalStateException("Could not find index [" + request.getIndexName() + "]")); + actionListener.onFailure( + SecurityAnalyticsException.wrap( + new OpenSearchStatusException( + "Could not find index [" + request.getIndexName() + "]", RestStatus.NOT_FOUND + ) + ) + ); return; } mapperService.getMappingsViewAction(request.getIndexName(), request.getRuleTopic(), actionListener); diff --git a/src/main/java/org/opensearch/securityanalytics/transport/TransportUpdateIndexMappingsAction.java b/src/main/java/org/opensearch/securityanalytics/transport/TransportUpdateIndexMappingsAction.java index 08dad2c5d..3717e24b2 100644 --- a/src/main/java/org/opensearch/securityanalytics/transport/TransportUpdateIndexMappingsAction.java +++ b/src/main/java/org/opensearch/securityanalytics/transport/TransportUpdateIndexMappingsAction.java @@ -4,6 +4,7 @@ */ package org.opensearch.securityanalytics.transport; +import org.opensearch.OpenSearchStatusException; import org.opensearch.action.ActionListener; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; @@ -11,9 +12,11 @@ import org.opensearch.cluster.metadata.IndexMetadata; import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.inject.Inject; +import org.opensearch.rest.RestStatus; import org.opensearch.securityanalytics.action.UpdateIndexMappingsAction; import org.opensearch.securityanalytics.mapper.MapperService; import org.opensearch.securityanalytics.action.UpdateIndexMappingsRequest; +import org.opensearch.securityanalytics.util.SecurityAnalyticsException; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; @@ -48,7 +51,13 @@ protected void doExecute(Task task, UpdateIndexMappingsRequest request, ActionLi try { IndexMetadata index = clusterService.state().metadata().index(request.getIndexName()); if (index == null) { - actionListener.onFailure(new IllegalStateException("Could not find index [" + request.getIndexName() + "]")); + actionListener.onFailure( + SecurityAnalyticsException.wrap( + new OpenSearchStatusException( + "Could not find index [" + request.getIndexName() + "]", RestStatus.NOT_FOUND + ) + ) + ); return; } mapperService.updateMappingAction( diff --git a/src/main/java/org/opensearch/securityanalytics/transport/TransportValidateRulesAction.java b/src/main/java/org/opensearch/securityanalytics/transport/TransportValidateRulesAction.java index 9290d8ed9..9ce59a088 100644 --- a/src/main/java/org/opensearch/securityanalytics/transport/TransportValidateRulesAction.java +++ b/src/main/java/org/opensearch/securityanalytics/transport/TransportValidateRulesAction.java @@ -5,24 +5,22 @@ package org.opensearch.securityanalytics.transport; import java.util.List; +import org.opensearch.OpenSearchStatusException; import org.opensearch.action.ActionListener; import org.opensearch.action.StepListener; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; -import org.opensearch.action.support.master.AcknowledgedResponse; import org.opensearch.client.Client; import org.opensearch.cluster.metadata.IndexMetadata; import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.inject.Inject; import org.opensearch.common.xcontent.NamedXContentRegistry; -import org.opensearch.securityanalytics.action.CreateIndexMappingsAction; -import org.opensearch.securityanalytics.action.CreateIndexMappingsRequest; +import org.opensearch.rest.RestStatus; import org.opensearch.securityanalytics.action.ValidateRulesAction; import org.opensearch.securityanalytics.action.ValidateRulesRequest; import org.opensearch.securityanalytics.action.ValidateRulesResponse; -import org.opensearch.securityanalytics.mapper.MapperService; -import org.opensearch.securityanalytics.util.RuleIndices; import org.opensearch.securityanalytics.util.RuleValidator; +import org.opensearch.securityanalytics.util.SecurityAnalyticsException; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportService; @@ -48,7 +46,13 @@ public TransportValidateRulesAction( protected void doExecute(Task task, ValidateRulesRequest request, ActionListener actionListener) { IndexMetadata index = clusterService.state().metadata().index(request.getIndexName()); if (index == null) { - actionListener.onFailure(new IllegalStateException("Could not find index [" + request.getIndexName() + "]")); + actionListener.onFailure( + SecurityAnalyticsException.wrap( + new OpenSearchStatusException( + "Could not find index [" + request.getIndexName() + "]", RestStatus.NOT_FOUND + ) + ) + ); return; } StepListener> validateRulesResponseListener = new StepListener(); diff --git a/src/test/java/org/opensearch/securityanalytics/alerts/AlertsIT.java b/src/test/java/org/opensearch/securityanalytics/alerts/AlertsIT.java index e565674e8..c8bf77a78 100644 --- a/src/test/java/org/opensearch/securityanalytics/alerts/AlertsIT.java +++ b/src/test/java/org/opensearch/securityanalytics/alerts/AlertsIT.java @@ -19,6 +19,7 @@ import org.junit.Assert; import org.opensearch.client.Request; import org.opensearch.client.Response; +import org.opensearch.client.ResponseException; import org.opensearch.commons.alerting.model.action.Action; import org.opensearch.rest.RestStatus; import org.opensearch.search.SearchHit; @@ -164,6 +165,16 @@ public void testGetAlerts_success() throws IOException { assertEquals(((ArrayList) ackAlertsResponseMap.get("acknowledged")).size(), 1); } + public void testGetAlerts_noDetector_failure() throws IOException { + // Call GetAlerts API + Map params = new HashMap<>(); + params.put("detector_id", "nonexistent_detector_id"); + try { + makeRequest(client(), "GET", SecurityAnalyticsPlugin.ALERTS_BASE_URI, params, null); + } catch (ResponseException e) { + assertEquals(HttpStatus.SC_NOT_FOUND, e.getResponse().getStatusLine().getStatusCode()); + } + } @SuppressWarnings("unchecked") public void testAckAlerts_WithInvalidDetectorAlertsCombination() throws IOException { diff --git a/src/test/java/org/opensearch/securityanalytics/findings/FindingIT.java b/src/test/java/org/opensearch/securityanalytics/findings/FindingIT.java index 3f542edb1..7d0e1792a 100644 --- a/src/test/java/org/opensearch/securityanalytics/findings/FindingIT.java +++ b/src/test/java/org/opensearch/securityanalytics/findings/FindingIT.java @@ -15,6 +15,7 @@ import org.junit.Assert; import org.opensearch.client.Request; import org.opensearch.client.Response; +import org.opensearch.client.ResponseException; import org.opensearch.rest.RestStatus; import org.opensearch.search.SearchHit; import org.opensearch.securityanalytics.SecurityAnalyticsPlugin; @@ -90,6 +91,16 @@ public void testGetFindings_byDetectorId_success() throws IOException { Assert.assertEquals(1, getFindingsBody.get("total_findings")); } + public void testGetFindings_noDetector_failure() throws IOException { + Map params = new HashMap<>(); + params.put("detector_id", "nonexistent_id"); + try { + makeRequest(client(), "GET", SecurityAnalyticsPlugin.FINDINGS_BASE_URI + "/_search", params, null); + } catch (ResponseException e) { + assertEquals(HttpStatus.SC_NOT_FOUND, e.getResponse().getStatusLine().getStatusCode()); + } + } + public void testGetFindings_byDetectorType_oneDetector_success() throws IOException { String index = createTestIndex(randomIndex(), windowsIndexMapping()); diff --git a/src/test/java/org/opensearch/securityanalytics/resthandler/DetectorRestApiIT.java b/src/test/java/org/opensearch/securityanalytics/resthandler/DetectorRestApiIT.java index a582970e3..5f03ab958 100644 --- a/src/test/java/org/opensearch/securityanalytics/resthandler/DetectorRestApiIT.java +++ b/src/test/java/org/opensearch/securityanalytics/resthandler/DetectorRestApiIT.java @@ -33,6 +33,7 @@ import java.util.Locale; import java.util.Map; import java.util.stream.Collectors; +import org.opensearch.securityanalytics.model.DetectorTrigger; import org.opensearch.securityanalytics.model.Rule; import static org.opensearch.securityanalytics.TestHelpers.productIndexMaxAggRule; @@ -41,6 +42,7 @@ import static org.opensearch.securityanalytics.TestHelpers.randomDetector; import static org.opensearch.securityanalytics.TestHelpers.randomDetectorType; import static org.opensearch.securityanalytics.TestHelpers.randomDetectorWithInputs; +import static org.opensearch.securityanalytics.TestHelpers.randomDetectorWithTriggers; import static org.opensearch.securityanalytics.TestHelpers.randomDoc; import static org.opensearch.securityanalytics.TestHelpers.randomIndex; import static org.opensearch.securityanalytics.TestHelpers.randomProductDocument; @@ -67,7 +69,7 @@ public void testCreatingADetector() throws IOException { Response response = client().performRequest(createMappingRequest); assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); - Detector detector = randomDetector(getRandomPrePackagedRules()); + Detector detector = randomDetectorWithTriggers(getRandomPrePackagedRules(), List.of(new DetectorTrigger(null, "test-trigger", "1", List.of(randomDetectorType()), List.of(), List.of(), List.of(), List.of()))); Response createResponse = makeRequest(client(), "POST", SecurityAnalyticsPlugin.DETECTOR_BASE_URI, Collections.emptyMap(), toHttpEntity(detector)); Assert.assertEquals("Create detector failed", RestStatus.CREATED, restStatus(createResponse));