1818import org .elasticsearch .common .Strings ;
1919import org .elasticsearch .common .TriFunction ;
2020import org .elasticsearch .common .bytes .ReleasableBytesReference ;
21+ import org .elasticsearch .common .logging .HeaderWarning ;
2122import org .elasticsearch .common .settings .Settings ;
2223import org .elasticsearch .core .Tuple ;
2324import org .elasticsearch .features .NodeFeature ;
2829import org .elasticsearch .rest .action .RestCancellableNodeClient ;
2930import org .elasticsearch .rest .action .RestRefCountedChunkedToXContentListener ;
3031import org .elasticsearch .search .builder .SearchSourceBuilder ;
32+ import org .elasticsearch .search .crossproject .CrossProjectModeDecider ;
3133import org .elasticsearch .usage .SearchUsageHolder ;
3234import org .elasticsearch .xcontent .XContent ;
3335import org .elasticsearch .xcontent .XContentParser ;
@@ -48,13 +50,15 @@ public class RestMultiSearchAction extends BaseRestHandler {
4850 private final boolean allowExplicitIndex ;
4951 private final SearchUsageHolder searchUsageHolder ;
5052 private final Predicate <NodeFeature > clusterSupportsFeature ;
51- private final Settings settings ;
53+ private final CrossProjectModeDecider crossProjectModeDecider ;
54+ private static final String MRT_ENABLED_IN_CPS_WARN = "ccs_minimize_roundtrips always defaults to true in Cross Project Search context."
55+ + " Setting it explicitly has no effect irrespective of the value specified and is ignored." ;
5256
5357 public RestMultiSearchAction (Settings settings , SearchUsageHolder searchUsageHolder , Predicate <NodeFeature > clusterSupportsFeature ) {
54- this .settings = settings ;
5558 this .allowExplicitIndex = MULTI_ALLOW_EXPLICIT_INDEX .get (settings );
5659 this .searchUsageHolder = searchUsageHolder ;
5760 this .clusterSupportsFeature = clusterSupportsFeature ;
61+ this .crossProjectModeDecider = new CrossProjectModeDecider (settings );
5862 }
5963
6064 @ Override
@@ -77,11 +81,18 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC
7781 if (client .threadPool () != null && client .threadPool ().getThreadContext () != null ) {
7882 client .threadPool ().getThreadContext ().setErrorTraceTransportHeader (request );
7983 }
80- if (settings != null && settings .getAsBoolean ("serverless.cross_project.enabled" , false )) {
84+ boolean crossProjectEnabled = crossProjectModeDecider .crossProjectEnabled ();
85+ if (crossProjectEnabled ) {
8186 // accept but drop project_routing param until fully supported
8287 request .param ("project_routing" );
8388 }
84- final MultiSearchRequest multiSearchRequest = parseRequest (request , allowExplicitIndex , searchUsageHolder , clusterSupportsFeature );
89+ final MultiSearchRequest multiSearchRequest = parseRequest (
90+ request ,
91+ allowExplicitIndex ,
92+ searchUsageHolder ,
93+ clusterSupportsFeature ,
94+ crossProjectEnabled
95+ );
8596 return channel -> {
8697 final RestCancellableNodeClient cancellableClient = new RestCancellableNodeClient (client , request .getHttpChannel ());
8798 cancellableClient .execute (
@@ -99,9 +110,17 @@ public static MultiSearchRequest parseRequest(
99110 RestRequest restRequest ,
100111 boolean allowExplicitIndex ,
101112 SearchUsageHolder searchUsageHolder ,
102- Predicate <NodeFeature > clusterSupportsFeature
113+ Predicate <NodeFeature > clusterSupportsFeature ,
114+ boolean crossProjectEnabled
103115 ) throws IOException {
104- return parseRequest (restRequest , allowExplicitIndex , searchUsageHolder , clusterSupportsFeature , (k , v , r ) -> false );
116+ return parseRequest (
117+ restRequest ,
118+ allowExplicitIndex ,
119+ searchUsageHolder ,
120+ clusterSupportsFeature ,
121+ (k , v , r ) -> false ,
122+ crossProjectEnabled
123+ );
105124 }
106125
107126 /**
@@ -113,7 +132,8 @@ public static MultiSearchRequest parseRequest(
113132 boolean allowExplicitIndex ,
114133 SearchUsageHolder searchUsageHolder ,
115134 Predicate <NodeFeature > clusterSupportsFeature ,
116- TriFunction <String , Object , SearchRequest , Boolean > extraParamParser
135+ TriFunction <String , Object , SearchRequest , Boolean > extraParamParser ,
136+ boolean crossProjectEnabled
117137 ) throws IOException {
118138 MultiSearchRequest multiRequest = new MultiSearchRequest ();
119139 IndicesOptions indicesOptions = IndicesOptions .fromRequest (restRequest , multiRequest .indicesOptions ());
@@ -142,12 +162,10 @@ public static MultiSearchRequest parseRequest(
142162 if (searchRequest .pointInTimeBuilder () != null ) {
143163 RestSearchAction .preparePointInTime (searchRequest , restRequest );
144164 } else {
145- searchRequest .setCcsMinimizeRoundtrips (
146- restRequest .paramAsBoolean ("ccs_minimize_roundtrips" , searchRequest .isCcsMinimizeRoundtrips ())
147- );
165+ searchRequest .setCcsMinimizeRoundtrips (maybeConsumeCcsMrtParam (restRequest , crossProjectEnabled ));
148166 }
149167 multiRequest .add (searchRequest );
150- }, extraParamParser );
168+ }, extraParamParser , crossProjectEnabled );
151169 List <SearchRequest > requests = multiRequest .requests ();
152170 for (SearchRequest request : requests ) {
153171 // preserve if it's set on the request
@@ -168,9 +186,10 @@ public static void parseMultiLineRequest(
168186 RestRequest request ,
169187 IndicesOptions indicesOptions ,
170188 boolean allowExplicitIndex ,
171- CheckedBiConsumer <SearchRequest , XContentParser , IOException > consumer
189+ CheckedBiConsumer <SearchRequest , XContentParser , IOException > consumer ,
190+ boolean crossProjectEnabled
172191 ) throws IOException {
173- parseMultiLineRequest (request , indicesOptions , allowExplicitIndex , consumer , (k , v , r ) -> false );
192+ parseMultiLineRequest (request , indicesOptions , allowExplicitIndex , consumer , (k , v , r ) -> false , crossProjectEnabled );
174193 }
175194
176195 /**
@@ -182,12 +201,13 @@ public static void parseMultiLineRequest(
182201 IndicesOptions indicesOptions ,
183202 boolean allowExplicitIndex ,
184203 CheckedBiConsumer <SearchRequest , XContentParser , IOException > consumer ,
185- TriFunction <String , Object , SearchRequest , Boolean > extraParamParser
204+ TriFunction <String , Object , SearchRequest , Boolean > extraParamParser ,
205+ boolean crossProjectEnabled
186206 ) throws IOException {
187207
188208 String [] indices = Strings .splitStringByCommaToArray (request .param ("index" ));
189209 String searchType = request .param ("search_type" );
190- boolean ccsMinimizeRoundtrips = request . paramAsBoolean ( "ccs_minimize_roundtrips" , true );
210+ boolean ccsMinimizeRoundtrips = maybeConsumeCcsMrtParam ( request , crossProjectEnabled );
191211 String routing = request .param ("routing" );
192212
193213 final Tuple <XContentType , ReleasableBytesReference > sourceTuple = request .contentOrSourceParam ();
@@ -208,6 +228,26 @@ public static void parseMultiLineRequest(
208228 );
209229 }
210230
231+ private static boolean maybeConsumeCcsMrtParam (RestRequest request , boolean crossProjectEnabled ) {
232+ if (crossProjectEnabled ) {
233+ // Warn user, consume param, and return true.
234+ if (request .hasParam ("ccs_minimize_roundtrips" )) {
235+ HeaderWarning .addWarning (RestMultiSearchAction .MRT_ENABLED_IN_CPS_WARN );
236+ request .param ("ccs_minimize_roundtrips" );
237+ return true ;
238+ }
239+
240+ /*
241+ * User has no preference, use the default value that's appropriate for CPS.
242+ * CPS searches should minimise round trips.
243+ */
244+ return true ;
245+ } else {
246+ // Not in CPS environment, pick whatever user chose.
247+ return request .paramAsBoolean ("ccs_minimize_roundtrips" , true );
248+ }
249+ }
250+
211251 @ Override
212252 public boolean mediaTypesValid (RestRequest request ) {
213253 return super .mediaTypesValid (request ) && XContentType .supportsDelimitedBulkRequests (request .getXContentType ());
0 commit comments