|  | 
| 21 | 21 | import org.elasticsearch.action.admin.cluster.node.info.NodeInfo; | 
| 22 | 22 | import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse; | 
| 23 | 23 | import org.elasticsearch.action.bulk.FailureStoreMetrics; | 
|  | 24 | +import org.elasticsearch.action.bulk.IndexDocFailureStoreStatus; | 
| 24 | 25 | import org.elasticsearch.action.bulk.TransportBulkAction; | 
| 25 | 26 | import org.elasticsearch.action.index.IndexRequest; | 
| 26 | 27 | import org.elasticsearch.action.ingest.DeletePipelineRequest; | 
| @@ -729,12 +730,34 @@ void validatePipeline(Map<DiscoveryNode, IngestInfo> ingestInfos, String pipelin | 
| 729 | 730 |         ExceptionsHelper.rethrowAndSuppress(exceptions); | 
| 730 | 731 |     } | 
| 731 | 732 | 
 | 
| 732 |  | -    private record IngestPipelinesExecutionResult(boolean success, boolean shouldKeep, Exception exception, String failedIndex) { | 
|  | 733 | +    private record IngestPipelinesExecutionResult( | 
|  | 734 | +        boolean success, | 
|  | 735 | +        boolean shouldKeep, | 
|  | 736 | +        Exception exception, | 
|  | 737 | +        String failedIndex, | 
|  | 738 | +        IndexDocFailureStoreStatus failureStoreStatus | 
|  | 739 | +    ) { | 
| 733 | 740 | 
 | 
| 734 |  | -        private static final IngestPipelinesExecutionResult SUCCESSFUL_RESULT = new IngestPipelinesExecutionResult(true, true, null, null); | 
| 735 |  | -        private static final IngestPipelinesExecutionResult DISCARD_RESULT = new IngestPipelinesExecutionResult(true, false, null, null); | 
|  | 741 | +        private static final IngestPipelinesExecutionResult SUCCESSFUL_RESULT = new IngestPipelinesExecutionResult( | 
|  | 742 | +            true, | 
|  | 743 | +            true, | 
|  | 744 | +            null, | 
|  | 745 | +            null, | 
|  | 746 | +            IndexDocFailureStoreStatus.NOT_APPLICABLE_OR_UNKNOWN | 
|  | 747 | +        ); | 
|  | 748 | +        private static final IngestPipelinesExecutionResult DISCARD_RESULT = new IngestPipelinesExecutionResult( | 
|  | 749 | +            true, | 
|  | 750 | +            false, | 
|  | 751 | +            null, | 
|  | 752 | +            null, | 
|  | 753 | +            IndexDocFailureStoreStatus.NOT_APPLICABLE_OR_UNKNOWN | 
|  | 754 | +        ); | 
| 736 | 755 |         private static IngestPipelinesExecutionResult failAndStoreFor(String index, Exception e) { | 
| 737 |  | -            return new IngestPipelinesExecutionResult(false, true, e, index); | 
|  | 756 | +            return new IngestPipelinesExecutionResult(false, true, e, index, IndexDocFailureStoreStatus.USED); | 
|  | 757 | +        } | 
|  | 758 | + | 
|  | 759 | +        private static IngestPipelinesExecutionResult failWithoutStoringIn(String index, Exception e) { | 
|  | 760 | +            return new IngestPipelinesExecutionResult(false, true, e, index, IndexDocFailureStoreStatus.NOT_ENABLED); | 
| 738 | 761 |         } | 
| 739 | 762 |     } | 
| 740 | 763 | 
 | 
| @@ -764,7 +787,7 @@ public void executeBulkRequest( | 
| 764 | 787 |         final IntConsumer onDropped, | 
| 765 | 788 |         final Function<String, Boolean> resolveFailureStore, | 
| 766 | 789 |         final TriConsumer<Integer, String, Exception> onStoreFailure, | 
| 767 |  | -        final BiConsumer<Integer, Exception> onFailure, | 
|  | 790 | +        final TriConsumer<Integer, Exception, IndexDocFailureStoreStatus> onFailure, | 
| 768 | 791 |         final BiConsumer<Thread, Exception> onCompletion, | 
| 769 | 792 |         final Executor executor | 
| 770 | 793 |     ) { | 
| @@ -821,18 +844,26 @@ public void onResponse(IngestPipelinesExecutionResult result) { | 
| 821 | 844 |                                             firstPipeline.getMetrics().postIngestBytes(indexRequest.ramBytesUsed()); | 
| 822 | 845 |                                         } | 
| 823 | 846 |                                     } else { | 
| 824 |  | -                                        // We were given a failure result in the onResponse method, so we must store the failure | 
| 825 |  | -                                        // Recover the original document state, track a failed ingest, and pass it along | 
| 826 |  | -                                        updateIndexRequestMetadata(indexRequest, originalDocumentMetadata); | 
| 827 | 847 |                                         totalMetrics.ingestFailed(); | 
| 828 |  | -                                        onStoreFailure.apply(slot, result.failedIndex, result.exception); | 
|  | 848 | +                                        if (IndexDocFailureStoreStatus.NOT_ENABLED.equals(result.failureStoreStatus)) { | 
|  | 849 | +                                            // A failure result, but despite the target being a data stream, it does not have failure | 
|  | 850 | +                                            // storage enabled currently. Capture the status in the onFailure call and skip any further | 
|  | 851 | +                                            // processing | 
|  | 852 | +                                            onFailure.apply(slot, result.exception, result.failureStoreStatus); | 
|  | 853 | +                                        } else { | 
|  | 854 | +                                            // We were given a failure result in the onResponse method, so we must store the failure | 
|  | 855 | +                                            // Recover the original document state, track a failed ingest, and pass it along | 
|  | 856 | +                                            updateIndexRequestMetadata(indexRequest, originalDocumentMetadata); | 
|  | 857 | +                                            onStoreFailure.apply(slot, result.failedIndex, result.exception); | 
|  | 858 | +                                        } | 
| 829 | 859 |                                     } | 
| 830 | 860 |                                 } | 
| 831 | 861 | 
 | 
