@@ -81,8 +81,8 @@ public SearchAccessor getSearchAccessor() {
8181
8282 InfoResponse infoResponse = null ;
8383
84- PluginComponentRefresher <ElasticsearchClient , OpenSearchSourceConfiguration > elasticsearchClientRefresher =
85- null ;
84+ PluginComponentRefresher <ElasticsearchClient , OpenSearchSourceConfiguration > elasticsearchClientRefresher = null ;
85+
8686 try {
8787 infoResponse = clientRefresher .get ().info ();
8888 pluginConfigObservable .addPluginConfigObserver (newConfig -> clientRefresher .update (
@@ -135,12 +135,33 @@ public SearchAccessor getSearchAccessor() {
135135 searchContextType = SearchContextType .SCROLL ;
136136 }
137137
138- if (Objects .isNull (elasticsearchClientRefresher )) {
139- return new OpenSearchAccessor (clientRefresher ,
140- searchContextType );
138+ if (OPENSEARCH_DISTRIBUTION .equals (distribution )) {
139+ LOG .debug ("Using OpenSearchAccessor as the determined distribution is OpenSearch." );
140+ return new OpenSearchAccessor (clientRefresher , searchContextType );
141+ } else {
142+ LOG .debug ("Using ElasticsearchAccessor as the determined distribution is Elasticsearch." );
143+ PluginComponentRefresher <ElasticsearchClient , OpenSearchSourceConfiguration > currentElasticsearchClientRefresher = elasticsearchClientRefresher ;
144+ if (Objects .isNull (currentElasticsearchClientRefresher )) {
145+ LOG .info ("Elasticsearch distribution determined, but no existing Elasticsearch client refresher found (e.g., OpenSearch client reported Elasticsearch, or distribution_version was set to elasticsearch). Creating a new Elasticsearch client refresher." );
146+ try {
147+ currentElasticsearchClientRefresher = new ClientRefresher <>(openSearchSourcePluginMetrics ,
148+ ElasticsearchClient .class , openSearchClientFactory ::provideElasticSearchClient ,
149+ openSearchSourceConfiguration );
150+ final PluginComponentRefresher <ElasticsearchClient , OpenSearchSourceConfiguration >
151+ finalNewElasticsearchClientRefresher = currentElasticsearchClientRefresher ;
152+ pluginConfigObservable .addPluginConfigObserver (
153+ newConfig -> {
154+ if (finalNewElasticsearchClientRefresher != null ) {
155+ finalNewElasticsearchClientRefresher .update ((OpenSearchSourceConfiguration ) newConfig );
156+ }
157+ });
158+ } catch (final Exception e ) {
159+ LOG .error ("Failed to create Elasticsearch client for an Elasticsearch distribution when one was not pre-existing." , e );
160+ throw new RuntimeException ("Failed to create Elasticsearch client for an Elasticsearch distribution: " + e .getMessage (), e );
161+ }
162+ }
163+ return new ElasticsearchAccessor (currentElasticsearchClientRefresher , searchContextType );
141164 }
142-
143- return new ElasticsearchAccessor (elasticsearchClientRefresher , searchContextType );
144165 }
145166
146167 private SearchAccessor createSearchAccessorForServerlessCollection (final PluginComponentRefresher clientRefresher ) {
@@ -189,14 +210,58 @@ private boolean versionSupportsPointInTime(final String distribution, final Stri
189210 private Pair <String , String > getDistributionAndVersionNumber (final InfoResponse infoResponseOpenSearch ,
190211 final PluginComponentRefresher <ElasticsearchClient , OpenSearchSourceConfiguration > elasticsearchClientRefresher ) {
191212 if (Objects .nonNull (infoResponseOpenSearch )) {
192- return Pair .of (infoResponseOpenSearch .version ().distribution (), infoResponseOpenSearch .version ().number ());
213+ final String distribution = infoResponseOpenSearch .version ().distribution ();
214+ final String versionNumber = infoResponseOpenSearch .version ().number ();
215+ if (Objects .nonNull (distribution ) && Objects .nonNull (versionNumber )) {
216+ LOG .info ("Detected OpenSearch distribution '{}' version '{}' from API response." , distribution , versionNumber );
217+ return Pair .of (distribution , versionNumber );
218+ }
219+ LOG .warn ("Distribution or version number is null in OpenSearch API response. Proceeding to check Elasticsearch or default." );
193220 }
194221
195- try {
196- final co .elastic .clients .elasticsearch .core .InfoResponse infoResponseElasticsearch = elasticsearchClientRefresher .get ().info ();
197- return Pair .of (ELASTICSEARCH_DISTRIBUTION + "-" + infoResponseElasticsearch .version ().buildFlavor (), infoResponseElasticsearch .version ().number ());
198- } catch (final Exception e ) {
199- throw new RuntimeException ("Unable to call info API using the elasticsearch client" , e );
222+ if (elasticsearchClientRefresher != null ) {
223+ try {
224+ final ElasticsearchClient elasticsearchClient = elasticsearchClientRefresher .get ();
225+ if (elasticsearchClient == null ) {
226+ LOG .info ("ElasticsearchClient from refresher is null. Cannot attempt Elasticsearch .info() call. Proceeding to default." );
227+ } else {
228+ final co .elastic .clients .elasticsearch .core .InfoResponse infoResponseElasticsearch = elasticsearchClient .info ();
229+ final String esBuildFlavor = infoResponseElasticsearch .version ().buildFlavor ();
230+ final String esVersionNumber = infoResponseElasticsearch .version ().number ();
231+
232+ if (Objects .nonNull (esVersionNumber )) {
233+ String effectiveDistribution = ELASTICSEARCH_DISTRIBUTION ;
234+ LOG .info ("Detected Elasticsearch (flavor '{}') version '{}' from API response." ,
235+ Objects .toString (esBuildFlavor , "unknown" ), esVersionNumber );
236+ if (ELASTICSEARCH_OSS_BUILD_FLAVOR .equalsIgnoreCase (esBuildFlavor )) {
237+ effectiveDistribution = ELASTICSEARCH_DISTRIBUTION + "-" + ELASTICSEARCH_OSS_BUILD_FLAVOR ;
238+ }
239+ return Pair .of (effectiveDistribution , esVersionNumber );
240+ }
241+ LOG .warn ("Version number is null in Elasticsearch API response. Proceeding to default." );
242+ }
243+ } catch (final Exception e ) {
244+ LOG .warn ("Failed to get cluster info using Elasticsearch client. Will proceed with default behavior." , e );
245+ }
246+ } else {
247+ LOG .info ("Elasticsearch client refresher is null, skipping Elasticsearch .info() call." );
248+ }
249+
250+ if (openSearchSourceConfiguration .getDistributionVersion () == null ) {
251+ LOG .warn ("Failed to auto-detect cluster distribution from API response for both OpenSearch and (if attempted) Elasticsearch clients. " +
252+ "Defaulting to OpenSearch distribution. Consider setting 'distribution_version' in the configuration if this is not an OpenSearch cluster." );
253+ return Pair .of (OPENSEARCH_DISTRIBUTION , OPENSEARCH_POINT_IN_TIME_SUPPORT_VERSION_CUTOFF );
254+ } else {
255+ final String configuredDistributionName = openSearchSourceConfiguration .getDistributionVersion ().name ();
256+ LOG .error ("Failed to connect to the cluster and verify its distribution. The 'distribution_version' was configured as '{}', " +
257+ "but communication attempts with the cluster failed or the cluster did not respond as expected for this distribution type. " +
258+ "Please check the endpoint, network connectivity, and the specified 'distribution_version'." ,
259+ configuredDistributionName );
260+ throw new InvalidPluginConfigurationException (
261+ String .format ("Failed to connect to the cluster and verify its distribution. The 'distribution_version' was configured as '%s', " +
262+ "but communication attempts with the cluster failed or the cluster did not respond as expected for this distribution type. " +
263+ "Please check the endpoint, network connectivity, and the specified 'distribution_version'." ,
264+ configuredDistributionName ));
200265 }
201266 }
202267
0 commit comments