@@ -666,7 +666,7 @@ private static Predicate<SnapshotInfo> buildAfterPredicate(
666666 }
667667 }
668668
669- private static Predicate < SnapshotInfo > filterBySLMPolicies (String [] slmPolicies ) {
669+ private static SnapshotPredicate filterBySLMPolicies (String [] slmPolicies ) {
670670 final List <String > includePatterns = new ArrayList <>();
671671 final List <String > excludePatterns = new ArrayList <>();
672672 boolean seenWildcard = false ;
@@ -686,25 +686,47 @@ private static Predicate<SnapshotInfo> filterBySLMPolicies(String[] slmPolicies)
686686 final String [] includes = includePatterns .toArray (Strings .EMPTY_ARRAY );
687687 final String [] excludes = excludePatterns .toArray (Strings .EMPTY_ARRAY );
688688 final boolean matchWithoutPolicy = matchNoPolicy ;
689- return snapshotInfo -> {
690- final Map <String , Object > metadata = snapshotInfo .userMetadata ();
691- final String policy ;
692- if (metadata == null ) {
693- policy = null ;
694- } else {
695- final Object policyFound = metadata .get (SnapshotsService .POLICY_ID_METADATA_FIELD );
696- policy = policyFound instanceof String ? (String ) policyFound : null ;
697- }
698- if (policy == null ) {
699- return matchWithoutPolicy ;
689+ return new SnapshotPredicate () {
690+ @ Override
691+ public boolean matchesPreflight (SnapshotId snapshotId , RepositoryData repositoryData ) {
692+ final RepositoryData .SnapshotDetails details = repositoryData .getSnapshotDetails (snapshotId );
693+ final String policy ;
694+ if (details == null || (details .getSlmPolicy () == null )) {
695+ // no SLM policy recorded
696+ return true ;
697+ } else {
698+ final String policyFound = details .getSlmPolicy ();
699+ // empty string means that snapshot was not created by an SLM policy
700+ policy = policyFound .isEmpty () ? null : policyFound ;
701+ }
702+ return matchPolicy (includes , excludes , matchWithoutPolicy , policy );
700703 }
701- if (Regex .simpleMatch (includes , policy ) == false ) {
702- return false ;
704+
705+ @ Override
706+ public boolean matches (SnapshotInfo snapshotInfo ) {
707+ final Map <String , Object > metadata = snapshotInfo .userMetadata ();
708+ final String policy ;
709+ if (metadata == null ) {
710+ policy = null ;
711+ } else {
712+ final Object policyFound = metadata .get (SnapshotsService .POLICY_ID_METADATA_FIELD );
713+ policy = policyFound instanceof String ? (String ) policyFound : null ;
714+ }
715+ return matchPolicy (includes , excludes , matchWithoutPolicy , policy );
703716 }
704- return excludes .length == 0 || Regex .simpleMatch (excludes , policy ) == false ;
705717 };
706718 }
707719
720+ private static boolean matchPolicy (String [] includes , String [] excludes , boolean matchWithoutPolicy , @ Nullable String policy ) {
721+ if (policy == null ) {
722+ return matchWithoutPolicy ;
723+ }
724+ if (Regex .simpleMatch (includes , policy ) == false ) {
725+ return false ;
726+ }
727+ return excludes .length == 0 || Regex .simpleMatch (excludes , policy ) == false ;
728+ }
729+
708730 private static Predicate <SnapshotInfo > filterByLongOffset (ToLongFunction <SnapshotInfo > extractor , long after , SortOrder order ) {
709731 return order == SortOrder .ASC ? info -> after <= extractor .applyAsLong (info ) : info -> after >= extractor .applyAsLong (info );
710732 }
@@ -759,19 +781,23 @@ private static final class SnapshotPredicates {
759781 Predicate <SnapshotInfo > snapshotPredicate = null ;
760782 final String [] slmPolicies = request .policies ();
761783 final String fromSortValue = request .fromSortValue ();
784+ BiPredicate <SnapshotId , RepositoryData > preflightPredicate = null ;
762785 if (slmPolicies .length > 0 ) {
763- snapshotPredicate = filterBySLMPolicies (slmPolicies );
786+ final SnapshotPredicate predicate = filterBySLMPolicies (slmPolicies );
787+ snapshotPredicate = predicate ::matches ;
788+ preflightPredicate = predicate ::matchesPreflight ;
764789 }
765790 final GetSnapshotsRequest .SortBy sortBy = request .sort ();
766791 final SortOrder order = request .order ();
767792 if (fromSortValue == null ) {
768- preflightPredicate = null ;
793+ this . preflightPredicate = preflightPredicate ;
769794 } else {
770795 final Predicate <SnapshotInfo > fromSortValuePredicate ;
796+ final BiPredicate <SnapshotId , RepositoryData > preflightPred ;
771797 switch (sortBy ) {
772798 case START_TIME :
773799 final long after = Long .parseLong (fromSortValue );
774- preflightPredicate = order == SortOrder .ASC ? (snapshotId , repositoryData ) -> {
800+ preflightPred = order == SortOrder .ASC ? (snapshotId , repositoryData ) -> {
775801 final long startTime = getStartTime (snapshotId , repositoryData );
776802 return startTime == -1 || after <= startTime ;
777803 } : (snapshotId , repositoryData ) -> {
@@ -781,14 +807,14 @@ private static final class SnapshotPredicates {
781807 fromSortValuePredicate = filterByLongOffset (SnapshotInfo ::startTime , after , order );
782808 break ;
783809 case NAME :
784- preflightPredicate = order == SortOrder .ASC
810+ preflightPred = order == SortOrder .ASC
785811 ? (snapshotId , repositoryData ) -> fromSortValue .compareTo (snapshotId .getName ()) <= 0
786812 : (snapshotId , repositoryData ) -> fromSortValue .compareTo (snapshotId .getName ()) >= 0 ;
787813 fromSortValuePredicate = null ;
788814 break ;
789815 case DURATION :
790816 final long afterDuration = Long .parseLong (fromSortValue );
791- preflightPredicate = order == SortOrder .ASC ? (snapshotId , repositoryData ) -> {
817+ preflightPred = order == SortOrder .ASC ? (snapshotId , repositoryData ) -> {
792818 final long duration = getDuration (snapshotId , repositoryData );
793819 return duration == -1 || afterDuration <= duration ;
794820 } : (snapshotId , repositoryData ) -> {
@@ -799,22 +825,22 @@ private static final class SnapshotPredicates {
799825 break ;
800826 case INDICES :
801827 final int afterIndexCount = Integer .parseInt (fromSortValue );
802- preflightPredicate = order == SortOrder .ASC
828+ preflightPred = order == SortOrder .ASC
803829 ? (snapshotId , repositoryData ) -> afterIndexCount <= indexCount (snapshotId , repositoryData )
804830 : (snapshotId , repositoryData ) -> afterIndexCount >= indexCount (snapshotId , repositoryData );
805831 fromSortValuePredicate = null ;
806832 break ;
807833 case REPOSITORY :
808834 // already handled in #maybeFilterRepositories
809- preflightPredicate = null ;
835+ preflightPred = null ;
810836 fromSortValuePredicate = null ;
811837 break ;
812838 case SHARDS :
813- preflightPredicate = null ;
839+ preflightPred = null ;
814840 fromSortValuePredicate = filterByLongOffset (SnapshotInfo ::totalShards , Integer .parseInt (fromSortValue ), order );
815841 break ;
816842 case FAILED_SHARDS :
817- preflightPredicate = null ;
843+ preflightPred = null ;
818844 fromSortValuePredicate = filterByLongOffset (SnapshotInfo ::failedShards , Integer .parseInt (fromSortValue ), order );
819845 break ;
820846 default :
@@ -826,6 +852,15 @@ private static final class SnapshotPredicates {
826852 } else if (fromSortValuePredicate != null ) {
827853 snapshotPredicate = fromSortValuePredicate .and (snapshotPredicate );
828854 }
855+ if (preflightPredicate == null ) {
856+ this .preflightPredicate = preflightPred ;
857+ } else {
858+ if (preflightPred != null ) {
859+ this .preflightPredicate = preflightPredicate .and (preflightPred );
860+ } else {
861+ this .preflightPredicate = preflightPredicate ;
862+ }
863+ }
829864 }
830865 this .snapshotPredicate = snapshotPredicate ;
831866 }
@@ -842,6 +877,19 @@ public BiPredicate<SnapshotId, RepositoryData> preflightPredicate() {
842877
843878 }
844879
880+ private interface SnapshotPredicate {
881+
882+ /**
883+ * Checks if a snapshot matches the predicate by testing its {@link SnapshotId} for a given {@link RepositoryData}.
884+ */
885+ boolean matchesPreflight (SnapshotId snapshotId , RepositoryData repositoryData );
886+
887+ /**
888+ * Checks if a snapshot matches the predicate by testing its {@link SnapshotInfo}.
889+ */
890+ boolean matches (SnapshotInfo snapshotInfo );
891+ }
892+
845893 private static final class SnapshotsInRepo {
846894
847895 private final List <SnapshotInfo > snapshotInfos ;
0 commit comments