| 832 | 862 |                                 @Override | 
| 833 | 863 |                                 public void onFailure(Exception e) { | 
|  | 864 | +                                    // The target of the request does not allow failure storage, or failed for unforeseen reason | 
| 834 | 865 |                                     totalMetrics.ingestFailed(); | 
| 835 |  | -                                    onFailure.accept(slot, e); | 
|  | 866 | +                                    onFailure.apply(slot, e, IndexDocFailureStoreStatus.NOT_APPLICABLE_OR_UNKNOWN); | 
| 836 | 867 |                                 } | 
| 837 | 868 |                             }, | 
| 838 | 869 |                             () -> { | 
| @@ -954,15 +985,15 @@ private void executePipelines( | 
| 954 | 985 |             if (failureStoreResolution != null && failureStoreResolution) { | 
| 955 | 986 |                 failureStoreMetrics.incrementFailureStore(originalIndex, errorType, FailureStoreMetrics.ErrorLocation.PIPELINE); | 
| 956 | 987 |                 listener.onResponse(IngestPipelinesExecutionResult.failAndStoreFor(originalIndex, e)); | 
|  | 988 | +            } else if (failureStoreResolution != null) { | 
|  | 989 | +                // If this document targeted a data stream that didn't have the failure store enabled, we increment | 
|  | 990 | +                // the rejected counter. | 
|  | 991 | +                // We also increment the total counter because this request will not reach the code that increments | 
|  | 992 | +                // the total counter for non-rejected documents. | 
|  | 993 | +                failureStoreMetrics.incrementTotal(originalIndex); | 
|  | 994 | +                failureStoreMetrics.incrementRejected(originalIndex, errorType, FailureStoreMetrics.ErrorLocation.PIPELINE, false); | 
|  | 995 | +                listener.onResponse(IngestPipelinesExecutionResult.failWithoutStoringIn(originalIndex, e)); | 
| 957 | 996 |             } else { | 
| 958 |  | -                if (failureStoreResolution != null) { | 
| 959 |  | -                    // If this document targeted a data stream that didn't have the failure store enabled, we increment | 
| 960 |  | -                    // the rejected counter. | 
| 961 |  | -                    // We also increment the total counter because this request will not reach the code that increments | 
| 962 |  | -                    // the total counter for non-rejected documents. | 
| 963 |  | -                    failureStoreMetrics.incrementTotal(originalIndex); | 
| 964 |  | -                    failureStoreMetrics.incrementRejected(originalIndex, errorType, FailureStoreMetrics.ErrorLocation.PIPELINE, false); | 
| 965 |  | -                } | 
| 966 | 997 |                 listener.onFailure(e); | 
| 967 | 998 |             } | 
| 968 | 999 |         }; | 
|  | 
0 commit comments