Common Method Implementation for Elasticsearch and OpenSearch Java SDK

31 Views Asked by At

Let's say I have an application supporting either Elasticsearch or OpenSearch service. I have a SearchClient interface with implementation for the specific client (i.e., ES or OS). Every method implements the same logic, but only the type is different.

Is it possible and what would be a recommend approach in Java to remove duplication of code and centralize the core logic? I understand there are recommendations around extracting the lowest common ancestor, but in this case it would end up being Object. I have also explored the possibility of using an Adapter class, but ended up in the same position where the return type of the adapter would be tie to the client type.

Code

public interface SearchClient {
[...]
  void update(
      String indexName,
      Pair<String, String> fieldAndValue,
      Pair<String, Map<String, Object>> updates);
[...]
}
public class ElasticSearchClient implements SearchClient {
[...]
  @Override
  public void update(
      String indexName,
      Pair<String, String> fieldAndValue,
      Pair<String, Map<String, Object>> updates) {
    if (isClientAvailable) {
      UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(indexName);
      updateByQueryRequest.setQuery(
          new MatchQueryBuilder(fieldAndValue.getKey(), fieldAndValue.getValue())
              .operator(Operator.AND));
      Script script =
          new Script(
              ScriptType.INLINE,
              Script.DEFAULT_SCRIPT_LANG,
              updates.getKey(),
              JsonUtils.getMap(updates.getValue() == null ? new HashMap<>() : updates.getValue()));
      updateByQueryRequest.setScript(script);
      updateElasticSearchByQuery(updateByQueryRequest);
    }
  }
}
[...]
public class OpenSearchClient implements SearchClient {
[...]
  @Override
  public void update(
      String indexName,
      Pair<String, String> fieldAndValue,
      Pair<String, Map<String, Object>> updates) {
    if (isClientAvailable) {
      UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(indexName);
      updateByQueryRequest.setQuery(
          new MatchQueryBuilder(fieldAndValue.getKey(), fieldAndValue.getValue())
              .operator(Operator.AND));
      Script script =
          new Script(
              ScriptType.INLINE,
              Script.DEFAULT_SCRIPT_LANG,
              updates.getKey(),
              JsonUtils.getMap(updates.getValue() == null ? new HashMap<>() : updates.getValue()));
      updateByQueryRequest.setScript(script);
      updateElasticSearchByQuery(updateByQueryRequest);
    }
  }
}
[...]
0

There are 0 best solutions below