Skip to content

Commit c03cd53

Browse files
authored
Merge pull request #188 from AtomicMaps/add-opensearch
Opensearch 2.11.1 Support
2 parents 481f61e + ed469d3 commit c03cd53

File tree

18 files changed

+1226
-46
lines changed

18 files changed

+1226
-46
lines changed

.github/workflows/cicd.yml

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,22 @@ jobs:
4646
ES_JAVA_OPTS: -Xms512m -Xmx1g
4747
ports:
4848
- 9400:9400
49+
50+
opensearch_2_11:
51+
image: opensearchproject/opensearch:2.11.1
52+
env:
53+
cluster.name: stac-cluster
54+
node.name: os01
55+
network.host: 0.0.0.0
56+
transport.host: 0.0.0.0
57+
discovery.type: single-node
58+
http.port: 9202
59+
http.cors.enabled: true
60+
plugins.security.disabled: true
61+
plugins.security.ssl.http.enabled: true
62+
OPENSEARCH_JAVA_OPTS: -Xms512m -Xmx512m
63+
ports:
64+
- 9202:9202
4965
strategy:
5066
matrix:
5167
python-version: [ "3.8", "3.9", "3.10", "3.11"]
@@ -90,4 +106,15 @@ jobs:
90106
ES_PORT: 9400
91107
ES_HOST: 172.17.0.1
92108
ES_USE_SSL: false
93-
ES_VERIFY_CERTS: false
109+
ES_VERIFY_CERTS: false
110+
111+
- name: Run test suite against OpenSearch 2.11.1
112+
run: |
113+
cd stac_fastapi/elasticsearch && pipenv run pytest -svvv
114+
env:
115+
ENVIRONMENT: testing
116+
ES_PORT: 9202
117+
ES_HOST: 172.17.0.1
118+
ES_USE_SSL: false
119+
ES_VERIFY_CERTS: false
120+
BACKEND: opensearch

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1010
### Added
1111

