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" )
@@ -163,25 +171,26 @@ public void initSearchClient() throws IOException {
163171 }
164172 clusterHosts = unmodifiableList (hosts );
165173 logger .info ("initializing REST search clients against {}" , clusterHosts );
166- searchClient = buildClient (restClientSettings (), clusterHosts .toArray (new HttpHost [clusterHosts . size () ]));
167- adminSearchClient = buildClient (restAdminSettings (), clusterHosts .toArray (new HttpHost [clusterHosts . size () ]));
174+ searchClient = buildClient (restClientSettings (), clusterHosts .toArray (new HttpHost [0 ]));
175+ adminSearchClient = buildClient (restAdminSettings (), clusterHosts .toArray (new HttpHost [0 ]));
168176
169177 searchYamlTestClient = new TestCandidateAwareClient (getRestSpec (), searchClient , hosts , this ::getClientBuilderWithSniffedHosts );
170178
171- // check that we have an established CCS connection
172- Request request = new Request ("GET" , "_remote/info" );
173- Response response = adminSearchClient .performRequest (request );
174- assertOK (response );
175- ObjectPath responseObject = ObjectPath .createFromResponse (response );
176- assertNotNull (responseObject .evaluate (REMOTE_CLUSTER_NAME ));
177- assertNull (responseObject .evaluate (REMOTE_CLUSTER_NAME + ".cluster_credentials" ));
178- logger .info ("Established connection to remote cluster [" + REMOTE_CLUSTER_NAME + "]" );
179+ assert searchClient != null ;
180+ assert adminSearchClient != null ;
181+ assert clusterHosts != null ;
182+
183+ if (isRemoteConfigured .compareAndSet (false , true )) {
184+ // check that we have an established CCS connection
185+ Request request = new Request ("GET" , "_remote/info" );
186+ Response response = adminSearchClient .performRequest (request );
187+ assertOK (response );
188+ ObjectPath responseObject = ObjectPath .createFromResponse (response );
189+ assertNotNull (responseObject .evaluate (REMOTE_CLUSTER_NAME ));
190+ assertNull (responseObject .evaluate (REMOTE_CLUSTER_NAME + ".cluster_credentials" ));
191+ logger .info ("Established connection to remote cluster [" + REMOTE_CLUSTER_NAME + "]" );
192+ }
179193 }
180-
181- assert searchClient != null ;
182- assert adminSearchClient != null ;
183- assert clusterHosts != null ;
184-
185194 searchYamlTestClient .setTestCandidate (getTestCandidate ());
186195 }
187196
@@ -299,44 +308,46 @@ protected ClientYamlTestExecutionContext createRestTestExecutionContext(
299308 final Set <String > osSet
300309 ) {
301310 try {
302- // Ensure the test specific initialization is run by calling it explicitly (@Before annotations on base-derived class may
303- // be called in a different order)
304- initSearchClient ();
305- // Reconcile and provide unified features, os, version(s), based on both clientYamlTestClient and searchYamlTestClient
306- var searchOs = readOsFromNodesInfo (adminSearchClient );
307- var searchNodeVersions = readVersionsFromNodesInfo (adminSearchClient );
308- var semanticNodeVersions = searchNodeVersions .stream ()
309- .map (ESRestTestCase ::parseLegacyVersion )
310- .flatMap (Optional ::stream )
311- .collect (Collectors .toSet ());
312- final TestFeatureService searchTestFeatureService = createTestFeatureService (
313- getClusterStateFeatures (adminSearchClient ),
314- semanticNodeVersions
315- );
316- final TestFeatureService combinedTestFeatureService = (featureId , any ) -> {
317- boolean adminFeature = testFeatureService .clusterHasFeature (featureId , any );
318- boolean searchFeature = searchTestFeatureService .clusterHasFeature (featureId , any );
319- return any ? adminFeature || searchFeature : adminFeature && searchFeature ;
320- };
321- final Set <String > combinedOsSet = Stream .concat (osSet .stream (), Stream .of (searchOs )).collect (Collectors .toSet ());
322- final Set <String > combinedNodeVersions = Stream .concat (nodesVersions .stream (), searchNodeVersions .stream ())
323- .collect (Collectors .toSet ());
311+ if (isCombinedComputed .compareAndSet (false , true )) {
312+ // Ensure the test specific initialization is run by calling it explicitly (@Before annotations on base-derived class may
313+ // be called in a different order)
314+ initSearchClient ();
315+ // Reconcile and provide unified features, os, version(s), based on both clientYamlTestClient and searchYamlTestClient
316+ var searchOs = readOsFromNodesInfo (adminSearchClient );
317+ var searchNodeVersions = readVersionsFromNodesInfo (adminSearchClient );
318+ var semanticNodeVersions = searchNodeVersions .stream ()
319+ .map (ESRestTestCase ::parseLegacyVersion )
320+ .flatMap (Optional ::stream )
321+ .collect (Collectors .toSet ());
322+ final TestFeatureService searchTestFeatureService = createTestFeatureService (
323+ getClusterStateFeatures (adminSearchClient ),
324+ semanticNodeVersions
325+ );
326+ final TestFeatureService combinedTestFeatureService = (featureId , any ) -> {
327+ boolean adminFeature = testFeatureService .clusterHasFeature (featureId , any );
328+ boolean searchFeature = searchTestFeatureService .clusterHasFeature (featureId , any );
329+ return any ? adminFeature || searchFeature : adminFeature && searchFeature ;
330+ };
331+ final Set <String > combinedOsSet = Stream .concat (osSet .stream (), Stream .of (searchOs )).collect (Collectors .toSet ());
332+ final Set <String > combinedNodeVersions = Stream .concat (nodesVersions .stream (), searchNodeVersions .stream ())
333+ .collect (Collectors .toSet ());
334+
335+ combinedTestFeatureServiceRef .set (combinedTestFeatureService );
336+ combinedOsSetRef .set (combinedOsSet );
337+ combinedNodeVersionsRef .set (combinedNodeVersions );
338+ }
324339
325340 return new ClientYamlTestExecutionContext (
326341 clientYamlTestCandidate ,
327342 clientYamlTestClient ,
328343 randomizeContentType (),
329- combinedNodeVersions ,
330- combinedTestFeatureService ,
331- combinedOsSet
344+ combinedNodeVersionsRef . get () ,
345+ combinedTestFeatureServiceRef . get () ,
346+ combinedOsSetRef . get ()
332347 ) {
333348 // depending on the API called, we either return the client running against the "write" or the "search" cluster here
334349 protected ClientYamlTestClient clientYamlTestClient (String apiName ) {
335- if (CCS_APIS .contains (apiName )) {
336- return searchYamlTestClient ;
337- } else {
338- return super .clientYamlTestClient (apiName );
339- }
350+ return CCS_APIS .contains (apiName ) ? searchYamlTestClient : super .clientYamlTestClient (apiName );
340351 }
341352 };
342353 } catch (IOException e ) {
0 commit comments