5252import java .util .Map ;
5353import java .util .Optional ;
5454import java .util .Set ;
55+ import java .util .concurrent .atomic .AtomicBoolean ;
56+ import java .util .concurrent .atomic .AtomicReference ;
5557import java .util .function .BiPredicate ;
5658import java .util .stream .Collectors ;
5759import java .util .stream .Stream ;
@@ -78,6 +80,12 @@ public class CcsCommonYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
7880 // the remote cluster is the one we write index operations etc... to
7981 private static final String REMOTE_CLUSTER_NAME = "remote_cluster" ;
8082
83+ private static final AtomicBoolean isRemoteConfigured = new AtomicBoolean (false );
84+ private static final AtomicBoolean isCombinedComputed = new AtomicBoolean (false );
85+ private static final AtomicReference <TestFeatureService > combinedTestFeatureServiceRef = new AtomicReference <>();
86+ private static final AtomicReference <Set <String >> combinedOsSetRef = new AtomicReference <>();
87+ private static final AtomicReference <Set <String >> combinedNodeVersionsRef = new AtomicReference <>();
88+
8189 private static LocalClusterConfigProvider commonClusterConfig = cluster -> cluster .module ("x-pack-async-search" )
8290 .module ("aggregations" )
8391 .module ("analysis-common" )
@@ -162,25 +170,26 @@ public void initSearchClient() throws IOException {
162170 }
163171 clusterHosts = unmodifiableList (hosts );
164172 logger .info ("initializing REST search clients against {}" , clusterHosts );
165- searchClient = buildClient (restClientSettings (), clusterHosts .toArray (new HttpHost [clusterHosts . size () ]));
166- adminSearchClient = buildClient (restAdminSettings (), clusterHosts .toArray (new HttpHost [clusterHosts . size () ]));
173+ searchClient = buildClient (restClientSettings (), clusterHosts .toArray (new HttpHost [0 ]));
174+ adminSearchClient = buildClient (restAdminSettings (), clusterHosts .toArray (new HttpHost [0 ]));
167175
168176 searchYamlTestClient = new TestCandidateAwareClient (getRestSpec (), searchClient , hosts , this ::getClientBuilderWithSniffedHosts );
169177
170- // check that we have an established CCS connection
171- Request request = new Request ("GET" , "_remote/info" );
172- Response response = adminSearchClient .performRequest (request );
173- assertOK (response );
174- ObjectPath responseObject = ObjectPath .createFromResponse (response );
175- assertNotNull (responseObject .evaluate (REMOTE_CLUSTER_NAME ));
176- assertNull (responseObject .evaluate (REMOTE_CLUSTER_NAME + ".cluster_credentials" ));
177- logger .info ("Established connection to remote cluster [" + REMOTE_CLUSTER_NAME + "]" );
178+ assert searchClient != null ;
179+ assert adminSearchClient != null ;
180+ assert clusterHosts != null ;
181+
182+ if (isRemoteConfigured .compareAndSet (false , true )) {
183+ // check that we have an established CCS connection
184+ Request request = new Request ("GET" , "_remote/info" );
185+ Response response = adminSearchClient .performRequest (request );
186+ assertOK (response );
187+ ObjectPath responseObject = ObjectPath .createFromResponse (response );
188+ assertNotNull (responseObject .evaluate (REMOTE_CLUSTER_NAME ));
189+ assertNull (responseObject .evaluate (REMOTE_CLUSTER_NAME + ".cluster_credentials" ));
190+ logger .info ("Established connection to remote cluster [" + REMOTE_CLUSTER_NAME + "]" );
191+ }
178192 }
179-
180- assert searchClient != null ;
181- assert adminSearchClient != null ;
182- assert clusterHosts != null ;
183-
184193 searchYamlTestClient .setTestCandidate (getTestCandidate ());
185194 }
186195
@@ -298,44 +307,46 @@ protected ClientYamlTestExecutionContext createRestTestExecutionContext(
298307 final Set <String > osSet
299308 ) {
300309 try {
301- // Ensure the test specific initialization is run by calling it explicitly (@Before annotations on base-derived class may
302- // be called in a different order)
303- initSearchClient ();
304- // Reconcile and provide unified features, os, version(s), based on both clientYamlTestClient and searchYamlTestClient
305- var searchOs = readOsFromNodesInfo (adminSearchClient );
306- var searchNodeVersions = readVersionsFromNodesInfo (adminSearchClient );
307- var semanticNodeVersions = searchNodeVersions .stream ()
308- .map (ESRestTestCase ::parseLegacyVersion )
309- .flatMap (Optional ::stream )
310- .collect (Collectors .toSet ());
311- final TestFeatureService searchTestFeatureService = createTestFeatureService (
312- getClusterStateFeatures (adminSearchClient ),
313- semanticNodeVersions
314- );
315- final TestFeatureService combinedTestFeatureService = (featureId , any ) -> {
316- boolean adminFeature = testFeatureService .clusterHasFeature (featureId , any );
317- boolean searchFeature = searchTestFeatureService .clusterHasFeature (featureId , any );
318- return any ? adminFeature || searchFeature : adminFeature && searchFeature ;
319- };
320- final Set <String > combinedOsSet = Stream .concat (osSet .stream (), Stream .of (searchOs )).collect (Collectors .toSet ());
321- final Set <String > combinedNodeVersions = Stream .concat (nodesVersions .stream (), searchNodeVersions .stream ())
322- .collect (Collectors .toSet ());
310+ if (isCombinedComputed .compareAndSet (false , true )) {
311+ // Ensure the test specific initialization is run by calling it explicitly (@Before annotations on base-derived class may
312+ // be called in a different order)
313+ initSearchClient ();
314+ // Reconcile and provide unified features, os, version(s), based on both clientYamlTestClient and searchYamlTestClient
315+ var searchOs = readOsFromNodesInfo (adminSearchClient );
316+ var searchNodeVersions = readVersionsFromNodesInfo (adminSearchClient );
317+ var semanticNodeVersions = searchNodeVersions .stream ()
318+ .map (ESRestTestCase ::parseLegacyVersion )
319+ .flatMap (Optional ::stream )
320+ .collect (Collectors .toSet ());
321+ final TestFeatureService searchTestFeatureService = createTestFeatureService (
322+ getClusterStateFeatures (adminSearchClient ),
323+ semanticNodeVersions
324+ );
325+ final TestFeatureService combinedTestFeatureService = (featureId , any ) -> {
326+ boolean adminFeature = testFeatureService .clusterHasFeature (featureId , any );
327+ boolean searchFeature = searchTestFeatureService .clusterHasFeature (featureId , any );
328+ return any ? adminFeature || searchFeature : adminFeature && searchFeature ;
329+ };
330+ final Set <String > combinedOsSet = Stream .concat (osSet .stream (), Stream .of (searchOs )).collect (Collectors .toSet ());
331+ final Set <String > combinedNodeVersions = Stream .concat (nodesVersions .stream (), searchNodeVersions .stream ())
332+ .collect (Collectors .toSet ());
333+
334+ combinedTestFeatureServiceRef .set (combinedTestFeatureService );
335+ combinedOsSetRef .set (combinedOsSet );
336+ combinedNodeVersionsRef .set (combinedNodeVersions );
337+ }
323338
324339 return new ClientYamlTestExecutionContext (
325340 clientYamlTestCandidate ,
326341 clientYamlTestClient ,
327342 randomizeContentType (),
328- combinedNodeVersions ,
329- combinedTestFeatureService ,
330- combinedOsSet
343+ combinedNodeVersionsRef . get () ,
344+ combinedTestFeatureServiceRef . get () ,
345+ combinedOsSetRef . get ()
331346 ) {
332347 // depending on the API called, we either return the client running against the "write" or the "search" cluster here
333348 protected ClientYamlTestClient clientYamlTestClient (String apiName ) {
334- if (CCS_APIS .contains (apiName )) {
335- return searchYamlTestClient ;
336- } else {
337- return super .clientYamlTestClient (apiName );
338- }
349+ return CCS_APIS .contains (apiName ) ? searchYamlTestClient : super .clientYamlTestClient (apiName );
339350 }
340351 };
341352 } catch (IOException e ) {
0 commit comments