1212
- Advanced comparison (LIKE, IN, BETWEEN) operators to the Filter extension [#178](https://github.com/stac-utils/stac-fastapi-elasticsearch/pull/178)
13+
- Collection update endpoint no longer delete all sub items [#177](https://github.com/stac-utils/stac-fastapi-elasticsearch/pull/177)
14+
- OpenSearch 2.11.1 support [#188](https://github.com/stac-utils/stac-fastapi-elasticsearch/pull/188)
1315

1416
### Changed
1517

Makefile

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
11
#!make
22
APP_HOST ?= 0.0.0.0
3-
APP_PORT ?= 8080
3+
ES_APP_PORT ?= 8080
44
EXTERNAL_APP_PORT ?= ${APP_PORT}
55

6-
APP_PORT ?= 8080
6+
ES_APP_PORT ?= 8080
77
ES_HOST ?= docker.for.mac.localhost
88
ES_PORT ?= 9200
99

10+
OS_APP_PORT ?= 8082
11+
ES_HOST ?= docker.for.mac.localhost
12+
OS_PORT ?= 9202
13+
1014
run_es = docker-compose \
1115
run \
12-
-p ${EXTERNAL_APP_PORT}:${APP_PORT} \
16+
-p ${EXTERNAL_APP_PORT}:${ES_APP_PORT} \
1317
-e PY_IGNORE_IMPORTMISMATCH=1 \
1418
-e APP_HOST=${APP_HOST} \
15-
-e APP_PORT=${APP_PORT} \
19+
-e APP_PORT=${ES_APP_PORT} \
1620
app-elasticsearch
1721

22+
run_os = docker-compose \
23+
run \
24+
-p ${EXTERNAL_APP_PORT}:${OS_APP_PORT} \
25+
-e PY_IGNORE_IMPORTMISMATCH=1 \
26+
-e APP_HOST=${APP_HOST} \
27+
-e APP_PORT=${OS_APP_PORT} \
28+
app-opensearch
29+
1830
.PHONY: image-deploy
1931
image-deploy:
2032
docker build -f Dockerfile.deploy -t stac-fastapi-elasticsearch:latest .
@@ -40,15 +52,32 @@ docker-run: image-dev
4052
docker-shell:
4153
$(run_es) /bin/bash
4254

55+
.PHONY: test-elasticsearch
56+
test:
57+
-$(run_es) /bin/bash -c 'export && ./scripts/wait-for-it-es.sh elasticsearch:9200 && cd /app/stac_fastapi/elasticsearch/tests/ && pytest'
58+
docker-compose down
59+
60+
.PHONY: test-opensearch
61+
test-opensearch:
62+
-$(run_os) /bin/bash -c 'export && ./scripts/wait-for-it-es.sh opensearch:9202 && cd /app/stac_fastapi/elasticsearch/tests/ && pytest'
63+
docker-compose down
64+
4365
.PHONY: test
4466
test:
4567
-$(run_es) /bin/bash -c 'export && ./scripts/wait-for-it-es.sh elasticsearch:9200 && cd /app/stac_fastapi/elasticsearch/tests/ && pytest'
4668
docker-compose down
4769

48-
.PHONY: run-database
49-
run-database:
70+
-$(run_os) /bin/bash -c 'export && ./scripts/wait-for-it-es.sh opensearch:9202 && cd /app/stac_fastapi/elasticsearch/tests/ && pytest'
71+
docker-compose down
72+
73+
.PHONY: run-database-es
74+
run-database-es:
5075
docker-compose run --rm elasticsearch
5176

77+
.PHONY: run-database-os
78+
run-database-os:
79+
docker-compose run --rm opensearch
80+
5281
.PHONY: pybase-install
5382
pybase-install:
5483
pip install wheel && \

README.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,15 @@ docker-compose build
4242
docker-compose up
4343
```
4444

45-
By default, docker-compose uses Elasticsearch 8.x. However, most recent 7.x versions should also work.
45+
By default, docker-compose uses Elasticsearch 8.x and OpenSearch 2.11.1.
4646
If you wish to use a different version, put the following in a
4747
file named `.env` in the same directory you run docker-compose from:
4848

4949
```shell
5050
ELASTICSEARCH_VERSION=7.17.1
51+
OPENSEARCH_VERSION=2.11.0
5152
```
53+
The most recent Elasticsearch 7.x versions should also work. See the [opensearch-py docs](https://github.com/opensearch-project/opensearch-py/blob/main/COMPATIBILITY.md) for compatibility information.
5254

5355
To create a new Collection:
5456

@@ -78,7 +80,18 @@ curl -X "GET" "http://localhost:8080/collections?limit=1&token=example_token"
7880
```shell
7981
make test
8082
```
81-
83+
Test against OpenSearch only
84+
85+
```shell
86+
make test-opensearch
87+
```
88+
89+
Test against Elasticsearch only
90+
91+
```shell
92+
make test-elasticsearch
93+
```
94+
8295
## Ingest sample data
8396

8497
```shell

data_loader/data_loader.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
"""Database ingestion script."""
22
import json
33
import os
4+
import sys
45

56
import click
67
import requests
78

9+
if len(sys.argv) != 2:
10+
print("Usage: python data_loader.py <opensearch|elasticsearch>")
11+
sys.exit(1)
12+
813
DATA_DIR = os.path.join(os.path.dirname(__file__), "setup_data/")
9-
STAC_API_BASE_URL = "http://localhost:8080"
14+
15+
backend = sys.argv[1].lower()
16+
if backend == "opensearch":
17+
STAC_API_BASE_URL = "http://localhost:8082"
18+
elif backend == "elasticsearch":
19+
STAC_API_BASE_URL = "http://localhost:8080"
20+
else:
21+
print("Invalid backend tag. Enter either 'opensearch' or 'elasticsearch'.")
1022

1123

1224
def load_data(filename):

docker-compose.yml

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ version: '3.9'
33
services:
44
app-elasticsearch:
55
container_name: stac-fastapi-es
6-
image: stac-utils/stac-fastapi
6+
image: stac-utils/stac-fastapi-es
77
restart: always
88
build:
99
context: .
@@ -18,6 +18,7 @@ services:
1818
- ES_PORT=9200
1919
- ES_USE_SSL=false
2020
- ES_VERIFY_CERTS=false
21+
- BACKEND=elasticsearch
2122
ports:
2223
- "8080:8080"
2324
volumes:
@@ -29,6 +30,35 @@ services:
2930
command:
3031
bash -c "./scripts/wait-for-it-es.sh es-container:9200 && python -m stac_fastapi.elasticsearch.app"
3132

33+
app-opensearch:
34+
container_name: stac-fastapi-os
35+
image: stac-utils/stac-fastapi-os
36+
restart: always
37+
build:
38+
context: .
39+
dockerfile: Dockerfile.dev
40+
environment:
41+
- APP_HOST=0.0.0.0
42+
- APP_PORT=8082
43+
- RELOAD=true
44+
- ENVIRONMENT=local
45+
- WEB_CONCURRENCY=10
46+
- ES_HOST=opensearch
47+
- ES_PORT=9202
48+
- ES_USE_SSL=false
49+
- ES_VERIFY_CERTS=false
50+
- BACKEND=opensearch
51+
ports:
52+
- "8082:8082"
53+
volumes:
54+
- ./stac_fastapi:/app/stac_fastapi
55+
- ./scripts:/app/scripts
56+
- ./osdata:/usr/share/opensearch/data
57+
depends_on:
58+
- opensearch
59+
command:
60+
bash -c "./scripts/wait-for-it-es.sh os-container:9202 && python -m stac_fastapi.elasticsearch.app"
61+
3262
elasticsearch:
3363
container_name: es-container
3464
image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTICSEARCH_VERSION:-8.11.0}
@@ -40,3 +70,17 @@ services:
4070
- ./elasticsearch/snapshots:/usr/share/elasticsearch/snapshots
4171
ports:
4272
- "9200:9200"
73+
74+
opensearch:
75+
container_name: os-container
76+
image: opensearchproject/opensearch:${OPENSEARCH_VERSION:-2.11.1}
77+
hostname: opensearch
78+
environment:
79+
- discovery.type=single-node
80+
- plugins.security.disabled=true
81+
- OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m
82+
volumes:
83+
- ./opensearch/config/opensearch.yml:/usr/share/opensearch/config/opensearch.yml
84+
- ./opensearch/snapshots:/usr/share/opensearch/snapshots
85+
ports:
86+
- "9202:9202"

opensearch/config/opensearch.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
## Cluster Settings
2+
cluster.name: stac-cluster
3+
node.name: os01
4+
network.host: 0.0.0.0
5+
transport.host: 0.0.0.0
6+
discovery.type: single-node
7+
http.port: 9202
8+
http.cors.enabled: true
9+
http.cors.allow-headers: X-Requested-With,Content-Type,Content-Length,Accept,Authorization
10+
11+
path:
12+
repo:
13+
- /usr/share/opensearch/snapshots
14+
15+
# Security
16+
plugins.security.disabled: true
17+
plugins.security.ssl.http.enabled: true
18+
19+
node.max_local_storage_nodes: 3

stac_fastapi/elasticsearch/setup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
"stac-fastapi.extensions==2.4.9",
1616
"elasticsearch[async]==8.11.0",
1717
"elasticsearch-dsl==8.11.0",
18+
"opensearch-py==2.4.2",
19+
"opensearch-py[async]==2.4.2",
1820
"pystac[validation]",
1921
"uvicorn",
2022
"orjson",

stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/app.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
11
"""FastAPI application."""
2+
import os
3+
24
from stac_fastapi.api.app import StacApi
35
from stac_fastapi.api.models import create_get_request_model, create_post_request_model
4-
from stac_fastapi.elasticsearch.config import ElasticsearchSettings
56
from stac_fastapi.elasticsearch.core import (
67
BulkTransactionsClient,
78
CoreClient,
89
EsAsyncBaseFiltersClient,
910
TransactionsClient,
1011
)
11-
from stac_fastapi.elasticsearch.database_logic import create_collection_index
12+
13+
if os.getenv("BACKEND", "elasticsearch").lower() == "opensearch":
14+
from stac_fastapi.elasticsearch.config.config_opensearch import SearchSettings
15+
from stac_fastapi.elasticsearch.database_logic.database_logic_opensearch import (
16+
create_collection_index,
17+
)
18+
else:
19+
from stac_fastapi.elasticsearch.config.config_elasticsearch import SearchSettings
20+
from stac_fastapi.elasticsearch.database_logic.database_logic_elasticsearch import (
21+
create_collection_index,
22+
)
23+
1224
from stac_fastapi.elasticsearch.extensions import QueryExtension
1325
from stac_fastapi.elasticsearch.session import Session
1426
from stac_fastapi.extensions.core import (
@@ -21,7 +33,7 @@
2133
)
2234
from stac_fastapi.extensions.third_party import BulkTransactionExtension
2335

24-
settings = ElasticsearchSettings()
36+
settings = SearchSettings()
2537
session = Session.create_from_settings(settings)
2638

2739
filter_extension = FilterExtension(client=EsAsyncBaseFiltersClient())
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""client config implementations."""

stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/config.py renamed to stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/config/config_elasticsearch.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def _es_config() -> Dict[str, Any]:
5454
_forbidden_fields: Set[str] = {"type"}
5555

5656

57-
class ElasticsearchSettings(ApiSettings):
57+
class SearchSettings(ApiSettings):
5858
"""API settings."""
5959

6060
# Fields which are defined by STAC but not included in the database model
@@ -67,7 +67,7 @@ def create_client(self):
6767
return Elasticsearch(**_es_config())
6868

6969

70-
class AsyncElasticsearchSettings(ApiSettings):
70+
class AsyncSearchSettings(ApiSettings):
7171
"""API settings."""
7272

7373
# Fields which are defined by STAC but not included in the database model

0 commit comments

Comments
 (0)