From 39d58cef2fddd48337fd1cde26c8eb0b9a39f5c6 Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Wed, 15 Dec 2021 13:46:02 -0600 Subject: [PATCH] Add a warning when connecting to imcompatible Elasticsearch versions --- README.md | 1 + docs/guide/overview.asciidoc | 4 ++++ eland/common.py | 19 +++++++++++++---- tests/test_common_pytest.py | 40 ++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 tests/test_common_pytest.py diff --git a/README.md b/README.md index b6229379..b28d0b6c 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ $ conda install -c conda-forge eland - Supports Python 3.7+ and Pandas 1.3 - Supports Elasticsearch clusters that are 7.11+, recommended 7.14 or later for all features to work. + Make sure your Eland major version matches the major version of your Elasticsearch cluster. ### Prerequisites diff --git a/docs/guide/overview.asciidoc b/docs/guide/overview.asciidoc index a4990a12..48b841f5 100644 --- a/docs/guide/overview.asciidoc +++ b/docs/guide/overview.asciidoc @@ -10,10 +10,14 @@ Source code is available on https://github.com/elastic/eland[GitHub]. - Supports Python 3.7+ and Pandas 1.3 - Supports {es} clusters that are 7.11+, recommended 7.14 or later for all features to work. + Make sure your Eland major version matches the major version of your Elasticsearch cluster. The recommended way to set your requirements in your `setup.py` or `requirements.txt` is:: + # Elasticsearch 8.x + eland>=8,<9 + # Elasticsearch 7.x eland>=7,<8 diff --git a/eland/common.py b/eland/common.py index 93a283ac..125b79de 100644 --- a/eland/common.py +++ b/eland/common.py @@ -32,7 +32,8 @@ import pandas as pd # type: ignore from elasticsearch import Elasticsearch -from elasticsearch import __version__ as ES_CLIENT_VERSION + +from ._version import __version__ as _eland_version if TYPE_CHECKING: from numpy.typing import DTypeLike @@ -49,9 +50,7 @@ int(part) for part in pd.__version__.split(".") if part.isdigit() )[:2] -# Starting in 7.15 the client raises DeprecationWarnings -# for some APIs using the 'body' parameter. -ES_CLIENT_HAS_V8_0_DEPRECATIONS = ES_CLIENT_VERSION >= (7, 15) +_ELAND_MAJOR_VERSION = int(_eland_version.split(".")[0]) with warnings.catch_warnings(): @@ -333,6 +332,18 @@ def es_version(es_client: Elasticsearch) -> Tuple[int, int, int]: Tuple[int, int, int], tuple(int(x) for x in match.groups()) ) es_client._eland_es_version = eland_es_version # type: ignore + + # Raise a warning if the major version of the library doesn't match the + # the Elasticsearch server major version. + if eland_es_version[0] != _ELAND_MAJOR_VERSION: + warnings.warn( + f"Eland major version ({_eland_version}) doesn't match the major " + f"version of the Elasticsearch server ({version_info}) which can lead " + f"to compatibility issues. Your Eland major version should be the same " + "as your cluster major version.", + stacklevel=2, + ) + else: eland_es_version = es_client._eland_es_version # type: ignore return eland_es_version diff --git a/tests/test_common_pytest.py b/tests/test_common_pytest.py new file mode 100644 index 00000000..841d415d --- /dev/null +++ b/tests/test_common_pytest.py @@ -0,0 +1,40 @@ +# Licensed to Elasticsearch B.V. under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Elasticsearch B.V. licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +import unittest.mock as mock +import warnings + +import pytest + +import eland +from eland.common import es_version + + +@pytest.mark.parametrize( + ["version_number", "version_tuple"], + [("7.10.0-alpha1", (7, 10, 0)), ("99.99.99", (99, 99, 99))], +) +def test_major_version_mismatch(version_number, version_tuple): + client = mock.Mock(spec=["info"]) + client.info.return_value = {"version": {"number": version_number}} + with warnings.catch_warnings(record=True) as w: + assert es_version(client) == version_tuple + assert len(w) == 1 + assert str(w[0].message) == ( + f"Eland major version ({eland.__version__}) doesn't match the major version of the Elasticsearch server ({version_number}) " + "which can lead to compatibility issues. Your Eland major version should be the same as your cluster major version." + )