diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index f535b34d3eb..2cca6612e81 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -67693,6 +67693,10 @@ components: The `parse_grok` processor extracts structured fields from unstructured log messages using Grok patterns. **Supported pipeline types:** logs + example: + id: "parse-grok-processor" + include: "service:my-service" + type: "parse_grok" properties: disable_library_rules: default: false @@ -67705,6 +67709,11 @@ components: description: Indicates whether the processor is enabled. example: true type: boolean + field: + default: "message" + description: The log field to parse with the Grok rules. + example: "message" + type: string id: description: A unique identifier for this processor. example: "parse-grok-processor" @@ -67714,9 +67723,9 @@ components: example: "service:my-service" type: string rules: - description: The list of Grok parsing rules. If multiple matching rules are provided, they are evaluated in order. The first successful match is applied. + description: The list of Grok parsing rules selected by either source field or include query. items: - $ref: "#/components/schemas/ObservabilityPipelineParseGrokProcessorRule" + $ref: "#/components/schemas/ObservabilityPipelineParseGrokProcessorRuleItem" type: array type: $ref: "#/components/schemas/ObservabilityPipelineParseGrokProcessorType" @@ -67728,6 +67737,37 @@ components: - enabled type: object x-pipeline-types: [logs] + ObservabilityPipelineParseGrokProcessorIncludeRule: + description: |- + A Grok parsing rule selected using the `include` query. Each rule defines how to extract structured fields + from logs matching a Datadog search query. + properties: + include: + description: A Datadog search query used to determine which logs this Grok rule targets. + example: "service:my-service" + type: string + match_rules: + description: |- + A list of Grok parsing rules that define how to extract fields from matching logs. + Each rule must contain a name and a valid Grok pattern. + example: + - name: "MyParsingRule" + rule: '%{word:user} connected on %{date("MM/dd/yyyy"):date}' + items: + $ref: "#/components/schemas/ObservabilityPipelineParseGrokProcessorRuleMatchRule" + type: array + support_rules: + description: A list of Grok helper rules that can be referenced by the parsing rules. + example: + - name: "user" + rule: "%{word:user.name}" + items: + $ref: "#/components/schemas/ObservabilityPipelineParseGrokProcessorRuleSupportRule" + type: array + required: + - include + - match_rules + type: object ObservabilityPipelineParseGrokProcessorRule: description: |- A Grok parsing rule used in the `parse_grok` processor. Each rule defines how to extract structured fields @@ -67760,6 +67800,11 @@ components: - source - match_rules type: object + ObservabilityPipelineParseGrokProcessorRuleItem: + description: A single Grok parsing rule, selected by either source field or include query. + oneOf: + - $ref: "#/components/schemas/ObservabilityPipelineParseGrokProcessorRule" + - $ref: "#/components/schemas/ObservabilityPipelineParseGrokProcessorIncludeRule" ObservabilityPipelineParseGrokProcessorRuleMatchRule: description: |- Defines a Grok parsing rule, which extracts structured fields from log content using named Grok patterns. diff --git a/examples/v2/observability-pipelines/ValidatePipeline_3345949653.java b/examples/v2/observability-pipelines/ValidatePipeline_3345949653.java new file mode 100644 index 00000000000..bdc7cfec015 --- /dev/null +++ b/examples/v2/observability-pipelines/ValidatePipeline_3345949653.java @@ -0,0 +1,104 @@ +// Validate an observability pipeline with parse grok processor source rules 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.ObservabilityPipelineParseGrokProcessor; +import com.datadog.api.client.v2.model.ObservabilityPipelineParseGrokProcessorRule; +import com.datadog.api.client.v2.model.ObservabilityPipelineParseGrokProcessorRuleItem; +import com.datadog.api.client.v2.model.ObservabilityPipelineParseGrokProcessorRuleMatchRule; +import com.datadog.api.client.v2.model.ObservabilityPipelineParseGrokProcessorType; +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 ObservabilityPipelineParseGrokProcessor() + .enabled(true) + .id("parse-grok-processor") + .include("*") + .type( + ObservabilityPipelineParseGrokProcessorType + .PARSE_GROK) + .rules( + Collections.singletonList( + new ObservabilityPipelineParseGrokProcessorRuleItem( + new ObservabilityPipelineParseGrokProcessorRule() + .source("message") + .matchRules( + Collections + .singletonList( + new ObservabilityPipelineParseGrokProcessorRuleMatchRule() + .name( + "MyParsingRule") + .rule( + "%{word:user}"))))))))))) + .sources( + Collections.singletonList( + new ObservabilityPipelineConfigSourceItem( + new ObservabilityPipelineDatadogAgentSource() + .id("datadog-agent-source") + .type( + ObservabilityPipelineDatadogAgentSourceType + .DATADOG_AGENT))))) + .name("Pipeline with Parse Grok Source Rules")) + .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/examples/v2/observability-pipelines/ValidatePipeline_3928499240.java b/examples/v2/observability-pipelines/ValidatePipeline_3928499240.java new file mode 100644 index 00000000000..04316fdea6b --- /dev/null +++ b/examples/v2/observability-pipelines/ValidatePipeline_3928499240.java @@ -0,0 +1,106 @@ +// Validate an observability pipeline with parse grok processor include rules 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.ObservabilityPipelineParseGrokProcessor; +import com.datadog.api.client.v2.model.ObservabilityPipelineParseGrokProcessorIncludeRule; +import com.datadog.api.client.v2.model.ObservabilityPipelineParseGrokProcessorRuleItem; +import com.datadog.api.client.v2.model.ObservabilityPipelineParseGrokProcessorRuleMatchRule; +import com.datadog.api.client.v2.model.ObservabilityPipelineParseGrokProcessorType; +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 ObservabilityPipelineParseGrokProcessor() + .enabled(true) + .id("parse-grok-processor") + .include("*") + .type( + ObservabilityPipelineParseGrokProcessorType + .PARSE_GROK) + .field("content") + .rules( + Collections.singletonList( + new ObservabilityPipelineParseGrokProcessorRuleItem( + new ObservabilityPipelineParseGrokProcessorIncludeRule() + .include( + "service:foo") + .matchRules( + Collections + .singletonList( + new ObservabilityPipelineParseGrokProcessorRuleMatchRule() + .name( + "MyParsingRule") + .rule( + "%{word:user}"))))))))))) + .sources( + Collections.singletonList( + new ObservabilityPipelineConfigSourceItem( + new ObservabilityPipelineDatadogAgentSource() + .id("datadog-agent-source") + .type( + ObservabilityPipelineDatadogAgentSourceType + .DATADOG_AGENT))))) + .name("Pipeline with Parse Grok Include Rules")) + .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/ObservabilityPipelineParseGrokProcessor.java b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineParseGrokProcessor.java index b78feb5c58d..bf33fb9b6e1 100644 --- a/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineParseGrokProcessor.java +++ b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineParseGrokProcessor.java @@ -29,6 +29,7 @@ ObservabilityPipelineParseGrokProcessor.JSON_PROPERTY_DISABLE_LIBRARY_RULES, ObservabilityPipelineParseGrokProcessor.JSON_PROPERTY_DISPLAY_NAME, ObservabilityPipelineParseGrokProcessor.JSON_PROPERTY_ENABLED, + ObservabilityPipelineParseGrokProcessor.JSON_PROPERTY_FIELD, ObservabilityPipelineParseGrokProcessor.JSON_PROPERTY_ID, ObservabilityPipelineParseGrokProcessor.JSON_PROPERTY_INCLUDE, ObservabilityPipelineParseGrokProcessor.JSON_PROPERTY_RULES, @@ -47,6 +48,9 @@ public class ObservabilityPipelineParseGrokProcessor { public static final String JSON_PROPERTY_ENABLED = "enabled"; private Boolean enabled; + public static final String JSON_PROPERTY_FIELD = "field"; + private String field = "message"; + public static final String JSON_PROPERTY_ID = "id"; private String id; @@ -54,7 +58,7 @@ public class ObservabilityPipelineParseGrokProcessor { private String include; public static final String JSON_PROPERTY_RULES = "rules"; - private List rules = new ArrayList<>(); + private List rules = new ArrayList<>(); public static final String JSON_PROPERTY_TYPE = "type"; private ObservabilityPipelineParseGrokProcessorType type = @@ -68,7 +72,7 @@ public ObservabilityPipelineParseGrokProcessor( @JsonProperty(required = true, value = JSON_PROPERTY_ID) String id, @JsonProperty(required = true, value = JSON_PROPERTY_INCLUDE) String include, @JsonProperty(required = true, value = JSON_PROPERTY_RULES) - List rules, + List rules, @JsonProperty(required = true, value = JSON_PROPERTY_TYPE) ObservabilityPipelineParseGrokProcessorType type) { this.enabled = enabled; @@ -141,6 +145,27 @@ public void setEnabled(Boolean enabled) { this.enabled = enabled; } + public ObservabilityPipelineParseGrokProcessor field(String field) { + this.field = field; + return this; + } + + /** + * The log field to parse with the Grok rules. + * + * @return field + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_FIELD) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + public ObservabilityPipelineParseGrokProcessor id(String id) { this.id = id; return this; @@ -182,34 +207,33 @@ public void setInclude(String include) { } public ObservabilityPipelineParseGrokProcessor rules( - List rules) { + List rules) { this.rules = rules; - for (ObservabilityPipelineParseGrokProcessorRule item : rules) { + for (ObservabilityPipelineParseGrokProcessorRuleItem item : rules) { this.unparsed |= item.unparsed; } return this; } public ObservabilityPipelineParseGrokProcessor addRulesItem( - ObservabilityPipelineParseGrokProcessorRule rulesItem) { + ObservabilityPipelineParseGrokProcessorRuleItem rulesItem) { this.rules.add(rulesItem); this.unparsed |= rulesItem.unparsed; return this; } /** - * The list of Grok parsing rules. If multiple matching rules are provided, they are evaluated in - * order. The first successful match is applied. + * The list of Grok parsing rules selected by either source field or include query. * * @return rules */ @JsonProperty(JSON_PROPERTY_RULES) @JsonInclude(value = JsonInclude.Include.ALWAYS) - public List getRules() { + public List getRules() { return rules; } - public void setRules(List rules) { + public void setRules(List rules) { this.rules = rules; } @@ -299,6 +323,7 @@ public boolean equals(Object o) { this.disableLibraryRules, observabilityPipelineParseGrokProcessor.disableLibraryRules) && Objects.equals(this.displayName, observabilityPipelineParseGrokProcessor.displayName) && Objects.equals(this.enabled, observabilityPipelineParseGrokProcessor.enabled) + && Objects.equals(this.field, observabilityPipelineParseGrokProcessor.field) && Objects.equals(this.id, observabilityPipelineParseGrokProcessor.id) && Objects.equals(this.include, observabilityPipelineParseGrokProcessor.include) && Objects.equals(this.rules, observabilityPipelineParseGrokProcessor.rules) @@ -311,7 +336,15 @@ public boolean equals(Object o) { @Override public int hashCode() { return Objects.hash( - disableLibraryRules, displayName, enabled, id, include, rules, type, additionalProperties); + disableLibraryRules, + displayName, + enabled, + field, + id, + include, + rules, + type, + additionalProperties); } @Override @@ -323,6 +356,7 @@ public String toString() { .append("\n"); sb.append(" displayName: ").append(toIndentedString(displayName)).append("\n"); sb.append(" enabled: ").append(toIndentedString(enabled)).append("\n"); + sb.append(" field: ").append(toIndentedString(field)).append("\n"); sb.append(" id: ").append(toIndentedString(id)).append("\n"); sb.append(" include: ").append(toIndentedString(include)).append("\n"); sb.append(" rules: ").append(toIndentedString(rules)).append("\n"); diff --git a/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineParseGrokProcessorIncludeRule.java b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineParseGrokProcessorIncludeRule.java new file mode 100644 index 00000000000..ae3b35a1b0f --- /dev/null +++ b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineParseGrokProcessorIncludeRule.java @@ -0,0 +1,242 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2019-Present Datadog, Inc. + */ + +package com.datadog.api.client.v2.model; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * A Grok parsing rule selected using the include query. Each rule defines how to + * extract structured fields from logs matching a Datadog search query. + */ +@JsonPropertyOrder({ + ObservabilityPipelineParseGrokProcessorIncludeRule.JSON_PROPERTY_INCLUDE, + ObservabilityPipelineParseGrokProcessorIncludeRule.JSON_PROPERTY_MATCH_RULES, + ObservabilityPipelineParseGrokProcessorIncludeRule.JSON_PROPERTY_SUPPORT_RULES +}) +@jakarta.annotation.Generated( + value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") +public class ObservabilityPipelineParseGrokProcessorIncludeRule { + @JsonIgnore public boolean unparsed = false; + public static final String JSON_PROPERTY_INCLUDE = "include"; + private String include; + + public static final String JSON_PROPERTY_MATCH_RULES = "match_rules"; + private List matchRules = new ArrayList<>(); + + public static final String JSON_PROPERTY_SUPPORT_RULES = "support_rules"; + private List supportRules = null; + + public ObservabilityPipelineParseGrokProcessorIncludeRule() {} + + @JsonCreator + public ObservabilityPipelineParseGrokProcessorIncludeRule( + @JsonProperty(required = true, value = JSON_PROPERTY_INCLUDE) String include, + @JsonProperty(required = true, value = JSON_PROPERTY_MATCH_RULES) + List matchRules) { + this.include = include; + this.matchRules = matchRules; + } + + public ObservabilityPipelineParseGrokProcessorIncludeRule include(String include) { + this.include = include; + return this; + } + + /** + * A Datadog search query used to determine which logs this Grok rule targets. + * + * @return include + */ + @JsonProperty(JSON_PROPERTY_INCLUDE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getInclude() { + return include; + } + + public void setInclude(String include) { + this.include = include; + } + + public ObservabilityPipelineParseGrokProcessorIncludeRule matchRules( + List matchRules) { + this.matchRules = matchRules; + for (ObservabilityPipelineParseGrokProcessorRuleMatchRule item : matchRules) { + this.unparsed |= item.unparsed; + } + return this; + } + + public ObservabilityPipelineParseGrokProcessorIncludeRule addMatchRulesItem( + ObservabilityPipelineParseGrokProcessorRuleMatchRule matchRulesItem) { + this.matchRules.add(matchRulesItem); + this.unparsed |= matchRulesItem.unparsed; + return this; + } + + /** + * A list of Grok parsing rules that define how to extract fields from matching logs. Each rule + * must contain a name and a valid Grok pattern. + * + * @return matchRules + */ + @JsonProperty(JSON_PROPERTY_MATCH_RULES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getMatchRules() { + return matchRules; + } + + public void setMatchRules(List matchRules) { + this.matchRules = matchRules; + } + + public ObservabilityPipelineParseGrokProcessorIncludeRule supportRules( + List supportRules) { + this.supportRules = supportRules; + for (ObservabilityPipelineParseGrokProcessorRuleSupportRule item : supportRules) { + this.unparsed |= item.unparsed; + } + return this; + } + + public ObservabilityPipelineParseGrokProcessorIncludeRule addSupportRulesItem( + ObservabilityPipelineParseGrokProcessorRuleSupportRule supportRulesItem) { + if (this.supportRules == null) { + this.supportRules = new ArrayList<>(); + } + this.supportRules.add(supportRulesItem); + this.unparsed |= supportRulesItem.unparsed; + return this; + } + + /** + * A list of Grok helper rules that can be referenced by the parsing rules. + * + * @return supportRules + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_SUPPORT_RULES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getSupportRules() { + return supportRules; + } + + public void setSupportRules( + List supportRules) { + this.supportRules = supportRules; + } + + /** + * A container for additional, undeclared properties. This is a holder for any undeclared + * properties as specified with the 'additionalProperties' keyword in the OAS document. + */ + private Map additionalProperties; + + /** + * Set the additional (undeclared) property with the specified name and value. If the property + * does not already exist, create it otherwise replace it. + * + * @param key The arbitrary key to set + * @param value The associated value + * @return ObservabilityPipelineParseGrokProcessorIncludeRule + */ + @JsonAnySetter + public ObservabilityPipelineParseGrokProcessorIncludeRule putAdditionalProperty( + String key, Object value) { + if (this.additionalProperties == null) { + this.additionalProperties = new HashMap(); + } + this.additionalProperties.put(key, value); + return this; + } + + /** + * Return the additional (undeclared) property. + * + * @return The additional properties + */ + @JsonAnyGetter + public Map getAdditionalProperties() { + return additionalProperties; + } + + /** + * Return the additional (undeclared) property with the specified name. + * + * @param key The arbitrary key to get + * @return The specific additional property for the given key + */ + public Object getAdditionalProperty(String key) { + if (this.additionalProperties == null) { + return null; + } + return this.additionalProperties.get(key); + } + + /** + * Return true if this ObservabilityPipelineParseGrokProcessorIncludeRule object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ObservabilityPipelineParseGrokProcessorIncludeRule + observabilityPipelineParseGrokProcessorIncludeRule = + (ObservabilityPipelineParseGrokProcessorIncludeRule) o; + return Objects.equals(this.include, observabilityPipelineParseGrokProcessorIncludeRule.include) + && Objects.equals( + this.matchRules, observabilityPipelineParseGrokProcessorIncludeRule.matchRules) + && Objects.equals( + this.supportRules, observabilityPipelineParseGrokProcessorIncludeRule.supportRules) + && Objects.equals( + this.additionalProperties, + observabilityPipelineParseGrokProcessorIncludeRule.additionalProperties); + } + + @Override + public int hashCode() { + return Objects.hash(include, matchRules, supportRules, additionalProperties); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ObservabilityPipelineParseGrokProcessorIncludeRule {\n"); + sb.append(" include: ").append(toIndentedString(include)).append("\n"); + sb.append(" matchRules: ").append(toIndentedString(matchRules)).append("\n"); + sb.append(" supportRules: ").append(toIndentedString(supportRules)).append("\n"); + sb.append(" additionalProperties: ") + .append(toIndentedString(additionalProperties)) + .append("\n"); + sb.append('}'); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineParseGrokProcessorRuleItem.java b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineParseGrokProcessorRuleItem.java new file mode 100644 index 00000000000..d0a4eed51fe --- /dev/null +++ b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineParseGrokProcessorRuleItem.java @@ -0,0 +1,329 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2019-Present Datadog, Inc. + */ + +package com.datadog.api.client.v2.model; + +import com.datadog.api.client.AbstractOpenApiSchema; +import com.datadog.api.client.JSON; +import com.datadog.api.client.UnparsedObject; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import jakarta.ws.rs.core.GenericType; +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +@jakarta.annotation.Generated( + value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") +@JsonDeserialize( + using = + ObservabilityPipelineParseGrokProcessorRuleItem + .ObservabilityPipelineParseGrokProcessorRuleItemDeserializer.class) +@JsonSerialize( + using = + ObservabilityPipelineParseGrokProcessorRuleItem + .ObservabilityPipelineParseGrokProcessorRuleItemSerializer.class) +public class ObservabilityPipelineParseGrokProcessorRuleItem extends AbstractOpenApiSchema { + private static final Logger log = + Logger.getLogger(ObservabilityPipelineParseGrokProcessorRuleItem.class.getName()); + + @JsonIgnore public boolean unparsed = false; + + public static class ObservabilityPipelineParseGrokProcessorRuleItemSerializer + extends StdSerializer { + public ObservabilityPipelineParseGrokProcessorRuleItemSerializer( + Class t) { + super(t); + } + + public ObservabilityPipelineParseGrokProcessorRuleItemSerializer() { + this(null); + } + + @Override + public void serialize( + ObservabilityPipelineParseGrokProcessorRuleItem value, + JsonGenerator jgen, + SerializerProvider provider) + throws IOException, JsonProcessingException { + jgen.writeObject(value.getActualInstance()); + } + } + + public static class ObservabilityPipelineParseGrokProcessorRuleItemDeserializer + extends StdDeserializer { + public ObservabilityPipelineParseGrokProcessorRuleItemDeserializer() { + this(ObservabilityPipelineParseGrokProcessorRuleItem.class); + } + + public ObservabilityPipelineParseGrokProcessorRuleItemDeserializer(Class vc) { + super(vc); + } + + @Override + public ObservabilityPipelineParseGrokProcessorRuleItem deserialize( + JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + JsonNode tree = jp.readValueAsTree(); + Object deserialized = null; + Object tmp = null; + boolean typeCoercion = ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS); + int match = 0; + JsonToken token = tree.traverse(jp.getCodec()).nextToken(); + // deserialize ObservabilityPipelineParseGrokProcessorRule + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (ObservabilityPipelineParseGrokProcessorRule.class.equals(Integer.class) + || ObservabilityPipelineParseGrokProcessorRule.class.equals(Long.class) + || ObservabilityPipelineParseGrokProcessorRule.class.equals(Float.class) + || ObservabilityPipelineParseGrokProcessorRule.class.equals(Double.class) + || ObservabilityPipelineParseGrokProcessorRule.class.equals(Boolean.class) + || ObservabilityPipelineParseGrokProcessorRule.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((ObservabilityPipelineParseGrokProcessorRule.class.equals(Integer.class) + || ObservabilityPipelineParseGrokProcessorRule.class.equals(Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((ObservabilityPipelineParseGrokProcessorRule.class.equals(Float.class) + || ObservabilityPipelineParseGrokProcessorRule.class.equals(Double.class)) + && (token == JsonToken.VALUE_NUMBER_FLOAT + || token == JsonToken.VALUE_NUMBER_INT)); + attemptParsing |= + (ObservabilityPipelineParseGrokProcessorRule.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (ObservabilityPipelineParseGrokProcessorRule.class.equals(String.class) + && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + tmp = + tree.traverse(jp.getCodec()) + .readValueAs(ObservabilityPipelineParseGrokProcessorRule.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + if (!((ObservabilityPipelineParseGrokProcessorRule) tmp).unparsed) { + deserialized = tmp; + match++; + } + log.log( + Level.FINER, + "Input data matches schema 'ObservabilityPipelineParseGrokProcessorRule'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log( + Level.FINER, + "Input data does not match schema 'ObservabilityPipelineParseGrokProcessorRule'", + e); + } + + // deserialize ObservabilityPipelineParseGrokProcessorIncludeRule + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (ObservabilityPipelineParseGrokProcessorIncludeRule.class.equals(Integer.class) + || ObservabilityPipelineParseGrokProcessorIncludeRule.class.equals(Long.class) + || ObservabilityPipelineParseGrokProcessorIncludeRule.class.equals(Float.class) + || ObservabilityPipelineParseGrokProcessorIncludeRule.class.equals(Double.class) + || ObservabilityPipelineParseGrokProcessorIncludeRule.class.equals(Boolean.class) + || ObservabilityPipelineParseGrokProcessorIncludeRule.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((ObservabilityPipelineParseGrokProcessorIncludeRule.class.equals(Integer.class) + || ObservabilityPipelineParseGrokProcessorIncludeRule.class.equals( + Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((ObservabilityPipelineParseGrokProcessorIncludeRule.class.equals(Float.class) + || ObservabilityPipelineParseGrokProcessorIncludeRule.class.equals( + Double.class)) + && (token == JsonToken.VALUE_NUMBER_FLOAT + || token == JsonToken.VALUE_NUMBER_INT)); + attemptParsing |= + (ObservabilityPipelineParseGrokProcessorIncludeRule.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (ObservabilityPipelineParseGrokProcessorIncludeRule.class.equals(String.class) + && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + tmp = + tree.traverse(jp.getCodec()) + .readValueAs(ObservabilityPipelineParseGrokProcessorIncludeRule.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + if (!((ObservabilityPipelineParseGrokProcessorIncludeRule) tmp).unparsed) { + deserialized = tmp; + match++; + } + log.log( + Level.FINER, + "Input data matches schema 'ObservabilityPipelineParseGrokProcessorIncludeRule'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log( + Level.FINER, + "Input data does not match schema 'ObservabilityPipelineParseGrokProcessorIncludeRule'", + e); + } + + ObservabilityPipelineParseGrokProcessorRuleItem ret = + new ObservabilityPipelineParseGrokProcessorRuleItem(); + if (match == 1) { + ret.setActualInstance(deserialized); + } else { + Map res = + new ObjectMapper() + .readValue( + tree.traverse(jp.getCodec()).readValueAsTree().toString(), + new TypeReference>() {}); + ret.setActualInstance(new UnparsedObject(res)); + } + return ret; + } + + /** Handle deserialization of the 'null' value. */ + @Override + public ObservabilityPipelineParseGrokProcessorRuleItem getNullValue(DeserializationContext ctxt) + throws JsonMappingException { + throw new JsonMappingException( + ctxt.getParser(), "ObservabilityPipelineParseGrokProcessorRuleItem cannot be null"); + } + } + + // store a list of schema names defined in oneOf + public static final Map schemas = new HashMap(); + + public ObservabilityPipelineParseGrokProcessorRuleItem() { + super("oneOf", Boolean.FALSE); + } + + public ObservabilityPipelineParseGrokProcessorRuleItem( + ObservabilityPipelineParseGrokProcessorRule o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + public ObservabilityPipelineParseGrokProcessorRuleItem( + ObservabilityPipelineParseGrokProcessorIncludeRule o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + static { + schemas.put( + "ObservabilityPipelineParseGrokProcessorRule", + new GenericType() {}); + schemas.put( + "ObservabilityPipelineParseGrokProcessorIncludeRule", + new GenericType() {}); + JSON.registerDescendants( + ObservabilityPipelineParseGrokProcessorRuleItem.class, + Collections.unmodifiableMap(schemas)); + } + + @Override + public Map getSchemas() { + return ObservabilityPipelineParseGrokProcessorRuleItem.schemas; + } + + /** + * Set the instance that matches the oneOf child schema, check the instance parameter is valid + * against the oneOf child schemas: ObservabilityPipelineParseGrokProcessorRule, + * ObservabilityPipelineParseGrokProcessorIncludeRule + * + *

