diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index a27042d9b8f..75f959902d4 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -44644,6 +44644,11 @@ components: targets. example: service:my-service type: string + keep_unmatched: + description: Whether to keep an event that does not match any of the mapping + filters. + example: false + type: boolean mappings: description: A list of mapping rules to convert events to the OCSF format. items: diff --git a/examples/v2/observability-pipelines/ValidatePipeline_3067748504.java b/examples/v2/observability-pipelines/ValidatePipeline_3067748504.java new file mode 100644 index 00000000000..9620d96856e --- /dev/null +++ b/examples/v2/observability-pipelines/ValidatePipeline_3067748504.java @@ -0,0 +1,101 @@ +// Validate an observability pipeline with OCSF mapper keep_unmatched returns "OK" response + +import com.datadog.api.client.ApiClient; +import com.datadog.api.client.ApiException; +import com.datadog.api.client.v2.api.ObservabilityPipelinesApi; +import com.datadog.api.client.v2.model.ObservabilityPipelineConfig; +import com.datadog.api.client.v2.model.ObservabilityPipelineConfigDestinationItem; +import com.datadog.api.client.v2.model.ObservabilityPipelineConfigProcessorGroup; +import com.datadog.api.client.v2.model.ObservabilityPipelineConfigProcessorItem; +import com.datadog.api.client.v2.model.ObservabilityPipelineConfigSourceItem; +import com.datadog.api.client.v2.model.ObservabilityPipelineDataAttributes; +import com.datadog.api.client.v2.model.ObservabilityPipelineDatadogAgentSource; +import com.datadog.api.client.v2.model.ObservabilityPipelineDatadogAgentSourceType; +import com.datadog.api.client.v2.model.ObservabilityPipelineDatadogLogsDestination; +import com.datadog.api.client.v2.model.ObservabilityPipelineDatadogLogsDestinationType; +import com.datadog.api.client.v2.model.ObservabilityPipelineOcsfMapperProcessor; +import com.datadog.api.client.v2.model.ObservabilityPipelineOcsfMapperProcessorMapping; +import com.datadog.api.client.v2.model.ObservabilityPipelineOcsfMapperProcessorMappingMapping; +import com.datadog.api.client.v2.model.ObservabilityPipelineOcsfMapperProcessorType; +import com.datadog.api.client.v2.model.ObservabilityPipelineOcsfMappingLibrary; +import com.datadog.api.client.v2.model.ObservabilityPipelineSpec; +import com.datadog.api.client.v2.model.ObservabilityPipelineSpecData; +import com.datadog.api.client.v2.model.ValidationResponse; +import java.util.Collections; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = ApiClient.getDefaultApiClient(); + ObservabilityPipelinesApi apiInstance = new ObservabilityPipelinesApi(defaultClient); + + ObservabilityPipelineSpec body = + new ObservabilityPipelineSpec() + .data( + new ObservabilityPipelineSpecData() + .attributes( + new ObservabilityPipelineDataAttributes() + .config( + new ObservabilityPipelineConfig() + .destinations( + Collections.singletonList( + new ObservabilityPipelineConfigDestinationItem( + new ObservabilityPipelineDatadogLogsDestination() + .id("datadog-logs-destination") + .inputs( + Collections.singletonList( + "my-processor-group")) + .type( + ObservabilityPipelineDatadogLogsDestinationType + .DATADOG_LOGS)))) + .processorGroups( + Collections.singletonList( + new ObservabilityPipelineConfigProcessorGroup() + .enabled(true) + .id("my-processor-group") + .include("service:my-service") + .inputs( + Collections.singletonList( + "datadog-agent-source")) + .processors( + Collections.singletonList( + new ObservabilityPipelineConfigProcessorItem( + new ObservabilityPipelineOcsfMapperProcessor() + .enabled(true) + .id("ocsf-mapper-processor") + .include("service:my-service") + .type( + ObservabilityPipelineOcsfMapperProcessorType + .OCSF_MAPPER) + .keepUnmatched(true) + .mappings( + Collections.singletonList( + new ObservabilityPipelineOcsfMapperProcessorMapping() + .include( + "source:cloudtrail") + .mapping( + new ObservabilityPipelineOcsfMapperProcessorMappingMapping( + ObservabilityPipelineOcsfMappingLibrary + .CLOUDTRAIL_ACCOUNT_CHANGE))))))))) + .sources( + Collections.singletonList( + new ObservabilityPipelineConfigSourceItem( + new ObservabilityPipelineDatadogAgentSource() + .id("datadog-agent-source") + .type( + ObservabilityPipelineDatadogAgentSourceType + .DATADOG_AGENT))))) + .name("OCSF Mapper Keep Unmatched Pipeline")) + .type("pipelines")); + + try { + ValidationResponse result = apiInstance.validatePipeline(body); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling ObservabilityPipelinesApi#validatePipeline"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineOcsfMapperProcessor.java b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineOcsfMapperProcessor.java index f6531a37b07..d63e8254590 100644 --- a/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineOcsfMapperProcessor.java +++ b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineOcsfMapperProcessor.java @@ -30,6 +30,7 @@ ObservabilityPipelineOcsfMapperProcessor.JSON_PROPERTY_ENABLED, ObservabilityPipelineOcsfMapperProcessor.JSON_PROPERTY_ID, ObservabilityPipelineOcsfMapperProcessor.JSON_PROPERTY_INCLUDE, + ObservabilityPipelineOcsfMapperProcessor.JSON_PROPERTY_KEEP_UNMATCHED, ObservabilityPipelineOcsfMapperProcessor.JSON_PROPERTY_MAPPINGS, ObservabilityPipelineOcsfMapperProcessor.JSON_PROPERTY_TYPE }) @@ -49,6 +50,9 @@ public class ObservabilityPipelineOcsfMapperProcessor { public static final String JSON_PROPERTY_INCLUDE = "include"; private String include; + public static final String JSON_PROPERTY_KEEP_UNMATCHED = "keep_unmatched"; + private Boolean keepUnmatched; + public static final String JSON_PROPERTY_MAPPINGS = "mappings"; private List mappings = new ArrayList<>(); @@ -157,6 +161,27 @@ public void setInclude(String include) { this.include = include; } + public ObservabilityPipelineOcsfMapperProcessor keepUnmatched(Boolean keepUnmatched) { + this.keepUnmatched = keepUnmatched; + return this; + } + + /** + * Whether to keep an event that does not match any of the mapping filters. + * + * @return keepUnmatched + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_KEEP_UNMATCHED) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Boolean getKeepUnmatched() { + return keepUnmatched; + } + + public void setKeepUnmatched(Boolean keepUnmatched) { + this.keepUnmatched = keepUnmatched; + } + public ObservabilityPipelineOcsfMapperProcessor mappings( List mappings) { this.mappings = mappings; @@ -274,6 +299,8 @@ public boolean equals(Object o) { && Objects.equals(this.enabled, observabilityPipelineOcsfMapperProcessor.enabled) && Objects.equals(this.id, observabilityPipelineOcsfMapperProcessor.id) && Objects.equals(this.include, observabilityPipelineOcsfMapperProcessor.include) + && Objects.equals( + this.keepUnmatched, observabilityPipelineOcsfMapperProcessor.keepUnmatched) && Objects.equals(this.mappings, observabilityPipelineOcsfMapperProcessor.mappings) && Objects.equals(this.type, observabilityPipelineOcsfMapperProcessor.type) && Objects.equals( @@ -283,7 +310,8 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(displayName, enabled, id, include, mappings, type, additionalProperties); + return Objects.hash( + displayName, enabled, id, include, keepUnmatched, mappings, type, additionalProperties); } @Override @@ -294,6 +322,7 @@ public String toString() { sb.append(" enabled: ").append(toIndentedString(enabled)).append("\n"); sb.append(" id: ").append(toIndentedString(id)).append("\n"); sb.append(" include: ").append(toIndentedString(include)).append("\n"); + sb.append(" keepUnmatched: ").append(toIndentedString(keepUnmatched)).append("\n"); sb.append(" mappings: ").append(toIndentedString(mappings)).append("\n"); sb.append(" type: ").append(toIndentedString(type)).append("\n"); sb.append(" additionalProperties: ") diff --git a/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_OCSF_mapper_keep_unmatched_returns_OK_response.freeze b/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_OCSF_mapper_keep_unmatched_returns_OK_response.freeze new file mode 100644 index 00000000000..4cc5bbd3eda --- /dev/null +++ b/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_OCSF_mapper_keep_unmatched_returns_OK_response.freeze @@ -0,0 +1 @@ +2026-03-16T13:02:49.264Z \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_OCSF_mapper_keep_unmatched_returns_OK_response.json b/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_OCSF_mapper_keep_unmatched_returns_OK_response.json new file mode 100644 index 00000000000..60ef454d963 --- /dev/null +++ b/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_OCSF_mapper_keep_unmatched_returns_OK_response.json @@ -0,0 +1,32 @@ +[ + { + "httpRequest": { + "body": { + "type": "JSON", + "json": "{\"data\":{\"attributes\":{\"config\":{\"destinations\":[{\"id\":\"datadog-logs-destination\",\"inputs\":[\"my-processor-group\"],\"type\":\"datadog_logs\"}],\"processor_groups\":[{\"enabled\":true,\"id\":\"my-processor-group\",\"include\":\"service:my-service\",\"inputs\":[\"datadog-agent-source\"],\"processors\":[{\"enabled\":true,\"id\":\"ocsf-mapper-processor\",\"include\":\"service:my-service\",\"keep_unmatched\":true,\"mappings\":[{\"include\":\"source:cloudtrail\",\"mapping\":\"CloudTrail Account Change\"}],\"type\":\"ocsf_mapper\"}]}],\"sources\":[{\"id\":\"datadog-agent-source\",\"type\":\"datadog_agent\"}]},\"name\":\"OCSF Mapper Keep Unmatched Pipeline\"},\"type\":\"pipelines\"}}" + }, + "headers": {}, + "method": "POST", + "path": "/api/v2/obs-pipelines/pipelines/validate", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "body": "{\"errors\":[]}\n", + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "statusCode": 200, + "reasonPhrase": "OK" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "f5433095-b669-5a37-c1e8-c7de43d95c58" + } +] \ No newline at end of file diff --git a/src/test/resources/com/datadog/api/client/v2/api/observability_pipelines.feature b/src/test/resources/com/datadog/api/client/v2/api/observability_pipelines.feature index e272303955a..7e8ceefc82e 100644 --- a/src/test/resources/com/datadog/api/client/v2/api/observability_pipelines.feature +++ b/src/test/resources/com/datadog/api/client/v2/api/observability_pipelines.feature @@ -191,6 +191,14 @@ Feature: Observability Pipelines When the request is sent Then the response status is 400 Bad Request + @team:DataDog/observability-pipelines + Scenario: Validate an observability pipeline with OCSF mapper keep_unmatched returns "OK" response + Given new "ValidatePipeline" request + And body with value {"data": {"attributes": {"config": {"destinations": [{"id": "datadog-logs-destination", "inputs": ["my-processor-group"], "type": "datadog_logs"}], "processor_groups": [{"enabled": true, "id": "my-processor-group", "include": "service:my-service", "inputs": ["datadog-agent-source"], "processors": [{"enabled": true, "id": "ocsf-mapper-processor", "include": "service:my-service", "type": "ocsf_mapper", "keep_unmatched": true, "mappings": [{"include": "source:cloudtrail", "mapping": "CloudTrail Account Change"}]}]}], "sources": [{"id": "datadog-agent-source", "type": "datadog_agent"}]}, "name": "OCSF Mapper Keep Unmatched Pipeline"}, "type": "pipelines"}} + When the request is sent + Then the response status is 200 OK + And the response "errors" has length 0 + @team:DataDog/observability-pipelines Scenario: Validate an observability pipeline with OCSF mapper library mapping returns "OK" response Given new "ValidatePipeline" request