It could be an instance of the 'oneOf' schemas. The oneOf child schemas may themselves be a + * composed schema (allOf, anyOf, oneOf). + */ + @Override + public void setActualInstance(Object instance) { + if (JSON.isInstanceOf( + ObservabilityPipelineParseGrokProcessorRule.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + if (JSON.isInstanceOf( + ObservabilityPipelineParseGrokProcessorIncludeRule.class, + instance, + new HashSet>())) { + super.setActualInstance(instance); + return; + } + + if (JSON.isInstanceOf(UnparsedObject.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + throw new RuntimeException( + "Invalid instance type. Must be ObservabilityPipelineParseGrokProcessorRule," + + " ObservabilityPipelineParseGrokProcessorIncludeRule"); + } + + /** + * Get the actual instance, which can be the following: + * ObservabilityPipelineParseGrokProcessorRule, ObservabilityPipelineParseGrokProcessorIncludeRule + * + * @return The actual instance (ObservabilityPipelineParseGrokProcessorRule, + * ObservabilityPipelineParseGrokProcessorIncludeRule) + */ + @Override + public Object getActualInstance() { + return super.getActualInstance(); + } + + /** + * Get the actual instance of `ObservabilityPipelineParseGrokProcessorRule`. If the actual + * instance is not `ObservabilityPipelineParseGrokProcessorRule`, the ClassCastException will be + * thrown. + * + * @return The actual instance of `ObservabilityPipelineParseGrokProcessorRule` + * @throws ClassCastException if the instance is not `ObservabilityPipelineParseGrokProcessorRule` + */ + public ObservabilityPipelineParseGrokProcessorRule + getObservabilityPipelineParseGrokProcessorRule() throws ClassCastException { + return (ObservabilityPipelineParseGrokProcessorRule) super.getActualInstance(); + } + + /** + * Get the actual instance of `ObservabilityPipelineParseGrokProcessorIncludeRule`. If the actual + * instance is not `ObservabilityPipelineParseGrokProcessorIncludeRule`, the ClassCastException + * will be thrown. + * + * @return The actual instance of `ObservabilityPipelineParseGrokProcessorIncludeRule` + * @throws ClassCastException if the instance is not + * `ObservabilityPipelineParseGrokProcessorIncludeRule` + */ + public ObservabilityPipelineParseGrokProcessorIncludeRule + getObservabilityPipelineParseGrokProcessorIncludeRule() throws ClassCastException { + return (ObservabilityPipelineParseGrokProcessorIncludeRule) super.getActualInstance(); + } +} diff --git a/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_parse_grok_processor_include_rules_returns_OK_response.freeze b/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_parse_grok_processor_include_rules_returns_OK_response.freeze new file mode 100644 index 00000000000..985fe4f60ae --- /dev/null +++ b/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_parse_grok_processor_include_rules_returns_OK_response.freeze @@ -0,0 +1 @@ +2026-06-29T20:01:05.978Z \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_parse_grok_processor_include_rules_returns_OK_response.json b/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_parse_grok_processor_include_rules_returns_OK_response.json new file mode 100644 index 00000000000..2d0834165e1 --- /dev/null +++ b/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_parse_grok_processor_include_rules_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,\"field\":\"content\",\"id\":\"parse-grok-processor\",\"include\":\"*\",\"rules\":[{\"include\":\"service:foo\",\"match_rules\":[{\"name\":\"MyParsingRule\",\"rule\":\"%{word:user}\"}]}],\"type\":\"parse_grok\"}]}],\"sources\":[{\"id\":\"datadog-agent-source\",\"type\":\"datadog_agent\"}]},\"name\":\"Pipeline with Parse Grok Include Rules\"},\"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": "b8062fd7-f4ed-ed7f-70d1-6663f84d35bf" + } +] \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_parse_grok_processor_source_rules_returns_OK_response.freeze b/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_parse_grok_processor_source_rules_returns_OK_response.freeze new file mode 100644 index 00000000000..4db9a90b937 --- /dev/null +++ b/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_parse_grok_processor_source_rules_returns_OK_response.freeze @@ -0,0 +1 @@ +2026-06-29T18:24:15.839Z \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_parse_grok_processor_source_rules_returns_OK_response.json b/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_parse_grok_processor_source_rules_returns_OK_response.json new file mode 100644 index 00000000000..18cd691c843 --- /dev/null +++ b/src/test/resources/cassettes/features/v2/Validate_an_observability_pipeline_with_parse_grok_processor_source_rules_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\":\"parse-grok-processor\",\"include\":\"*\",\"rules\":[{\"match_rules\":[{\"name\":\"MyParsingRule\",\"rule\":\"%{word:user}\"}],\"source\":\"message\"}],\"type\":\"parse_grok\"}]}],\"sources\":[{\"id\":\"datadog-agent-source\",\"type\":\"datadog_agent\"}]},\"name\":\"Pipeline with Parse Grok Source Rules\"},\"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": "bca7a00b-7717-b67f-4393-6397923b1e3c" + } +] \ 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 e42bbd7b033..8aa6ef36159 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 @@ -295,6 +295,22 @@ Feature: Observability Pipelines Then the response status is 200 OK And the response "errors" has length 0 + @team:DataDog/observability-pipelines + Scenario: Validate an observability pipeline with parse grok processor include rules 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": "parse-grok-processor", "include": "*", "type": "parse_grok", "field": "content", "rules": [{"include": "service:foo", "match_rules": [{"name": "MyParsingRule", "rule": "%{word:user}"}]}]}]}], "sources": [{"id": "datadog-agent-source", "type": "datadog_agent"}]}, "name": "Pipeline with Parse Grok Include Rules"}, "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 parse grok processor source rules 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": "parse-grok-processor", "include": "*", "type": "parse_grok", "rules": [{"source": "message", "match_rules": [{"name": "MyParsingRule", "rule": "%{word:user}"}]}]}]}], "sources": [{"id": "datadog-agent-source", "type": "datadog_agent"}]}, "name": "Pipeline with Parse Grok Source Rules"}, "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 source secret key returns "OK" response Given new "ValidatePipeline" request