diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 668fc8b7b5..fca481b3e3 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -7,16 +7,18 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
- java: [ 11 ]
+ java: [ 11, 17, 21 ]
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
+ - name: Checkout Java Client
+ uses: actions/checkout@v3
+
- name: Set up JDK ${{ matrix.java }}
- uses: actions/setup-java@v1
+ uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java }}
-
- - name: Checkout Branch
- uses: actions/checkout@v2
+ distribution: 'temurin'
+ cache: 'gradle'
- name: Build with Gradle
run: ./gradlew clean build -x test
diff --git a/.github/workflows/changelog_verifier.yml b/.github/workflows/changelog_verifier.yml
index 96f99f17b0..992a38b624 100644
--- a/.github/workflows/changelog_verifier.yml
+++ b/.github/workflows/changelog_verifier.yml
@@ -15,4 +15,4 @@ jobs:
- uses: dangoslen/changelog-enforcer@v3
with:
- skipLabels: "autocut"
+ skipLabels: "autocut, skip-changelog"
diff --git a/.github/workflows/checkstyle.yml b/.github/workflows/checkstyle.yml
deleted file mode 100644
index ecc9129902..0000000000
--- a/.github/workflows/checkstyle.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-name: Checkstyle
-
-on: [push, pull_request]
-
-jobs:
- checkstyle:
- runs-on: ubuntu-latest
- strategy:
- matrix:
- java: [ 11 ]
- steps:
- - name: Set up JDK ${{ matrix.java }}
- uses: actions/setup-java@v1
- with:
- java-version: ${{ matrix.java }}
-
- - uses: actions/checkout@v2
- - name: Check style and license headers
- run: |
- ./gradlew checkstyleMain checkstyleTest
diff --git a/.github/workflows/dependabot_pr.yml b/.github/workflows/dependabot_pr.yml
index f13889c13d..ffcdd521c1 100644
--- a/.github/workflows/dependabot_pr.yml
+++ b/.github/workflows/dependabot_pr.yml
@@ -18,7 +18,7 @@ jobs:
installation_id: 22958780
- name: Check out code
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
token: ${{ steps.github_app_token.outputs.token }}
diff --git a/.github/workflows/increment-version.yml b/.github/workflows/increment-version.yml
new file mode 100644
index 0000000000..e8e754dd04
--- /dev/null
+++ b/.github/workflows/increment-version.yml
@@ -0,0 +1,66 @@
+name: Increment Version
+
+on:
+ push:
+ tags:
+ - '*.*.*'
+
+permissions: {}
+jobs:
+ build:
+ if: github.repository == 'opensearch-project/opensearch-java'
+ runs-on: ubuntu-latest
+ steps:
+ - name: GitHub App token
+ id: github_app_token
+ uses: tibdex/github-app-token@v2.1.0
+ with:
+ app_id: ${{ secrets.APP_ID }}
+ private_key: ${{ secrets.APP_PRIVATE_KEY }}
+ installation_id: 22958780
+
+ - uses: actions/checkout@v4
+ - name: Fetch Tag and Version Information
+ run: |
+ TAG=$(echo "${GITHUB_REF#refs/*/}")
+ CURRENT_VERSION_ARRAY=($(echo "${TAG//v}" | tr . '\n'))
+ CURRENT_VERSION_ARRAY[0]=$((CURRENT_VERSION_ARRAY[0]//v))
+ BASE_X=$(IFS=. ; echo "${CURRENT_VERSION_ARRAY[*]:0:1}.x")
+ CURRENT_VERSION=$(IFS=. ; echo "${CURRENT_VERSION_ARRAY[*]:0:3}")
+ CURRENT_VERSION_ARRAY[1]=$((CURRENT_VERSION_ARRAY[1]+1))
+ NEXT_VERSION=$(IFS=. ; echo "${CURRENT_VERSION_ARRAY[*]:0:3}")
+ # if [[ ${#CURRENT_VERSION_ARRAY[2]} -gt 1 ]]; then
+ # NEXT_VERSION_ID="${CURRENT_VERSION_ARRAY[0]:0:3}0${CURRENT_VERSION_ARRAY[1]:0:3}${CURRENT_VERSION_ARRAY[2]:0:3}99"
+ # else
+ # NEXT_VERSION_ID=$(IFS=0 ; echo "${CURRENT_VERSION_ARRAY[*]:0:3}99")
+ # fi
+ echo "TAG=$TAG" >> $GITHUB_ENV
+ # echo "BASE=$BASE" >> $GITHUB_ENV
+ echo "BASE_X=$BASE_X" >> $GITHUB_ENV
+ echo "CURRENT_VERSION=$CURRENT_VERSION" >> $GITHUB_ENV
+ echo "NEXT_VERSION=$NEXT_VERSION" >> $GITHUB_ENV
+ # echo "NEXT_VERSION_ID=$NEXT_VERSION_ID" >> $GITHUB_ENV
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ env.BASE_X }}
+ token: ${{ steps.github_app_token.outputs.token }}
+
+ - name: Increment Minor Version
+ run: |
+ echo Incrementing $CURRENT_VERSION to $NEXT_VERSION
+ sed -i "s/systemProp.version = $CURRENT_VERSION/systemProp.version = $NEXT_VERSION/g" gradle.properties
+
+ - name: Create Pull Request
+ uses: peter-evans/create-pull-request@v5
+ with:
+ token: ${{ steps.github_app_token.outputs.token }}
+ base: ${{ env.BASE_X }}
+ branch: 'create-pull-request/patch-${{ env.BASE }}'
+ commit-message: Increment version to ${{ env.NEXT_VERSION }}
+ signoff: true
+ delete-branch: true
+ labels: |
+ autocut
+ title: '[AUTO] Increment version to ${{ env.NEXT_VERSION }}.'
+ body: |
+ I've noticed that a new tag ${{ env.TAG }} was pushed, and incremented the version from ${{ env.CURRENT_VERSION }} to ${{ env.NEXT_VERSION }}.
diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml
index 2b1a29fb3d..f5d2b8dd6e 100644
--- a/.github/workflows/links.yml
+++ b/.github/workflows/links.yml
@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: lychee Link Checker
id: lychee
uses: lycheeverse/lychee-action@v1.5.0
diff --git a/.github/workflows/publish-snapshots.yml b/.github/workflows/publish-snapshots.yml
new file mode 100644
index 0000000000..3fb806f6d7
--- /dev/null
+++ b/.github/workflows/publish-snapshots.yml
@@ -0,0 +1,34 @@
+name: Publish snapshots to maven
+
+on:
+ push:
+ branches:
+ - main
+ - '2.x'
+
+jobs:
+ build-and-publish-snapshots:
+ runs-on: ubuntu-latest
+ permissions:
+ id-token: write
+ contents: write
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up JDK 11
+ uses: actions/setup-java@v3
+ with:
+ java-version: '11'
+ distribution: 'temurin'
+ cache: 'gradle'
+ - name: Configure AWS credentials
+ uses: aws-actions/configure-aws-credentials@v1
+ with:
+ role-to-assume: ${{ secrets.PUBLISH_SNAPSHOTS_ROLE }}
+ aws-region: us-east-1
+ - name: publish snapshots to maven
+ run: |
+ export SONATYPE_USERNAME=$(aws secretsmanager get-secret-value --secret-id maven-snapshots-username --query SecretString --output text)
+ export SONATYPE_PASSWORD=$(aws secretsmanager get-secret-value --secret-id maven-snapshots-password --query SecretString --output text)
+ echo "::add-mask::$SONATYPE_USERNAME"
+ echo "::add-mask::$SONATYPE_PASSWORD"
+ ./gradlew --no-daemon publishPublishMavenPublicationToSnapshotsRepository
\ No newline at end of file
diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml
new file mode 100644
index 0000000000..4374158a6c
--- /dev/null
+++ b/.github/workflows/release-drafter.yml
@@ -0,0 +1,44 @@
+name: Release drafter
+
+on:
+ push:
+ tags:
+ - "*"
+
+jobs:
+ draft-a-release:
+ name: Draft a release
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+ - id: get_data
+ run: |
+ echo "approvers=$(cat .github/CODEOWNERS | grep @ | tr -d '* ' | sed 's/@/,/g' | sed 's/,//1')" >> $GITHUB_OUTPUT
+ echo "version=$(cat gradle.properties | grep "systemProp.version" | cut -d'=' -f2)" >> $GITHUB_OUTPUT
+ - uses: trstringer/manual-approval@v1
+ with:
+ secret: ${{ github.TOKEN }}
+ approvers: ${{ steps.get_data.outputs.approvers }}
+ minimum-approvals: 2
+ issue-title: 'Release opensearch-java : ${{ steps.get_data.outputs.version }}'
+ issue-body: "Please approve or deny the release of opensearch-java. **VERSION**: ${{ steps.get_data.outputs.version }} **TAG**: ${{ github.ref_name }} **COMMIT**: ${{ github.sha }}"
+ exclude-workflow-initiator-as-approver: true
+ - name: Set up JDK 11
+ uses: actions/setup-java@v3
+ with:
+ java-version: '11'
+ distribution: 'temurin'
+ cache: 'gradle'
+ - name: Build with Gradle
+ run: |
+ export VERSION=`cat gradle.properties | grep "systemProp.version" | tr -d " " | cut -d '=' -f2`
+ echo Building the version: $VERSION
+ ./gradlew --no-daemon publishPublishMavenPublicationToLocalRepoRepository && tar -C build -cvf artifacts.tar.gz repository
+ - name: Draft a release
+ uses: softprops/action-gh-release@v1
+ with:
+ draft: true
+ generate_release_notes: true
+ files: |
+ artifacts.tar.gz
diff --git a/.github/workflows/test-integration-unreleased.yml b/.github/workflows/test-integration-unreleased.yml
index a136ed906c..2c0d59a450 100644
--- a/.github/workflows/test-integration-unreleased.yml
+++ b/.github/workflows/test-integration-unreleased.yml
@@ -18,36 +18,57 @@ jobs:
- { opensearch_ref: '1.x', java: 11 }
- { opensearch_ref: '2.x', java: 11 }
- { opensearch_ref: '2.x', java: 17 }
- - { opensearch_ref: '2.0', java: 11 }
+ - { opensearch_ref: '2.x', java: 21 }
- { opensearch_ref: 'main', java: 11 }
- { opensearch_ref: 'main', java: 17 }
+ - { opensearch_ref: 'main', java: 21 }
steps:
- name: Set up JDK ${{ matrix.entry.java }}
- uses: actions/setup-java@v1
+ uses: actions/setup-java@v3
with:
java-version: ${{ matrix.entry.java }}
+ distribution: 'temurin'
- name: Checkout OpenSearch
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
repository: opensearch-project/OpenSearch
ref: ${{ matrix.entry.opensearch_ref }}
path: opensearch
+ - name: Get OpenSearch branch top
+ id: get-key
+ working-directory: opensearch
+ run: echo key=`git log -1 --format='%H'` >> $GITHUB_OUTPUT
+
+ - name: Restore cached build
+ id: cache-restore
+ uses: actions/cache/restore@v3
+ with:
+ path: opensearch/distribution/archives/linux-tar/build/distributions
+ key: ${{ steps.get-key.outputs.key }}
+
- name: Assemble OpenSearch
- run: |
- cd opensearch
- ./gradlew assemble
+ if: steps.cache-restore.outputs.cache-hit != 'true'
+ working-directory: opensearch
+ run: ./gradlew :distribution:archives:linux-tar:assemble
- # This step runs the docker image generated during gradle assemble in OpenSearch. It is tagged as opensearch:test.
- # Reference: https://github.com/opensearch-project/OpenSearch/blob/2.0/distribution/docker/build.gradle#L190
- - name: Run Docker Image
+ - name: Save cached build
+ if: steps.cache-restore.outputs.cache-hit != 'true'
+ uses: actions/cache/save@v3
+ with:
+ path: opensearch/distribution/archives/linux-tar/build/distributions
+ key: ${{ steps.get-key.outputs.key }}
+
+ - name: Run OpenSearch
+ working-directory: opensearch/distribution/archives/linux-tar/build/distributions
run: |
- docker run -p 9200:9200 -p 9600:9600 -d -e "discovery.type=single-node" -e "bootstrap.memory_lock=true" opensearch:test
- sleep 90
+ tar xf opensearch-min-*
+ ./opensearch-*/bin/opensearch &
+ for attempt in {1..20}; do sleep 5; if curl -s localhost:9200; then echo '=====> ready'; break; fi; echo '=====> waiting...'; done
- name: Checkout Java Client
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
path: opensearch-java
@@ -55,3 +76,11 @@ jobs:
run: |
cd opensearch-java
./gradlew clean integrationTest -Dhttps=false
+
+ - name: Upload Reports
+ if: failure()
+ uses: actions/upload-artifact@v3
+ with:
+ name: test-reports
+ path: opensearch-java/java-client/build/reports/
+ retention-days: 7
diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml
index 921815ecb8..9308fb7078 100644
--- a/.github/workflows/test-integration.yml
+++ b/.github/workflows/test-integration.yml
@@ -12,19 +12,29 @@ jobs:
- { opensearch_version: 1.0.1, java: 11 }
- { opensearch_version: 1.1.0, java: 11 }
- { opensearch_version: 1.2.4, java: 11 }
- - { opensearch_version: 1.3.5, java: 11 }
+ - { opensearch_version: 1.3.13, java: 11 }
- { opensearch_version: 2.0.1, java: 11 }
- { opensearch_version: 2.1.0, java: 11 }
- { opensearch_version: 2.2.1, java: 11 }
- { opensearch_version: 2.3.0, java: 11 }
+ - { opensearch_version: 2.4.1, java: 11 }
+ - { opensearch_version: 2.5.0, java: 11 }
+ - { opensearch_version: 2.6.0, java: 11 }
+ - { opensearch_version: 2.7.0, java: 11 }
+ - { opensearch_version: 2.8.0, java: 11 }
+ - { opensearch_version: 2.9.0, java: 11 }
+ - { opensearch_version: 2.10.0, java: 11 }
+ - { opensearch_version: 2.11.1, java: 11 }
steps:
+ - name: Checkout Java Client
+ uses: actions/checkout@v3
+
- name: Set up JDK ${{ matrix.java }}
- uses: actions/setup-java@v1
+ uses: actions/setup-java@v3
with:
java-version: ${{ matrix.entry.java }}
-
- - name: Checkout Branch
- uses: actions/checkout@v2
+ distribution: 'temurin'
+ cache: 'gradle'
- name: Run Docker
run: |
@@ -34,6 +44,14 @@ jobs:
- name: Run Integration Test
run: ./gradlew clean integrationTest
+ - name: Upload Reports
+ if: failure()
+ uses: actions/upload-artifact@v3
+ with:
+ name: test-reports
+ path: java-client/build/reports/
+ retention-days: 7
+
- name: Stop Docker
run: |
docker-compose --project-directory .ci/opensearch down
\ No newline at end of file
diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml
index fbfe15671c..982d3d957a 100644
--- a/.github/workflows/test-unit.yml
+++ b/.github/workflows/test-unit.yml
@@ -7,16 +7,18 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
- java: [ 11 ]
+ java: [ 11, 17, 21 ]
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
+ - name: Checkout Java Client
+ uses: actions/checkout@v3
+
- name: Set up JDK ${{ matrix.java }}
- uses: actions/setup-java@v1
+ uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java }}
-
- - name: Checkout Branch
- uses: actions/checkout@v2
+ distribution: 'temurin'
+ cache: 'gradle'
- name: Run Unit Test
run: ./gradlew clean unitTest
diff --git a/.gitignore b/.gitignore
index 96cbff8d90..b8638f2e72 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,4 @@ gradle-app.setting
.ci/output
java-client/bin
+samples/bin
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9534bde8ab..9d4aa6e87f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,28 +1,232 @@
# CHANGELOG
Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
-## [Unreleased]
+## [Unreleased 2.x]
### Added
-- Github workflow for changelog verification ([#239](https://github.com/opensearch-project/opensearch-java/pull/239))
-- Github workflow for dependabot PRs ([#247](https://github.com/opensearch-project/opensearch-java/pull/247))
+- Added support for icu_collation_keyword type ([#725](https://github.com/opensearch-project/opensearch-java/pull/725))
+- Added support for flat_object field property ([#735](https://github.com/opensearch-project/opensearch-java/pull/735))
+- Expose HTTP status code through `ResponseException#status` ([#756](https://github.com/opensearch-project/opensearch-java/pull/756))
+- Added toBuilder method to all request model in core package & _types.query_dsl package ([#766](https://github.com/opensearch-project/opensearch-java/pull/766))
+- Added toQuery method in Query and QueryVariant ([#760](https://github.com/opensearch-project/opensearch-java/pull/760)
+- Added missing WrapperQuery accessors and builder methods ([#806](https://github.com/opensearch-project/opensearch-java/pull/806))
+### Dependencies
+- Bumps `com.diffplug.spotless` from 6.22.0 to 6.24.0
+- Bumps `org.apache.httpcomponents.client5:httpclient5` from 5.2.1 to 5.3
+- Bumps `org.owasp.dependencycheck` from 8.4.2 to 9.0.8
+
+### Changed
+
+### Deprecated
+- Deprecated "_toQuery()" in Query and QueryVariant ([#760](https://github.com/opensearch-project/opensearch-java/pull/760))
+
+### Removed
+- Removed unsupported `prefix` field from CompletionSuggester ([#812](https://github.com/opensearch-project/opensearch-java/pull/812))
+
+### Fixed
+- Fix partial success results for msearch_template ([#709](https://github.com/opensearch-project/opensearch-java/pull/709))
+- Fix deserialization of node stats response ([#745](https://github.com/opensearch-project/opensearch-java/pull/745))
+- Fix PutIndexTemplateRequest field deserialization ([#765](https://github.com/opensearch-project/opensearch-java/pull/765))
+
+### Security
+
+## [2.8.0] - 01/11/2023
+### Added
+- Added support for indexing and search index settings ([#667](https://github.com/opensearch-project/opensearch-java/pull/667))
+- Added support for neural query type ([#674](https://github.com/opensearch-project/opensearch-java/pull/674))
+
+### Dependencies
+
+### Changed
+- Allow null values in arrays ([#687](https://github.com/opensearch-project/opensearch-java/pull/687))
+- Add an example for bulk update operation in samples ([#690](https://github.com/opensearch-project/opensearch-java/pull/690))
+
+### Deprecated
+
+### Removed
+
+### Fixed
+- Fixed Hit response when search request has storedFields as null ([#698](https://github.com/opensearch-project/opensearch-java/pull/698))
+- Fix InnerHits storedFields deserialization/serialization ([#781](https://github.com/opensearch-project/opensearch-java/pull/781)
+
+### Security
+
+## [2.7.0] - 10/13/2023
+### Added
+- Added support for "smartcn" analyzer ([#605](https://github.com/opensearch-project/opensearch-java/pull/605))
+- Added support for "cjk" analyzer ([#604](https://github.com/opensearch-project/opensearch-java/pull/604))
+- Added support for wrapper queries ([#630](https://github.com/opensearch-project/opensearch-java/pull/630))
+- Added support for "script_fields" in multi search request ([#632](https://github.com/opensearch-project/opensearch-java/pull/632))
+- Added size attribute to MultiTermsAggregation ([#627](https://github.com/opensearch-project/opensearch-java/pull/627))
+- Added version increment workflow that executes after release ([#664](https://github.com/opensearch-project/opensearch-java/pull/664))
+
+### Dependencies
+- Bumps `org.ajoberstar.grgit:grgit-gradle` from 5.0.0 to 5.2.0
+- Bumps `com.github.jk1.dependency-license-report` from 2.4 to 2.5
+- Bumps `io.github.classgraph:classgraph` from 4.8.160 to 4.8.161
+
+### Changed
+- Moved "software.amazon.awssdk" dependencies to the compileOnly scope. ([#628](https://github.com/opensearch-project/opensearch-java/pull/628))
+- Migrated from checkstyle to spotless ([#648](https://github.com/opensearch-project/opensearch-java/pull/648))
+
+### Deprecated
+
+### Removed
+- Remove generated code comments from all files ([#598](https://github.com/opensearch-project/opensearch-java/pull/598))
+
+### Fixed
+- Fix PutMappingRequest by removing unsupported fields ([#597](https://github.com/opensearch-project/opensearch-java/pull/597))
+- [BUG] JarHell caused by latest software.amazon.awssdk 2.20.141 ([#616](https://github.com/opensearch-project/opensearch-java/pull/616))
+- Don't over-allocate in HeapBufferedAsyncEntityConsumer in order to consume the response ([#620](https://github.com/opensearch-project/opensearch-java/pull/620))
+- Fixed CVE-2976 + added CVE checker ([#624](https://github.com/opensearch-project/opensearch-java/pull/624))
+- Fix parsing of GetFieldMappingResponse ([#641](https://github.com/opensearch-project/opensearch-java/pull/641))
+- Fix TermvectorsResponse for optional fields ([#642](https://github.com/opensearch-project/opensearch-java/pull/642))
+- Fix deserialization of MsearchTemplateResponse ([#660](https://github.com/opensearch-project/opensearch-java/pull/660))
+
+### Security
+
+## [2.6.0] - 07/05/2023
+### Added
+- Add support for knn_vector field type ([#524](https://github.com/opensearch-project/opensearch-java/pull/524))
+- Add translog option object and missing translog sync interval option in index settings ([#518](https://github.com/opensearch-project/opensearch-java/pull/518))
+- Adds the option to set slices=auto for UpdateByQueryRequest, DeleteByQueryRequest and ReindexRequest ([#538](https://github.com/opensearch-project/opensearch-java/pull/538))
+- Add support for approximate k-NN queries ([#548](https://github.com/opensearch-project/opensearch-java/pull/548))
+
+### Dependencies
+- Bumps `com.github.jk1.dependency-license-report` from 2.2 to 2.4
+- Bumps `io.github.classgraph:classgraph` from 4.8.157 to 4.8.160
+- Bumps `jackson` from 2.14.2 to 2.15.2 ((#537)[https://github.com/opensearch-project/opensearch-java/pull/537])
+- Update `org.apache.httpcomponents.client5:httpclient5` from `5.1.4` to `5.2.1` and `org.apache.httpcomponents.core5:httpcore5` from `5.1.5` to `5.2.2`
+
+### Changed
+
+### Deprecated
+- Deprecate translogDurability and translogFlushThresholdSize in IndexSettings in favor of a separate translog object ([#518](https://github.com/opensearch-project/opensearch-java/pull/518))
+
+### Removed
+
+### Fixed
+- Fixed Suggesters for Completion, Term, and Phrase and refactored the Suggestion class ([#477](https://github.com/opensearch-project/opensearch-java/pull/477))
+- Fix highlight max_analyzer_offset field name to match with the one introduced in OpenSearch 2.2.0 ([#555](https://github.com/opensearch-project/opensearch-java/pull/555))
+
+### Security
+
+## [2.5.0] - 06/02/2023
+### Added
+- Add workflow to publish snapshots via GHA ([#454](https://github.com/opensearch-project/opensearch-java/pull/454))
+- Added Point-In-Time APIs ([#461](https://github.com/opensearch-project/opensearch-java/pull/461))
+
+### Dependencies
+- Bumps `com.github.jk1.dependency-license-report` from 1.19 to 2.2
+- Bumps `org.eclipse.parsson:parsson` from 1.1.2 to 1.1.4
+
+### Changed
+- Improve time taken by Github actions by using cache ([#439](https://github.com/opensearch-project/opensearch-java/pull/439))
+- Introduce intermediary SearchResult for SearchResponse and SearchTemplateResponse classes, enabling similar response handling for both ([#462](https://github.com/opensearch-project/opensearch-java/pull/462))
+
+### Deprecated
+
+### Removed
+
+### Fixed
+- Fix missing Highlight and SourceConfig in the MultisearchBody ([#442](https://github.com/opensearch-project/opensearch-java/pull/442))
+- Fix search failure with missing required property HitsMetadata.total when trackTotalHits is disabled ([#372](https://github.com/opensearch-project/opensearch-java/pull/372))
+- Fix failure when deserialing response for tasks API ([#463](https://github.com/opensearch-project/opensearch-java/pull/463))
+- Fix failure when deserializing boolean types for enums ([#463](https://github.com/opensearch-project/opensearch-java/pull/482))
+- Fix missing minScore, postFilter, searchAfter, sort, trackScores in the MultisearchBody ([#516](https://github.com/opensearch-project/opensearch-java/pull/516))
+### Security
+
+## [2.4.0] - 04/11/2023
+
+### Added
+- Add buffered lookahead for Jackson ([#338](https://github.com/opensearch-project/opensearch-java/pull/338))
+- Add support for headers and sort parameters in cat requests ([#413](https://github.com/opensearch-project/opensearch-java/pull/413))
+- Add support for data stream operations ([#419](https://github.com/opensearch-project/opensearch-java/pull/419))
+
+### Dependencies
+- Bumps `io.github.classgraph:classgraph` from 4.8.156 to 4.8.157 ([#408](https://github.com/opensearch-project/opensearch-java/pull/408))
+
+### Changed
+
+### Deprecated
+
+### Removed
+
+### Fixed
+
+### Security
+
+## [2.3.0] - 03/15/2023
+
+### Added
+- Require two maintainers to approve release ([#383](https://github.com/opensearch-project/opensearch-java/pull/383))
+- Add support for mapping limit settings ([#382](https://github.com/opensearch-project/opensearch-java/pull/382))
+
+### Dependencies
+- Bumps `Jackson` from 2.14.1 to 2.14.2 ([#357](https://github.com/opensearch-project/opensearch-java/pull/357))
+- Bumps `classgraph` from 4.8.149 to 4.8.156 ([#395](https://github.com/opensearch-project/opensearch-java/pull/395))
+
+### Changed
+- Prevent SPI calls at runtime ([#293](https://github.com/opensearch-project/opensearch-java/pull/293))
+
+### Deprecated
+
+### Removed
+
+### Fixed
+- Fix issue where completion suggestions were failing, due to being parsed as term suggestions ([#350](https://github.com/opensearch-project/opensearch-java/pull/350))
+- Bulk UpdateOperation misses upsert options ([#353](https://github.com/opensearch-project/opensearch-java/pull/353))
+- Fix missing key property in the RangeBucket ([#381](https://github.com/opensearch-project/opensearch-java/pull/381))
+
+### Security
+
+## [2.2.0] - 01/23/2023
+
+### Added
+- Add Github workflow for changelog verification ([#239](https://github.com/opensearch-project/opensearch-java/pull/239))
+- Add Github workflow for dependabot PRs ([#247](https://github.com/opensearch-project/opensearch-java/pull/247))
+- Add support for signing service name in AwsSdk2Transport ([#324](https://github.com/opensearch-project/opensearch-java/pull/324))
+- Add new OpenSearchTransport based on Apache HttpClient 5 ([#328](https://github.com/opensearch-project/opensearch-java/pull/328))
+- Add 1-click release workflows ([#321](https://github.com/opensearch-project/opensearch-java/pull/321))
+- Add support for OpenSearch Serverless ([#339](https://github.com/opensearch-project/opensearch-java/pull/339))
+- Add support to parse sub-aggregations from filter/nested aggregations ([#234](https://github.com/opensearch-project/opensearch-java/pull/234))
+
### Dependencies
- Bumps `grgit-gradle` from 4.0.1 to 5.0.0
+- Update Jackson to 2.14.0 ([#259](https://github.com/opensearch-project/opensearch-java/pull/259))
+- Update Gradle to 7.6 ([#311](https://github.com/opensearch-project/opensearch-java/pull/311))
### Changed
- Update literature around changelog contributions in CONTRIBUTING.md ([#242](https://github.com/opensearch-project/opensearch-java/pull/242))
- Update tests to use JUnit's Assert ([#244](https://github.com/opensearch-project/opensearch-java/pull/244))
-- Add support to parse sub-aggregations from filter/nested aggregations ([#234](https://github.com/opensearch-project/opensearch-java/pull/234))
- Add timeout and throttle to the jenkins workflows ([#231](https://github.com/opensearch-project/opensearch-java/pull/231))
-- Updating maintainers, admins and documentation ([#248](https://github.com/opensearch-project/opensearch-java/pull/248))
+- Update maintainers, admins and documentation ([#248](https://github.com/opensearch-project/opensearch-java/pull/248))
### Deprecated
+- Deprecate the totalDataSetSize and totalDataSetSizeInBytes fields in the StoreStats ([#498](https://github.com/opensearch-project/opensearch-java/pull/498))
+
### Removed
+- Remove support for unsupported dynamic_templates in bulk ([#276](https://github.com/opensearch-project/opensearch-java/pull/276))
### Fixed
-
+- Make ChildrenAggregate as a SingleBucketAggregate ([#306](https://github.com/opensearch-project/opensearch-java/pull/306))
+- Fix /_nodes/stats, /_nodes/info throwing serialization error ([#315](https://github.com/opensearch-project/opensearch-java/pull/315))
+- Do not double-wrap OpenSearchException on error ([#323](https://github.com/opensearch-project/opensearch-java/pull/323))
+- Fix AwsSdk2TransportOptions.responseCompression ([#322](https://github.com/opensearch-project/opensearch-java/pull/322))
+- Fix missing Highlight and SourceConfig in the MultisearchBody ([#442](https://github.com/opensearch-project/opensearch-java/pull/442))
+- Fix parsing /_alias error response for not existing alias ([#476](https://github.com/opensearch-project/opensearch-java/pull/476))
+- Fix missing cause message in missing permission to call Fine Grained Access Control Amazon OpenSearch domain ([#473](https://github.com/opensearch-project/opensearch-java/issues/473))
+- Fix catching JsonParsingException ([#494](https://github.com/opensearch-project/opensearch-java/issues/494))
+- Fix StoryStats numeric value out of range of int ([#489](https://github.com/opensearch-project/opensearch-java/pull/489))
+
### Security
-
-[Unreleased]: https://github.com/opensearch-project/opensearch-java/compare/2.0...HEAD
+[Unreleased 2.x]: https://github.com/opensearch-project/opensearch-java/compare/v2.8.0...2.x
+[2.8.0]: https://github.com/opensearch-project/opensearch-java/compare/v2.7.0...v2.8.0
+[2.7.0]: https://github.com/opensearch-project/opensearch-java/compare/v2.6.0...v2.7.0
+[2.6.0]: https://github.com/opensearch-project/opensearch-java/compare/v2.5.0...v2.6.0
+[2.5.0]: https://github.com/opensearch-project/opensearch-java/compare/v2.4.0...v2.5.0
+[2.4.0]: https://github.com/opensearch-project/opensearch-java/compare/v2.3.0...v2.4.0
+[2.3.0]: https://github.com/opensearch-project/opensearch-java/compare/v2.2.0...v2.3.0
+[2.2.0]: https://github.com/opensearch-project/opensearch-java/compare/v2.1.0...v2.2.0
diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md
index c0b9044ee4..10bc8b9767 100644
--- a/COMPATIBILITY.md
+++ b/COMPATIBILITY.md
@@ -1,4 +1,5 @@
- [Compatibility with OpenSearch](#compatibility-with-opensearch)
+- [Compatibility with JDK](#compatibility-with-jdk)
- [Upgrading](#upgrading)
## Compatibility with OpenSearch
@@ -6,10 +7,19 @@
The below matrix shows the compatibility of the [`opensearch-java-client`](https://search.maven.org/artifact/org.opensearch.client/opensearch-java) with versions of [`OpenSearch`](https://opensearch.org/downloads.html#opensearch).
| Client Version | OpenSearch Version |
-| --- | --- |
-| 1.0.0 | 1.0.0-1.3.3 |
-| 2.0.0 | 1.3.3-2.0.1 |
-| 2.1.0 | 1.3.3-2.3.0 |
+|----------------|--------------------|
+| 1.0.0 | 1.x |
+| 2.x.0 | 1.3.13-2.x.x |
+
+
+## Compatibility with JDK
+
+The below matrix shows the compatibility of the [`opensearch-java-client`](https://search.maven.org/artifact/org.opensearch.client/opensearch-java) with JDK versions.
+
+| Client Version | JDK |
+|----------------|--------------------|
+| 1.0.0 | 8 |
+| 2.x.0 | 11 / 17 / 21 |
## Upgrading
diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md
index fa2da6946e..6969aba856 100644
--- a/DEVELOPER_GUIDE.md
+++ b/DEVELOPER_GUIDE.md
@@ -7,6 +7,7 @@
- [Run Tests](#run-tests)
- [Unit Tests](#unit-tests)
- [Integration Tests](#integration-tests)
+ - [AWS Transport Integration Tests](#aws-transport-integration-tests)
- [Use an Editor](#use-an-editor)
- [IntelliJ IDEA](#intellij-idea)
- [Visual Studio Code](#visual-studio-code)
@@ -64,6 +65,20 @@ Run integration tests after starting OpenSearch cluster:
./gradlew clean integrationTest
```
+#### AWS Transport Integration Tests
+
+To run integration tests for the AWS transport client, ensure working AWS credentials in `/.aws/credentials` and specify your OpenSearch domain and region as follows:
+
+```
+./gradlew integrationTest --tests "*AwsSdk2*" -Dtests.awsSdk2support.domainHost=search-...us-west-2.es.amazonaws.com -Dtests.awsSdk2support.domainRegion=us-west-2 -Dtests.awsSdk2support.serviceName=es
+```
+
+For OpenSearch Serverless, change the signing service name.
+
+```
+./gradlew integrationTest --tests "*AwsSdk2*" -Dtests.awsSdk2support.domainHost=....us-west-2.aoss.amazonaws.com -Dtests.awsSdk2support.domainRegion=us-west-2 -Dtests.awsSdk2support.serviceName=aoss
+```
+
## Use an Editor
### IntelliJ IDEA
@@ -82,11 +97,28 @@ Follow links in the [Java Tutorial](https://code.visualstudio.com/docs/java/java
## Java Language Formatting Guidelines
-Java files in the opensearch-java codebase are formatted with the [checkstyle plugin](https://docs.gradle.org/current/userguide/checkstyle_plugin.html). This plugin is configured using [checkstyle.xml](config/checkstyle/checkstyle.xml). To run the formatting checks:
+Java files in the OpenSearch codebase are formatted with the Eclipse JDT formatter, using the [Spotless Gradle](https://github.com/diffplug/spotless/tree/master/plugin-gradle) plugin. This plugin is configured on a project-by-project basis, via `build.gradle.kts`. So long as at least one project is configured, the formatting check can be run explicitly with:
-```
-./gradlew checkstyleMain checkstyleTest
-```
+ ./gradlew spotlessJavaCheck
+
+The code can be formatted with:
+
+ ./gradlew spotlessApply
+
+These tasks can also be run for specific subprojects, e.g.
+
+ ./gradlew :java-client:spotlessJavaCheck
+ ./gradlew :samples:spotlessJavaCheck
+
+Please follow these formatting guidelines:
+
+* Java indent is 4 spaces
+* Line width is 140 characters
+* Lines of code surrounded by `// tag::NAME` and `// end::NAME` comments are included in the documentation and should only be 76 characters wide not counting leading indentation. Such regions of code are not formatted automatically as it is not possible to change the line length rule of the formatter for part of a file. Please format such sections sympathetically with the rest of the code, while keeping lines to maximum length of 76 characters.
+* Wildcard imports (`import foo.bar.baz.*`) are forbidden and will cause the build to fail.
+* If *absolutely* necessary, you can disable formatting for regions of code with the `// tag::NAME` and `// end::NAME` directives, but note that these are intended for use in documentation, so please make it clear what you have done, and only do this where the benefit clearly outweighs the decrease in consistency.
+* Note that JavaDoc and block comments i.e. `/* ... */` are not formatted, but line comments i.e `// ...` are.
+* There is an implicit rule that negative boolean expressions should use the form `foo == false` instead of `!foo` for better readability of the code. While this isn't strictly enforced, if might get called out in PR reviews as something to change.
## Submitting Changes
diff --git a/README.md b/README.md
index a0563ca3d7..84206a71d5 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,3 @@
-[![Checkstyle](https://github.com/opensearch-project/opensearch-java/actions/workflows/checkstyle.yml/badge.svg?branch=main)](https://github.com/opensearch-project/opensearch-java/actions/workflows/checkstyle.yml)
[![Build](https://github.com/opensearch-project/opensearch-java/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/opensearch-project/opensearch-java/actions/workflows/build.yml)
[![Integration Tests](https://github.com/opensearch-project/opensearch-java/actions/workflows/test-integration.yml/badge.svg?branch=main)](https://github.com/opensearch-project/opensearch-java/actions/workflows/test-integration.yml)
![Maven Central](https://img.shields.io/maven-central/v/org.opensearch.client/opensearch-java)
@@ -14,6 +13,7 @@ OpenSearch Java Client
- [Project Resources](#project-resources)
- [Code of Conduct](#code-of-conduct)
- [User Guide](#user-guide)
+- [Snapshot Builds](#snapshot-builds)
- [Compatibility with OpenSearch](#compatibility-with-opensearch)
- [Security](#security)
- [License](#license)
@@ -33,8 +33,9 @@ Please see the [USER_GUIDE](USER_GUIDE.md) for code snippets.
* [Project Website](https://opensearch.org/)
* [Documentation](https://opensearch.org/docs/latest/clients/java/)
+* [JavaDoc](https://www.javadoc.io/doc/org.opensearch.client/opensearch-java/latest/index.html)
* [Maven Central](https://search.maven.org/artifact/org.opensearch.client/opensearch-java)
-* [Snapshot Builds](https://aws.oss.sonatype.org/content/repositories/snapshots/org/opensearch/client/opensearch-java/)
+* [Snapshot Builds](#snapshot-builds)
* Need help? Try [Forums](https://discuss.opendistrocommunity.dev/)
* [Project Principles](https://opensearch.org/#principles)
* [Contributing to OpenSearch](CONTRIBUTING.md)
@@ -51,6 +52,9 @@ This project has adopted the [Amazon Open Source Code of Conduct](CODE_OF_CONDUC
See [User Guide](USER_GUIDE.md).
+## Snapshot Builds
+The [snapshots builds](https://aws.oss.sonatype.org/content/repositories/snapshots/org/opensearch/client/opensearch-java/) are published to sonatype using [publish-snapshots.yml](./.github/workflows/publish-snapshots.yml) workflow.
+
## Compatibility with OpenSearch
See [Compatibility](COMPATIBILITY.md).
diff --git a/RELEASING.md b/RELEASING.md
index 14dac4c92e..b19130399b 100644
--- a/RELEASING.md
+++ b/RELEASING.md
@@ -34,9 +34,7 @@ Repositories create consistent release labels, such as `v1.0.0`, `v1.1.0` and `v
The release process is standard across repositories in this org and is run by a release manager volunteering from amongst [MAINTAINERS](MAINTAINERS.md).
1. Create a tag, e.g. `v2.1.0`, and push it to the GitHub repo.
-2. The [opensearch-java-maven-sign-and-release/](https://build.ci.opensearch.org/job/opensearch-java-maven-sign-and-release/) will be automatically kicked off.
-3. Login to [AWS OSS Sonatype](https://aws.oss.sonatype.org/#stagingRepositories), and locate the staged release.
-4. `Close` the staged repository, and ensure all checks pass.
-5. `Release` the staged respository.
-6. [Create a release on GitHub](https://github.com/opensearch-project/opensearch-java/releases/new) with release notes.
-7. Increment `systemProp.version` in [gradle.properties](gradle.properties) to the next patch release, e.g. `v2.1.1`, commit and push.
\ No newline at end of file
+1. The [release-drafter.yml](.github/workflows/release-drafter.yml) will be automatically kicked off and is responsible for drafting a new release on GitHub containing release artifacts.
+1. Before creating a draft release, this workflow creates a GitHub issue asking for approval from the [maintainers](MAINTAINERS.md). See sample [issue](https://github.com/gaiksaya/opensearch-java/issues/1). The maintainers need to approve in order to continue the workflow run.
+1. Once a release is drafted [opensearch-java-maven-sign-and-release/](https://build.ci.opensearch.org/job/opensearch-java-maven-sign-and-release/) jenkins workflow is triggered. The artifacts will be automcatically signed and published to maven.
+1. Increment `systemProp.version` in [gradle.properties](gradle.properties) to the next patch release, e.g. `v2.1.1`, commit and push.
\ No newline at end of file
diff --git a/USER_GUIDE.md b/USER_GUIDE.md
index f51063052e..982e2bb14c 100644
--- a/USER_GUIDE.md
+++ b/USER_GUIDE.md
@@ -1,54 +1,108 @@
-# User Guide
+- [OpenSearch Java Client User Guide](#opensearch-java-client-user-guide)
+ - [Setup](#setup)
+ - [Basic Features](#basic-features)
+ - [Creating a client](#creating-a-client)
+ - [Using `RestClientTransport`](#using-restclienttransport)
+ - [Using `ApacheHttpClient5Transport`](#using-apachehttpclient5transport)
+ - [Creating an index](#creating-an-index)
+ - [With default settings](#with-default-settings)
+ - [With custom settings and mappings](#with-custom-settings-and-mappings)
+ - [With FlatObject mappings](#with-flat-object-mappings)
+ - [Indexing data](#indexing-data)
+ - [Searching for a document](#searching-for-a-document)
+ - [Deleting a document](#deleting-a-document)
+ - [Deleting an index](#deleting-an-index)
+ - [Advanced Features](#advanced-features)
+ - [Plugins](#plugins)
+
+# OpenSearch Java Client User Guide
+
+## Setup
+
+To start using the OpenSearch Java client, you need to provide a transport. The default `ApacheHttpClient5TransportBuilder` transport comes with the Java client. To use the OpenSearch Java client with the default transport, add it to your `pom.xml` file as a dependency:
-- [User Guide](#user-guide)
- - [Sample data](#sample-data)
- - [Create an index](#create-an-index)
- - [Index data](#index-data)
- - [Search for the document](#search-for-the-document)
- - [Search documents using a match query](#search-documents-using-a-match-query)
- - [Aggregations](#aggregations)
- - [Delete the document](#delete-the-document)
- - [Delete the index](#delete-the-index)
- - [Aggregations](#aggregations)
+```
+
+ org.opensearch.client
+ opensearch-java
+ 2.6.0
+
+```
+
+If you’re using Gradle, add the following dependencies to your project:
+
+```
+dependencies {
+ implementation 'org.opensearch.client:opensearch-java:2.6.0'
+}
+```
+
+## Basic Features
-## Sample data
+In the example below, we create a client, create an index with default and non-default settings, insert a document into the index, search for the document, delete the document, and finally delete the index.
-### IndexData class
+You can find working versions of the code below that can be run with a local instance of OpenSearch in [samples](./samples/).
+
+### Creating a client
+
+There are multiple low level transports which `OpenSearchClient` could be configured with.
+
+#### Using `RestClientTransport`
```java
-static class IndexData {
- private String firstName;
- private String lastName;
-
- public IndexData(String firstName, String lastName) {
- this.firstName = firstName;
- this.lastName = lastName;
- }
-
- public String getFirstName() {
- return firstName;
- }
-
- public void setFirstName(String firstName) {
- this.firstName = firstName;
- }
-
- public String getLastName() {
- return lastName;
- }
-
- public void setLastName(String lastName) {
- this.lastName = lastName;
- }
-
- @Override
- public String toString() {
- return String.format("IndexData{first name='%s', last name='%s'}", firstName, lastName);
- }
-}
+import org.apache.http.HttpHost;
+
+final HttpHost[] hosts = new HttpHost[] {
+ new HttpHost("localhost", 9200, "http")
+ };
+
+// Initialize the client with SSL and TLS enabled
+final RestClient restClient = RestClient
+ .builder(hosts)
+ .build();
+
+OpenSearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
+OpenSearchClient client = new OpenSearchClient(transport);
```
-## Create an index
+The `JacksonJsonpMapper` class (2.x versions) only supports Java 7 objects by default. [Java 8 modules](https://github.com/FasterXML/jackson-modules-java8) to support JDK8 classes such as the Date and Time API (JSR-310), `Optional`, and more can be used by including [the additional datatype dependency](https://github.com/FasterXML/jackson-modules-java8#usage) and adding the module. For example, to include JSR-310 classes:
+
+```java
+Transport transport = new RestClientTransport(restClient,
+ new JacksonJsonpMapper(new ObjectMapper().registerModule(new JavaTimeModule())));
+OpenSearchClient client = new OpenSearchClient(transport);
+```
+
+#### Using `ApacheHttpClient5Transport`
+
+```java
+import org.apache.hc.core5.http.HttpHost;
+
+final HttpHost[] hosts = new HttpHost[] {
+ new HttpHost("http", "localhost", 9200)
+ };
+
+final OpenSearchTransport transport = ApacheHttpClient5TransportBuilder
+ .builder(hosts)
+ .setMapper(new JacksonJsonpMapper())
+ .build();
+OpenSearchClient client = new OpenSearchClient(transport);
+```
+
+The Apache HttpClient 5 based transport has dependences on Apache HttpClient 5 and Apache HttpCore 5 which has to be added to the project explicitly.
+
+```gradle
+ implementation("org.apache.httpcomponents.client5", "httpclient5", "5.2.1")
+ implementation("org.apache.httpcomponents.core5", "httpcore5", "5.2.2")
+```
+
+Upcoming OpenSearch `3.0.0` release brings HTTP/2 support and as such, the `RestClientTransport` would switch to HTTP/2 if available (for both HTTPS and/or HTTP protocols). The desired protocol could be forced using `RestClientBuilder.HttpClientConfigCallback`.
+
+See [SampleClient.java](./samples/src/main/java/org/opensearch/client/samples/SampleClient.java) for a working sample.
+
+### Creating an index
+
+#### With default settings
```java
String index = "sample-index";
@@ -56,19 +110,52 @@ CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(i
client.indices().create(createIndexRequest);
```
-## Index data
+#### With custom settings and mappings
+
+```java
+String index = "sample-index";
+IndexSettings settings = new IndexSettings.Builder()
+ .numberOfShards("2")
+ .numberOfReplicas("1")
+ .build();
+TypeMapping mapping = new TypeMapping.Builder()
+ .properties("age", new Property.Builder().integer(new IntegerNumberProperty.Builder().build()).build())
+ .build();
+CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder()
+ .index(index)
+ .settings(settings)
+ .mappings(mapping)
+ .build();
+client.indices().create(createIndexRequest);
+```
+#### With flat object mappings
+OpenSearch supports FlatObject mappings from version 2.7.0 without additional parameters.
```java
-IndexData indexData = new IndexData("John", "Doe");
+final CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(indexName)
+ .mappings(m -> m.properties("issue", Property.of(p -> p.flatObject(new FlatObjectProperty.Builder().build()))))
+ .build();
+client.indices().create(createIndexRequest);
+```
+
+You can find a working sample of the above code in [FlatObjectBasics.java](./samples/src/main/java/org/opensearch/client/samples/FlatObjectBasics.java).
+
+
+### Indexing data
+
+[IndexData](./samples/src/main/java/org/opensearch/client/samples/util/IndexData.java) refers to sample data class.
+
+```java
+IndexData indexData = new IndexData("Document 1", "Text for document 1");
IndexRequest indexRequest = new IndexRequest.Builder().index(index).id("1").document(indexData).build();
client.index(indexRequest);
-indexData = new IndexData("John", "Joe");
+indexData = new IndexData("Document 2", "Text for document 2");
indexRequest = new IndexRequest.Builder().index(index).id("2").document(indexData).build();
client.index(indexRequest);
```
-## Search for the documents
+### Searching for a document
```java
SearchResponse searchResponse = client.search(s -> s.index(index), IndexData.class);
@@ -77,46 +164,32 @@ for (int i = 0; i < searchResponse.hits().hits().size(); i++) {
}
```
-## Search documents using a match query
+### Deleting a document
-```java
-SearchRequest searchRequest = new SearchRequest.Builder().query(q -> q.match(m -> m.field("firstName")
- .query(FieldValue.of("John"))))
- .build();
+The following sample code deletes a document whose ID is 1.
-SearchResponse searchResponse = client.search(searchRequest, IndexData.class);
-for (int i = 0; i < searchResponse.hits().hits().size(); i++) {
- System.out.println(searchResponse.hits().hits().get(i).source());
-}
+```java
+client.delete(d -> d.index(index).id("1"));
```
-## Aggregations
+## Deleting an index
```java
-SearchRequest searchRequest = new SearchRequest.Builder().query(q -> q.match(m -> m.field("firstName")
- .query(FieldValue.of("John"))))
- .aggregations("firstNames", new Aggregation.Builder().terms(t -> t.field("firstName.keyword"))
- .build())
- .build();
-
-SearchResponse searchResponse = client.search(searchRequest, IndexData.class);
-for (Map.Entry entry : searchResponse.aggregations().entrySet()) {
- System.out.println("Agg - " + entry.getKey());
- entry.getValue().sterms().buckets().array().forEach(b -> System.out.printf("%s : %d%n", b.key(), b.docCount()));
-}
+DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest.Builder().index(index).build();
+DeleteIndexResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest);
```
-## Delete the document
+You can find a working sample of the above code in [IndexingBasics.java](./samples/src/main/java/org/opensearch/client/samples/IndexingBasics.java).
-The following sample code deletes a document whose ID is 1.
+## Advanced Features
-```java
-client.delete(d -> d.index(index).id("1"));
-```
+- [Authentication (IAM, SigV4)](./guides/auth.md)
+- [Bulk Indexing](./guides/bulk.md)
+- [Cat APIs](./guides/cat.md)
+- [Data Stream APIs](./guides/data_stream.md)
+- [Point-in-Time APIs](./guides/point_in_time.md)
+- [Search](./guides/search.md)
-## Delete the index
+## Plugins
-```java
-DeleteIndexRequest deleteIndexRequest = new DeleteRequest.Builder().index(index).build();
-DeleteIndexResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest);
-```
\ No newline at end of file
+- [k-NN](guides/plugins/knn.md)
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index df7f0dc13b..7779a42fd3 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -42,8 +42,6 @@ allprojects {
mavenCentral()
maven(url = "https://plugins.gradle.org/m2/")
}
-
- apply(plugin = "checkstyle")
}
// Find git information.
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
index 81e081c058..be0dd199c3 100644
--- a/buildSrc/build.gradle.kts
+++ b/buildSrc/build.gradle.kts
@@ -31,7 +31,7 @@
*/
dependencies {
- implementation("org.ajoberstar.grgit:grgit-gradle:5.0.0")
+ implementation("org.ajoberstar.grgit:grgit-gradle:5.2.0")
}
repositories {
diff --git a/buildSrc/formatterConfig.xml b/buildSrc/formatterConfig.xml
new file mode 100644
index 0000000000..425f9acfea
--- /dev/null
+++ b/buildSrc/formatterConfig.xml
@@ -0,0 +1,362 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
deleted file mode 100644
index 7739883f14..0000000000
--- a/config/checkstyle/checkstyle.xml
+++ /dev/null
@@ -1,156 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/config/checkstyle/checkstyle_suppressions.xml b/config/checkstyle/checkstyle_suppressions.xml
deleted file mode 100644
index edfa8870aa..0000000000
--- a/config/checkstyle/checkstyle_suppressions.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/config/checkstyle/header.java.txt b/config/checkstyle/header.java.txt
deleted file mode 100644
index b5b39ea4ed..0000000000
--- a/config/checkstyle/header.java.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- */
diff --git a/gradle.properties b/gradle.properties
index 712a6787e1..8fa3f72312 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1 +1 @@
-systemProp.version = 2.1.1
\ No newline at end of file
+systemProp.version = 2.9.0
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 7454180f2a..7f93135c49 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 788d8e5179..48db9b89d2 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -28,7 +28,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionSha256Sum=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4
+distributionSha256Sum=3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae
diff --git a/gradlew b/gradlew
index e5053f218f..1aa94a4269 100755
--- a/gradlew
+++ b/gradlew
@@ -1,33 +1,7 @@
-#!/usr/bin/env sh
+#!/bin/sh
#
-# SPDX-License-Identifier: Apache-2.0
-#
-# The OpenSearch Contributors require contributions made to
-# this file be licensed under the Apache-2.0 license or a
-# compatible open source license.
-#
-#
-# 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.
-#
-
-#
-# Copyright 2015 the original author or authors.
+# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -42,72 +16,100 @@
# limitations under the License.
#
-# Modifications Copyright OpenSearch Contributors. See
-# GitHub history for details.
-
-
##############################################################################
-##
-## Gradle start up script for UN*X
-##
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
##############################################################################
# Attempt to set APP_HOME
+
# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
warn () {
echo "$*"
-}
+} >&2
die () {
echo
echo "$*"
echo
exit 1
-}
+} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -117,9 +119,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACMD=$JAVA_HOME/jre/sh/java
else
- JAVACMD="$JAVA_HOME/bin/java"
+ JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -128,88 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
+ fi
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
fi
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
# Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
fi
- i=`expr $i + 1`
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
done
- case $i in
- 0) set -- ;;
- 1) set -- "$args0" ;;
- 2) set -- "$args0" "$args1" ;;
- 3) set -- "$args0" "$args1" "$args2" ;;
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
fi
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=`save "$@"`
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index a9f778a7a9..6689b85bee 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
-@if "%DEBUG%" == "" @echo off
+@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +25,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
+if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -54,7 +55,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-if exist "%JAVA_EXE%" goto init
+if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -64,21 +65,6 @@ echo location of your Java installation.
goto fail
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
:execute
@rem Setup the command line
@@ -86,17 +72,19 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
+if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
diff --git a/guides/auth.md b/guides/auth.md
new file mode 100644
index 0000000000..658464642d
--- /dev/null
+++ b/guides/auth.md
@@ -0,0 +1,27 @@
+- [Authentication](#authentication)
+ - [Amazon OpenSearch Service](#amazon-opensearch-service)
+
+# Authentication
+
+## Amazon OpenSearch Service
+
+Requests to [OpenSearch Service and OpenSearch Serverless](https://docs.aws.amazon.com/opensearch-service/index.html) must be signed using the AWS signing protocol. Use `AwsSdk2Transport` to send signed requests.
+
+```java
+SdkHttpClient httpClient = ApacheHttpClient.builder().build();
+
+OpenSearchClient client = new OpenSearchClient(
+ new AwsSdk2Transport(
+ httpClient,
+ "search-...us-west-2.es.amazonaws.com", // OpenSearch endpoint, without https://
+ "es" // signing service name, use "aoss" for OpenSearch Serverless
+ Region.US_WEST_2, // signing service region
+ AwsSdk2TransportOptions.builder().build()
+ )
+);
+
+InfoResponse info = client.info();
+System.out.println(info.version().distribution() + ": " + info.version().number());
+
+httpClient.close();
+```
\ No newline at end of file
diff --git a/guides/bulk.md b/guides/bulk.md
new file mode 100644
index 0000000000..3c12c2ddc7
--- /dev/null
+++ b/guides/bulk.md
@@ -0,0 +1,41 @@
+- [Bulk](#bulk)
+ - [Bulk Indexing](#bulk-indexing)
+ - [Bulk requests](#bulk-requests)
+
+# Bulk
+
+The [Bulk API](https://opensearch.org/docs/latest/api-reference/document-apis/bulk/) lets you add, update, or delete multiple documents in a single request.
+
+## Bulk Indexing
+
+## Bulk requests
+
+```java
+String indexName = "sample-index";
+CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(index).build();
+client.indices().create(createIndexRequest);
+
+ArrayList ops = new ArrayList<>();
+IndexData doc1 = new IndexData("Document 1", "The text of document 1");
+ops.add(new BulkOperation.Builder().index(
+ IndexOperation.of(io -> io.index(indexName).id("id1").document(doc1))
+).build());
+IndexData doc2 = new IndexData("Document 2", "The text of document 2");
+ops.add(new BulkOperation.Builder().index(
+ IndexOperation.of(io -> io.index(indexName).id("id2").document(doc2))
+).build());
+IndexData doc3 = new IndexData("Document 3", "The text of document 3");
+ops.add(new BulkOperation.Builder().index(
+ IndexOperation.of(io -> io.index(indexName).id("id3").document(doc3))
+).build());
+
+BulkRequest.Builder bulkReq = new BulkRequest.Builder()
+ .index(indexName)
+ .operations(ops)
+ .refresh(Refresh.WaitFor);
+BulkResponse bulkResponse = client.bulk(bulkReq.build());
+```
+
+[IndexData](../samples/src/main/java/org/opensearch/client/samples/util/IndexData.java) refers to sample data class.
+
+You can find a working sample of the above code in [Bulk.java](../samples/src/main/java/org/opensearch/client/samples/Bulk.java).
\ No newline at end of file
diff --git a/guides/cat.md b/guides/cat.md
new file mode 100644
index 0000000000..a5a3adcb5e
--- /dev/null
+++ b/guides/cat.md
@@ -0,0 +1,42 @@
+- [Cat API](#cat-api)
+ - [Cat Indices](#cat-indices)
+ - [Cat aliases](#cat-aliases)
+ - [Cat nodes](#cat-nodes)
+ - [Cat point in time segments](#cat-point-in-time-segments)
+
+# Cat API
+
+The CAT API is a human-readable interface that returns plain text instead of traditional JSON.
+
+## Cat Indices
+The following sample code cat indices with required headers and sorted by creation date
+
+```java
+IndicesRequest indicesRequest = new IndicesRequest.Builder()
+ .headers("index,health,status,pri,rep,doc.count,creation.date,creation.date.string").sort("creation.date").build();
+IndicesResponse indicesResponse = javaClient().cat().indices(indicesRequest);
+```
+
+
+## Cat aliases
+The following sample code cat aliases with name "test-alias" and sorted by index
+
+```java
+AliasesRequest aliasesRequest = new AliasesRequest.Builder().name("test-alias").sort("index").build();
+AliasesResponse aliasesResponse = javaClient().cat().aliases(aliasesRequest);
+```
+
+## Cat nodes
+The following sample code cat nodes sorted by cpu
+
+```java
+NodesResponse nodesResponse = javaClient().cat().nodes(r -> r.sort("cpu"));
+```
+
+## Cat point in time segments
+Similarly to the CAT Segments API, the PIT Segments API provides low-level information about the disk utilization of a PIT by describing its Lucene segments.
+
+```java
+SegmentsResponse pitSegmentsResponse = javaClient().cat()
+ .pitSegments(r -> r.headers("index,shard,id,segment,size"));
+```
\ No newline at end of file
diff --git a/guides/data_stream.md b/guides/data_stream.md
new file mode 100644
index 0000000000..7c49807f8c
--- /dev/null
+++ b/guides/data_stream.md
@@ -0,0 +1,54 @@
+- [Data Stream API](#data-stream-api)
+ - [Create a data stream](#create-a-data-stream)
+ - [Get data stream](#get-data-stream)
+ - [Data stream stats](#data-stream-stats)
+ - [Delete data stream and backing indices](#delete-data-stream-and-backing-indices)
+
+# Data Stream API
+
+## Create a data stream
+Before creating a data stream, you need to create an index template which configures a set of indices as a data stream.
+A data stream must have a timestamp field. If not specified, OpenSearch uses `@timestamp` as the default timestamp field name.
+
+The following sample code creates an index template for data stream with a custom timestamp field, and creates a data stream
+which matches the name pattern specified in the index template.
+```java
+String dataStreamIndexTemplateName = "sample-data-stream-template";
+String timestampFieldName = "my_timestamp_field";
+String namePattern = "sample-data-stream-*";
+String dataStreamName = "sample-data-stream-1";
+
+// Create an index template which configures data stream
+PutIndexTemplateRequest putIndexTemplateRequest = new PutIndexTemplateRequest.Builder()
+ .name(dataStreamIndexTemplateName)
+ .indexPatterns(namePattern)
+ .dataStream(new DataStream.Builder()
+ .timestampField(t -> t.name(timestampFieldName))
+ .build())
+ .build();
+PutIndexTemplateResponse putIndexTemplateResponse = client.indices().putIndexTemplate(putIndexTemplateRequest);
+
+// Create a data stream
+CreateDataStreamRequest createDataStreamRequest = new CreateDataStreamRequest.Builder().name(dataStreamName).build();
+CreateDataStreamResponse createDataStreamResponse = client.indices().createDataStream(createDataStreamRequest);
+```
+
+## Get data stream
+```java
+GetDataStreamRequest getDataStreamRequest = new GetDataStreamRequest.Builder().name(dataStreamName).build();
+GetDataStreamResponse getDataStreamResponse = client.indices().getDataStream(getDataStreamRequest);
+```
+
+## Data stream stats
+```java
+DataStreamsStatsRequest dataStreamsStatsRequest = new DataStreamsStatsRequest.Builder().name(dataStreamName).build();
+DataStreamsStatsResponse dataStreamsStatsResponse = client.indices().dataStreamsStats(dataStreamsStatsRequest);
+```
+
+## Delete data stream and backing indices
+```java
+DeleteDataStreamRequest deleteDataStreamRequest = new DeleteDataStreamRequest.Builder().name(dataStreamName).build();
+DeleteDataStreamResponse deleteDataStreamResponse = client.indices().deleteDataStream(deleteDataStreamRequest);
+```
+
+You can find a working sample of the above code in [DataStreamBasics.java](../samples/src/main/java/org/opensearch/client/samples/DataStreamBasics.java).
\ No newline at end of file
diff --git a/guides/index_templates.md b/guides/index_templates.md
new file mode 100644
index 0000000000..43cf79fd2d
--- /dev/null
+++ b/guides/index_templates.md
@@ -0,0 +1,79 @@
+- [Index templates](#index-templates)
+ - [Setup](#setup)
+
+
+# Index templates
+
+Index templates let you initialize new indexes with predefined mappings and settings.
+For example, if you continuously index log data, you can define an index template so that all of these indexes have
+the same number of shards and replicas.
+
+## Setup
+
+To get started, first create a client, create an index template. In this example, an index template is created,
+composed of two component templates:
+
+- `index-settings` which specifies index settings such as shard configuration and slowlog settings
+- `index-mappings` which specifies the field mappings
+
+```java
+import org.apache.hc.core5.http.HttpHost;
+
+final HttpHost[] hosts = new HttpHost[] {
+ new HttpHost("http", "localhost", 9200)
+ };
+
+final OpenSearchTransport transport = ApacheHttpClient5TransportBuilder
+ .builder(hosts)
+ .setMapper(new JacksonJsonpMapper())
+ .build();
+OpenSearchClient client = new OpenSearchClient(transport);
+
+final var indexSettingsComponentTemplate = "index-settings";
+PutComponentTemplateRequest putComponentTemplateRequest = PutComponentTemplateRequest.of(
+ c -> c.name(indexSettingsComponentTemplate)
+ .settings(
+ s -> s.numberOfShards("2")
+ .numberOfReplicas("1")
+ .indexing(
+ i -> i.slowlog(
+ sl -> sl.level("info")
+ .reformat(true)
+ .threshold(th -> th.index(ith -> ith.warn(Time.of(t -> t.time("2s")))))
+ )
+ )
+ .search(
+ se -> se.slowlog(sl -> sl.level("info").threshold(th -> th.query(q -> q.warn(Time.of(t -> t.time("2s"))))))
+ )
+ )
+);
+client.cluster().putComponentTemplate(putComponentTemplateRequest);
+
+final var indexMappingsComponentTemplate = "index-mappings";
+putComponentTemplateRequest = PutComponentTemplateRequest.of(
+ c -> c.name(indexMappingsComponentTemplate).mappings(m -> m.properties("age", p -> p.integer(i -> i)))
+);
+client.cluster().putComponentTemplate(putComponentTemplateRequest);
+
+final var indexTemplateName = "my-index-template";
+PutIndexTemplateRequest putIndexTemplateRequest = PutIndexTemplateRequest.of(
+ it -> it.name(indexTemplateName)
+ .indexPatterns("my-index-*")
+ .composedOf(List.of(indexSettingsComponentTemplate, indexMappingsComponentTemplate))
+);
+
+client.indices().putIndexTemplate(putIndexTemplateRequest);
+```
+
+## Usage
+
+Create an index with a name that matches the index template's `indexPatterns`
+
+```java
+String indexName = "my-index-1";
+client.indices().create(CreateIndexRequest.of(c -> c.index(indexName)));
+```
+
+The index will be created with the index settings and mappings defined by the `my-index-template` index template.
+
+You can find a working sample of the above code in [IndexTemplates.java](../samples/src/main/java/org/opensearch/client/samples/IndexTemplates.java).
\ No newline at end of file
diff --git a/guides/plugins/knn.md b/guides/plugins/knn.md
new file mode 100644
index 0000000000..a2c3db72b8
--- /dev/null
+++ b/guides/plugins/knn.md
@@ -0,0 +1,288 @@
+- [k-NN Plugin](#k-nn-plugin)
+ - [Basic Approximate k-NN](#basic-approximate-k-nn)
+ - [Create an Index](#create-an-index)
+ - [Index Vectors](#index-vectors)
+ - [Search for Nearest Neighbors](#search-for-nearest-neighbors)
+ - [Approximate k-NN with a Boolean Filter](#approximate-k-nn-with-a-boolean-filter)
+ - [Approximate k-NN with an Efficient Filter](#approximate-k-nn-with-an-efficient-filter)
+ - [Exact k-NN with a scoring script](#exact-k-nn-with-a-scoring-script)
+ - [Exact k-NN with the Painless scripting extensions](#exact-k-nn-with-the-painless-scripting-extensions)
+
+# k-NN Plugin
+
+Short for k-nearest neighbors, the k-NN plugin enables users to search for the k-nearest neighbors to a query point across an index of vectors. See the [plugin's documentation](https://opensearch.org/docs/latest/search-plugins/knn/index/) for more information.
+
+## Basic Approximate k-NN
+
+In the following example we create a 5-dimensional k-NN index with random data. You can find a synchronous version of this working sample in [samples/src/main/java/org/opensearch/client/samples/knn/KnnBasics.java](../../samples/src/main/java/org/opensearch/client/samples/knn/KnnBasics.java).
+
+```bash
+$ ./gradlew :samples:run -Dsamples.mainClass=knn.KnnBasics
+
+[Main] INFO - Running main class: org.opensearch.client.samples.knn.KnnBasics
+[KnnBasics] INFO - Server: opensearch@2.7.0
+[KnnBasics] INFO - Creating index my-index
+[KnnBasics] INFO - Indexing 10 vectors
+[KnnBasics] INFO - Waiting for indexing to finish
+[KnnBasics] INFO - Searching for vector [0.67, 0.67, 0.37, 0.0, 0.72]
+[KnnBasics] INFO - Found {values=[0.32, 0.96, 0.41, 0.04, 0.9]} with score 0.8050233
+[KnnBasics] INFO - Found {values=[0.04, 0.58, 0.13, 0.27, 0.37]} with score 0.6031363
+[KnnBasics] INFO - Found {values=[0.96, 0.88, 0.8, 0.41, 0.18]} with score 0.5640794
+[KnnBasics] INFO - Deleting index my-index
+```
+
+### Create an Index
+
+```java
+final var indexName = "my-index";
+final var dimensions = 5;
+
+client.indices().create(r -> r
+ .index(indexName)
+ .settings(s -> s.knn(true))
+ .mappings(m -> m
+ .properties("values", p -> p
+ .knnVector(k -> k.dimension(dimensions)))));
+```
+
+### Index Vectors
+
+Given the following document class definition:
+
+```java
+public static class Doc {
+ private float[] values;
+
+ public Doc() {}
+
+ public Doc(float[] values) {
+ this.values = values;
+ }
+
+ public static Doc rand(int dimensions) {
+ var values = new float[dimensions];
+ for (var i = 0; i < dimensions; ++i) {
+ values[i] = Math.round(Math.random() * 100.0) / 100.0f;
+ }
+ return new Doc(values);
+ }
+
+ // Getters/Setters & toString elided
+}
+```
+
+Create 10 random vectors and insert them using the bulk API:
+
+```java
+final var nVectors = 10;
+var bulkRequest = new BulkRequest.Builder();
+for (var i = 0; i < nVectors; ++i) {
+ var id = Integer.toString(i);
+ var doc = Doc.rand(dimensions);
+ bulkRequest.operations(b -> b
+ .index(o -> o
+ .index(indexName)
+ .id(id)
+ .document(doc)));
+}
+
+client.bulk(bulkRequest.build());
+
+client.indices().refresh(i -> i.index(indexName));
+```
+
+### Search for Nearest Neighbors
+
+Create a random vector of the same size and search for its nearest neighbors.
+
+```java
+final var searchVector = new float[dimensions];
+for (var i = 0; i < dimensions; ++i) {
+ searchVector[i] = Math.round(Math.random() * 100.0) / 100.0f;
+}
+
+var searchResponse = client.search(s -> s
+ .index(indexName)
+ .query(q -> q
+ .knn(k -> k
+ .field("values")
+ .vector(searchVector)
+ .k(3))),
+ Doc.class);
+
+for (var hit : searchResponse.hits().hits()) {
+ System.out.println(hit.source());
+}
+```
+
+## Approximate k-NN with a Boolean Filter
+
+In the [KnnBooleanFilter.java sample](../../samples/src/main/java/org/opensearch/client/samples/knn/KnnBooleanFilter.java) we create a 5-dimensional k-NN index with random data and a `metadata` field that contains a book genre (e.g. `fiction`). The search query is a k-NN search filtered by genre. The filter clause is outside the k-NN query clause and is applied after the k-NN search.
+
+```java
+var searchResponse = client.search(s -> s
+ .index(indexName)
+ .query(q -> q
+ .bool(b -> b
+ .filter(f -> f
+ .bool(b2 -> b2
+ .must(m -> m
+ .term(t -> t
+ .field("metadata.genre")
+ .value(v -> v.stringValue(searchGenre))))))
+ .must(m -> m
+ .knn(k -> k
+ .field("values")
+ .vector(searchVector)
+ .k(5))))),
+ Doc.class);
+```
+
+```bash
+$ ./gradlew :samples:run -Dsamples.mainClass=knn.KnnBooleanFilter
+
+[Main] INFO - Running main class: org.opensearch.client.samples.knn.KnnBooleanFilter
+[KnnBooleanFilter] INFO - Server: opensearch@2.7.0
+[KnnBooleanFilter] INFO - Creating index my-index
+[KnnBooleanFilter] INFO - Indexing 3000 vectors
+[KnnBooleanFilter] INFO - Waiting for indexing to finish
+[KnnBooleanFilter] INFO - Searching for vector [0.18, 0.71, 0.44, 0.03, 0.42] with the 'drama' genre
+[KnnBooleanFilter] INFO - Found {values=[0.21, 0.58, 0.55, 0.09, 0.45], metadata={genre=drama}} with score 0.966744
+[KnnBooleanFilter] INFO - Deleting index my-index
+```
+
+## Approximate k-NN with an Efficient Filter
+
+In the [KnnEfficientFilter.java sample](../../samples/src/main/java/org/opensearch/client/samples/knn/KnnEfficientFilter.java) we implement the example in [the k-NN documentation](https://opensearch.org/docs/latest/search-plugins/knn/filter-search-knn/), which creates an index that uses the Lucene engine and HNSW as the method in the mapping, containing hotel location and parking data, then search for the top three hotels near the location with the coordinates `[5, 4]` that are rated between 8 and 10, inclusive, and provide parking.
+
+```java
+var searchResponse = client.search(s -> s
+ .index(indexName)
+ .size(3)
+ .query(q -> q
+ .knn(k -> k
+ .field("location")
+ .vector(searchLocation)
+ .k(3)
+ .filter(Query.of(f -> f
+ .bool(b -> b
+ .must(m -> m
+ .range(r -> r
+ .field("rating")
+ .gte(JsonData.of(searchRatingMin))
+ .lte(JsonData.of(searchRatingMax))))
+ .must(m -> m
+ .term(t -> t
+ .field("parking")
+ .value(FieldValue.of(searchParking))))))))),
+ Hotel.class);
+```
+
+```bash
+$ ./gradlew :samples:run -Dsamples.mainClass=knn.KnnEfficientFilter
+
+[Main] INFO - Running main class: org.opensearch.client.samples.knn.KnnEfficientFilter
+[KnnEfficientFilter] INFO - Server: opensearch@2.7.0
+[KnnEfficientFilter] INFO - Creating index hotels-index
+[KnnEfficientFilter] INFO - Indexing hotel {location=[5.2, 4.0], parking=true, rating=5} with id 1
+[KnnEfficientFilter] INFO - Indexing hotel {location=[5.2, 3.9], parking=false, rating=4} with id 2
+[KnnEfficientFilter] INFO - Indexing hotel {location=[4.9, 3.4], parking=true, rating=9} with id 3
+[KnnEfficientFilter] INFO - Indexing hotel {location=[4.2, 4.6], parking=false, rating=6} with id 4
+[KnnEfficientFilter] INFO - Indexing hotel {location=[3.3, 4.5], parking=true, rating=8} with id 5
+[KnnEfficientFilter] INFO - Indexing hotel {location=[6.4, 3.4], parking=true, rating=9} with id 6
+[KnnEfficientFilter] INFO - Indexing hotel {location=[4.2, 6.2], parking=true, rating=5} with id 7
+[KnnEfficientFilter] INFO - Indexing hotel {location=[2.4, 4.0], parking=true, rating=8} with id 8
+[KnnEfficientFilter] INFO - Indexing hotel {location=[1.4, 3.2], parking=false, rating=5} with id 9
+[KnnEfficientFilter] INFO - Indexing hotel {location=[7.0, 9.9], parking=true, rating=9} with id 10
+[KnnEfficientFilter] INFO - Indexing hotel {location=[3.0, 2.3], parking=false, rating=6} with id 11
+[KnnEfficientFilter] INFO - Indexing hotel {location=[5.0, 1.0], parking=true, rating=3} with id 12
+[KnnEfficientFilter] INFO - Indexing 12 documents
+[KnnEfficientFilter] INFO - Waiting for indexing to finish
+[KnnEfficientFilter] INFO - Searching for hotel near [5.0, 4.0] with rating >=8,<=10 and parking=true
+[KnnEfficientFilter] INFO - Found {location=[4.9, 3.4], parking=true, rating=9} with score 0.72992706
+[KnnEfficientFilter] INFO - Found {location=[6.4, 3.4], parking=true, rating=9} with score 0.3012048
+[KnnEfficientFilter] INFO - Found {location=[3.3, 4.5], parking=true, rating=8} with score 0.24154587
+[KnnEfficientFilter] INFO - Deleting index hotels-index
+```
+
+## Exact k-NN with a scoring script
+
+In the [KnnScriptScore.java sample](../../samples/src/main/java/org/opensearch/client/samples/knn/KnnScriptScore.java) we create a 5-dimensional k-NN index with random data. The search query uses the [k-NN scoring script](https://opensearch.org/docs/latest/search-plugins/knn/knn-score-script/) to calculate exact nearest neighbors.
+
+```java
+var searchResponse = client.search(s -> s
+ .index(indexName)
+ .query(q -> q
+ .scriptScore(ss -> ss
+ .query(qq -> qq.matchAll(m -> m))
+ .script(sss -> sss
+ .inline(i -> i
+ .source("knn_score")
+ .lang("knn")
+ .params("field", JsonData.of("values"))
+ .params("query_value", JsonData.of(searchVector))
+ .params("space_type", JsonData.of("cosinesimil")))))),
+ Doc.class);
+```
+
+```bash
+$ ./gradlew :samples:run -Dsamples.mainClass=knn.KnnScriptScore
+
+[Main] INFO - Running main class: org.opensearch.client.samples.knn.KnnScriptScore
+[KnnScriptScore] INFO - Server: opensearch@2.7.0
+[KnnScriptScore] INFO - Creating index my-index
+[KnnScriptScore] INFO - Indexing 10 vectors
+[KnnScriptScore] INFO - Waiting for indexing to finish
+[KnnScriptScore] INFO - Searching for vector [0.94, 0.1, 0.39, 0.63, 0.42]
+[KnnScriptScore] INFO - Found {values=[0.66, 0.23, 0.15, 0.44, 0.13]} with score 1.9564294
+[KnnScriptScore] INFO - Found {values=[0.94, 0.05, 0.86, 0.68, 0.05]} with score 1.90958
+[KnnScriptScore] INFO - Found {values=[0.88, 0.72, 0.29, 0.48, 0.56]} with score 1.8788767
+[KnnScriptScore] INFO - Found {values=[0.97, 0.99, 0.66, 0.61, 0.91]} with score 1.847905
+[KnnScriptScore] INFO - Found {values=[0.18, 0.29, 0.43, 0.63, 0.25]} with score 1.7819176
+[KnnScriptScore] INFO - Found {values=[0.35, 0.2, 0.62, 0.4, 0.96]} with score 1.7673628
+[KnnScriptScore] INFO - Found {values=[0.34, 0.59, 0.05, 0.47, 0.54]} with score 1.7316635
+[KnnScriptScore] INFO - Found {values=[0.55, 0.98, 0.07, 0.57, 0.06]} with score 1.6385877
+[KnnScriptScore] INFO - Found {values=[0.03, 0.72, 0.89, 0.83, 0.46]} with score 1.6147845
+[KnnScriptScore] INFO - Found {values=[0.17, 0.81, 0.09, 0.21, 0.3]} with score 1.4616101
+[KnnScriptScore] INFO - Deleting index my-index
+```
+
+## Exact k-NN with the Painless scripting extensions
+
+In the [KnnPainlessScript.java sample](../../samples/src/main/java/org/opensearch/client/samples/knn/KnnPainlessScript.java) we create a 5-dimensional k-NN index with random data. The search query uses the [k-NN Painless extensions](https://opensearch.org/docs/latest/search-plugins/knn/painless-functions/) to calculate exact nearest neighbors.
+
+```java
+var searchResponse = client.search(s -> s
+ .index(indexName)
+ .query(q -> q
+ .scriptScore(ss -> ss
+ .query(qq -> qq.matchAll(m -> m))
+ .script(sss -> sss
+ .inline(i -> i
+ .source("1.0 + cosineSimilarity(params.query_value, doc[params.field])")
+ .params("field", JsonData.of("values"))
+ .params("query_value", JsonData.of(searchVector)))))),
+ Doc.class);
+```
+
+```bash
+$ ./gradlew :samples:run -Dsamples.mainClass=knn.KnnPainlessScript
+
+[Main] INFO - Running main class: org.opensearch.client.samples.knn.KnnPainlessScript
+[KnnPainlessScript] INFO - Server: opensearch@2.7.0
+[KnnPainlessScript] INFO - Creating index my-index
+[KnnPainlessScript] INFO - Indexing 10 vectors
+[KnnPainlessScript] INFO - Waiting for indexing to finish
+[KnnPainlessScript] INFO - Searching for vector [0.57, 0.86, 0.37, 0.07, 0.38]
+[KnnPainlessScript] INFO - Found {values=[1.0, 0.6, 0.66, 0.03, 0.18]} with score 1.8911908
+[KnnPainlessScript] INFO - Found {values=[0.4, 0.39, 0.63, 0.09, 0.39]} with score 1.8776901
+[KnnPainlessScript] INFO - Found {values=[0.32, 0.98, 0.7, 0.7, 0.77]} with score 1.8616674
+[KnnPainlessScript] INFO - Found {values=[0.93, 0.35, 0.27, 0.45, 0.81]} with score 1.789043
+[KnnPainlessScript] INFO - Found {values=[0.81, 0.36, 0.87, 0.78, 0.56]} with score 1.7457235
+[KnnPainlessScript] INFO - Found {values=[0.55, 0.19, 0.61, 0.42, 0.4]} with score 1.743325
+[KnnPainlessScript] INFO - Found {values=[0.12, 0.54, 0.09, 0.83, 0.28]} with score 1.6045148
+[KnnPainlessScript] INFO - Found {values=[0.0, 0.04, 0.63, 0.07, 0.9]} with score 1.479921
+[KnnPainlessScript] INFO - Found {values=[0.41, 0.05, 0.52, 1.0, 0.18]} with score 1.4306322
+[KnnPainlessScript] INFO - Found {values=[0.22, 0.1, 0.59, 0.89, 0.15]} with score 1.4274814
+[KnnPainlessScript] INFO - Deleting index my-index
+```
\ No newline at end of file
diff --git a/guides/point_in_time.md b/guides/point_in_time.md
new file mode 100644
index 0000000000..f2fa36118b
--- /dev/null
+++ b/guides/point_in_time.md
@@ -0,0 +1,53 @@
+- [Point-in-Time](#point-in-time)
+ - [Point-In-Time API](#point-in-time-api)
+ - [Creating a point in time](#creating-a-point-in-time)
+ - [List all point in time](#list-all-point-in-time)
+ - [Delete point in time](#delete-point-in-time)
+
+# Point-in-Time
+
+[Point in Time (PIT)](https://opensearch.org/docs/latest/search-plugins/point-in-time/) lets you run different queries against a dataset that is fixed in time.
+
+## Point-In-Time API
+
+### Creating a point in time
+
+To create a PIT, first create an index.
+
+```
+java
+String index = "sample-index";
+CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(index).build();
+client.indices().create(createIndexRequest);
+```
+
+To create a PIT, the keep_alive query parameter is required; it specifies how long to keep a PIT.
+
+```java
+CreatePitRequest createPitRequest = new CreatePitRequest.Builder()
+ .targetIndexes(Collections.singletonList(index))
+ .keepAlive(new Time.Builder().time("100m").build()).build();
+
+CreatePitResponse createPitResponse = client.createPit(createPitRequest);
+```
+
+### List all point in time
+
+Returns all PITs in the OpenSearch cluster.
+
+```java
+ListAllPitResponse listAllPitResponse = client.listAllPit();
+```
+
+### Delete point in time
+
+Deletes one, several, or all PITs. PITs are automatically deleted when the keep_alive time period elapses. However, to deallocate resources, you can delete a PIT using the Delete PIT API. The Delete PIT API supports deleting a list of PITs by ID or deleting all PITs at once.
+
+```java
+DeletePitRequest deletePitRequest = new DeletePitRequest.Builder()
+ .pitId(Collections.singletonList(createPitResponse.pitId())).build();
+
+DeletePitResponse deletePitResponse = client.deletePit(deletePitRequest);
+```
+
+You can find a working sample of the above code in [PointInTime.java](../samples/src/main/java/org/opensearch/client/samples/PointInTime.java).
\ No newline at end of file
diff --git a/guides/search.md b/guides/search.md
new file mode 100644
index 0000000000..d343b30420
--- /dev/null
+++ b/guides/search.md
@@ -0,0 +1,283 @@
+- [Search](#search)
+ - [Setup](#setup)
+ - [Search API](#search-api)
+ - [Basic Search](#basic-search)
+ - [Get raw JSON results](#get-raw-json-results)
+ - [Search documents using a match query](#search-documents-using-a-match-query)
+ - [Search documents using suggesters](#search-documents-using-suggesters)
+ - [Using completion suggester](#using-completion-suggester)
+ - [Using term suggester](#using-term-suggester)
+ - [Using phrase suggester](#using-phrase-suggester)
+ - [Aggregations](#aggregations)
+
+# Search
+
+OpenSearch provides a powerful search API that allows you to search for documents in an index. The search API supports a number of parameters that allow you to customize the search operation. In this guide, we will explore the search API and its parameters.
+
+## Setup
+
+To get started, first create a client, create an index and index some documents:
+
+```java
+import org.apache.hc.core5.http.HttpHost;
+
+final HttpHost[] hosts = new HttpHost[] {
+ new HttpHost("http", "localhost", 9200)
+ };
+
+final OpenSearchTransport transport = ApacheHttpClient5TransportBuilder
+ .builder(hosts)
+ .setMapper(new JacksonJsonpMapper())
+ .build();
+OpenSearchClient client = new OpenSearchClient(transport);
+
+String index = "sample-index";
+CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(index).build();
+client.indices().create(createIndexRequest);
+
+IndexData indexData = new IndexData("Document 1", "Text for document 1");
+IndexRequest indexRequest = new IndexRequest.Builder().index(index).id("1").document(indexData).build();
+client.index(indexRequest);
+
+indexData = new IndexData("Document 2", "Text for document 2");
+indexRequest = new IndexRequest.Builder().index(index).id("2").document(indexData).build();
+client.index(indexRequest);
+```
+
+[IndexData](../samples/src/main/java/org/opensearch/client/samples/util/IndexData.java) refers to sample data class.
+
+## Search API
+
+### Basic Search
+
+```java
+SearchResponse searchResponse = client.search(s -> s.index(index), IndexData.class);
+for (int i = 0; i < searchResponse.hits().hits().size(); i++) {
+ System.out.println(searchResponse.hits().hits().get(i).source());
+}
+```
+
+#### Get raw JSON results
+
+When the target class is not defined or if the response result is a semi-structured data not tied to an object definition, use a raw JSON data representation as the target class. For example, the below snippet uses `ObjectNode` from jackson.
+
+```java
+SearchResponse searchResponse = client.search(b -> b.index(index), ObjectNode.class);
+for (int i = 0; i < searchResponse.hits().hits().size(); i++) {
+ System.out.println(searchResponse.hits().hits().get(i).source());
+}
+```
+
+### Search documents using a match query
+
+```java
+SearchRequest searchRequest = new SearchRequest.Builder().query(q -> q.match(m -> m.field("text")
+ .query(FieldValue.of("Text for document 2"))))
+ .build();
+
+SearchResponse searchResponse = client.search(searchRequest, IndexData.class);
+for (int i = 0; i < searchResponse.hits().hits().size(); i++) {
+ System.out.println(searchResponse.hits().hits().get(i).source());
+}
+```
+
+### Search documents using suggesters
+
+[AppData](../samples/src/main/java/org/opensearch/client/samples/util/AppData.java) refers to the sample data class used in the below samples.
+
+#### Using completion suggester
+
+```java
+String index = "completion-suggester";
+
+Property intValueProp = new Property.Builder()
+ .long_(v -> v)
+ .build();
+Property msgCompletionProp = new Property.Builder()
+ .completion(c -> c)
+ .build();
+client.indices().create(c -> c
+ .index(index)
+ .mappings(m -> m
+ .properties("intValue", intValueProp)
+ .properties("msg", msgCompletionProp)));
+
+AppData appData = new AppData();
+appData.setIntValue(1337);
+appData.setMsg("foo");
+
+client.index(b -> b
+ .index(index)
+ .id("1")
+ .document(appData)
+ .refresh(Refresh.True));
+
+appData.setIntValue(1338);
+appData.setMsg("foobar");
+
+client.index(b -> b
+ .index(index)
+ .id("2")
+ .document(appData)
+ .refresh(Refresh.True));
+
+String suggesterName = "msgSuggester";
+
+CompletionSuggester completionSuggester = FieldSuggesterBuilders.completion()
+ .field("msg")
+ .size(1)
+ .build();
+FieldSuggester fieldSuggester = new FieldSuggester.Builder().prefix("foo")
+ .completion(completionSuggester)
+ .build();
+Suggester suggester = new Suggester.Builder()
+ .suggesters(Collections.singletonMap(suggesterName, fieldSuggester))
+ .build();
+SearchRequest searchRequest = new SearchRequest.Builder()
+ .index(index)
+ .suggest(suggester)
+ .build();
+
+SearchResponse response = client.search(searchRequest, AppData.class);
+```
+
+#### Using term suggester
+
+```java
+String index = "term-suggester";
+
+// term suggester does not require a special mapping
+client.indices().create(c -> c
+ .index(index));
+
+AppData appData = new AppData();
+appData.setIntValue(1337);
+appData.setMsg("foo");
+
+client.index(b -> b
+ .index(index)
+ .id("1")
+ .document(appData)
+ .refresh(Refresh.True));
+
+appData.setIntValue(1338);
+appData.setMsg("foobar");
+
+client.index(b -> b
+ .index(index)
+ .id("2")
+ .document(appData)
+ .refresh(Refresh.True));
+
+String suggesterName = "msgSuggester";
+
+TermSuggester termSuggester = FieldSuggesterBuilders.term()
+ .field("msg")
+ .size(1)
+ .build();
+FieldSuggester fieldSuggester = new FieldSuggester.Builder().text("fool")
+ .term(termSuggester)
+ .build();
+Suggester suggester = new Suggester.Builder()
+ .suggesters(Collections.singletonMap(suggesterName, fieldSuggester))
+ .build();
+SearchRequest searchRequest = new SearchRequest.Builder()
+ .index(index)
+ .suggest(suggester)
+ .build();
+
+SearchResponse response = client.search(searchRequest, AppData.class);
+```
+
+#### Using phrase suggester
+
+```java
+String index = "test-phrase-suggester";
+
+ShingleTokenFilter shingleTokenFilter = new ShingleTokenFilter.Builder().minShingleSize("2")
+ .maxShingleSize("3")
+ .build();
+
+Analyzer analyzer = new Analyzer.Builder()
+ .custom(new CustomAnalyzer.Builder().tokenizer("standard")
+ .filter(Arrays.asList("lowercase", "shingle")).build())
+ .build();
+
+TokenFilter tokenFilter = new TokenFilter.Builder()
+ .definition(new TokenFilterDefinition.Builder()
+ .shingle(shingleTokenFilter).build())
+ .build();
+
+IndexSettingsAnalysis indexSettingsAnalysis = new IndexSettingsAnalysis.Builder()
+ .analyzer("trigram", analyzer)
+ .filter("shingle", tokenFilter)
+ .build();
+
+IndexSettings settings = new IndexSettings.Builder().analysis(indexSettingsAnalysis).build();
+
+TypeMapping mapping = new TypeMapping.Builder().properties("msg", new Property.Builder()
+ .text(new TextProperty.Builder().fields("trigram", new Property.Builder()
+ .text(new TextProperty.Builder().analyzer("trigram").build())
+ .build()).build())
+ .build()).build();
+
+client.indices().create(c -> c
+ .index(index)
+ .settings(settings)
+ .mappings(mapping));
+
+AppData appData = new AppData();
+appData.setIntValue(1337);
+appData.setMsg("Design Patterns");
+
+client.index(b -> b
+ .index(index)
+ .id("1")
+ .document(appData)
+ .refresh(Refresh.True));
+
+appData.setIntValue(1338);
+appData.setMsg("Software Architecture Patterns Explained");
+
+client.index(b -> b
+ .index(index)
+ .id("2")
+ .document(appData)
+ .refresh(Refresh.True));
+
+String suggesterName = "msgSuggester";
+
+PhraseSuggester phraseSuggester = FieldSuggesterBuilders.phrase()
+ .field("msg.trigram")
+ .build();
+FieldSuggester fieldSuggester = new FieldSuggester.Builder().text("design paterns")
+ .phrase(phraseSuggester)
+ .build();
+Suggester suggester = new Suggester.Builder()
+ .suggesters(Collections.singletonMap(suggesterName, fieldSuggester))
+ .build();
+SearchRequest searchRequest = new SearchRequest.Builder()
+ .index(index)
+ .suggest(suggester)
+ .build();
+
+SearchResponse response = client.search(searchRequest, AppData.class);
+```
+
+### Aggregations
+
+```java
+SearchRequest searchRequest = new SearchRequest.Builder().query(q -> q.match(m -> m.field("title")
+ .query(FieldValue.of("Document 1"))))
+ .aggregations("titles", new Aggregation.Builder().terms(t -> t.field("title.keyword"))
+ .build())
+ .build();
+
+SearchResponse searchResponse = client.search(searchRequest, IndexData.class);
+for (Map.Entry entry : searchResponse.aggregations().entrySet()) {
+ System.out.println("Agg - " + entry.getKey());
+ entry.getValue().sterms().buckets().array().forEach(b -> System.out.printf("%s : %d%n", b.key(), b.docCount()));
+}
+```
+
+You can find a working sample of the above code in [Search.java](../samples/src/main/java/org/opensearch/client/samples/Search.java).
\ No newline at end of file
diff --git a/java-client/build.gradle.kts b/java-client/build.gradle.kts
index 307c75393b..d3ff87a199 100644
--- a/java-client/build.gradle.kts
+++ b/java-client/build.gradle.kts
@@ -46,13 +46,18 @@ buildscript {
plugins {
java
`java-library`
- checkstyle
`maven-publish`
- id("com.github.jk1.dependency-license-report") version "1.19"
+ id("com.github.jk1.dependency-license-report") version "2.5"
+ id("org.owasp.dependencycheck") version "9.0.8"
+ id("com.diffplug.spotless") version "6.24.0"
}
-checkstyle {
- toolVersion = "10.0"
+apply(plugin = "org.owasp.dependencycheck")
+
+configurations {
+ all {
+ exclude(group = "software.amazon.awssdk", module = "third-party-jackson-core")
+ }
}
java {
@@ -104,6 +109,10 @@ tasks.withType {
}
}
+tasks.build {
+ dependsOn("spotlessJavaCheck")
+}
+
tasks.test {
systemProperty("tests.security.manager", "false")
@@ -131,15 +140,17 @@ val integrationTest = task("integrationTest") {
systemProperty("password", System.getProperty("password", "admin"))
systemProperty("tests.awsSdk2support.domainHost",
System.getProperty("tests.awsSdk2support.domainHost", null))
+ systemProperty("tests.awsSdk2support.serviceName",
+ System.getProperty("tests.awsSdk2support.serviceName", "es"))
systemProperty("tests.awsSdk2support.domainRegion",
System.getProperty("tests.awsSdk2support.domainRegion", "us-east-1"))
}
dependencies {
- val opensearchVersion = "2.3.0"
- val jacksonVersion = "2.13.4"
- val jacksonDatabindVersion = "2.13.4.2"
+ val opensearchVersion = "2.7.0"
+ val jacksonVersion = "2.15.2"
+ val jacksonDatabindVersion = "2.15.2"
// Apache 2.0
implementation("org.opensearch.client", "opensearch-rest-client", opensearchVersion)
@@ -152,7 +163,7 @@ dependencies {
// Needed even if using Jackson to have an implementation of the Jsonp object model
// EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
// https://github.com/eclipse-ee4j/parsson
- api("org.eclipse.parsson:parsson:1.1.1")
+ api("org.eclipse.parsson:parsson:1.1.4")
// EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
// http://json-b.net/
@@ -164,21 +175,27 @@ dependencies {
implementation("com.fasterxml.jackson.core", "jackson-databind", jacksonDatabindVersion)
testImplementation("com.fasterxml.jackson.datatype", "jackson-datatype-jakarta-jsonp", jacksonVersion)
+ // ApacheHttpClient5Transport dependencies (optional)
+ implementation("org.apache.httpcomponents.client5", "httpclient5", "5.3")
+ implementation("org.apache.httpcomponents.core5", "httpcore5", "5.2.4")
+
// For AwsSdk2Transport
- "awsSdk2SupportImplementation"("software.amazon.awssdk","sdk-core","[2.15,3.0)")
- "awsSdk2SupportImplementation"("software.amazon.awssdk","auth","[2.15,3.0)")
+ "awsSdk2SupportCompileOnly"("software.amazon.awssdk","sdk-core","[2.15,3.0)")
+ "awsSdk2SupportCompileOnly"("software.amazon.awssdk","auth","[2.15,3.0)")
testImplementation("software.amazon.awssdk","sdk-core","[2.15,3.0)")
testImplementation("software.amazon.awssdk","auth","[2.15,3.0)")
testImplementation("software.amazon.awssdk","aws-crt-client","[2.15,3.0)")
testImplementation("software.amazon.awssdk","apache-client","[2.15,3.0)")
testImplementation("software.amazon.awssdk","sts","[2.15,3.0)")
-
+ testImplementation("org.apache.logging.log4j", "log4j-api","[2.17.1,3.0)")
+ testImplementation("org.apache.logging.log4j", "log4j-core","[2.17.1,3.0)")
+
// EPL-2.0 OR BSD-3-Clause
// https://eclipse-ee4j.github.io/yasson/
implementation("org.eclipse", "yasson", "2.0.2")
// https://github.com/classgraph/classgraph
- testImplementation("io.github.classgraph:classgraph:4.8.149")
+ testImplementation("io.github.classgraph:classgraph:4.8.161")
// Eclipse 1.0
testImplementation("junit", "junit" , "4.13.2") {
@@ -187,7 +204,7 @@ dependencies {
}
licenseReport {
- renderers = arrayOf(SpdxReporter(File(rootProject.buildDir, "release/dependencies.csv")))
+ renderers = arrayOf(SpdxReporter(rootProject.layout.buildDirectory.file("release/dependencies.csv").get().getAsFile()))
excludeGroups = arrayOf("org.opensearch.client")
}
@@ -240,23 +257,42 @@ class SpdxReporter(val dest: File) : ReportRenderer {
tasks.withType {
doLast {
ant.withGroovyBuilder {
- "checksum"("algorithm" to "md5", "file" to archivePath)
- "checksum"("algorithm" to "sha1", "file" to archivePath)
- "checksum"("algorithm" to "sha-256", "file" to archivePath, "fileext" to ".sha256")
- "checksum"("algorithm" to "sha-512", "file" to archivePath, "fileext" to ".sha512")
+ "checksum"("algorithm" to "md5", "file" to archiveFile.get())
+ "checksum"("algorithm" to "sha1", "file" to archiveFile.get())
+ "checksum"("algorithm" to "sha-256", "file" to archiveFile.get(), "fileext" to ".sha256")
+ "checksum"("algorithm" to "sha-512", "file" to archiveFile.get(), "fileext" to ".sha512")
}
}
}
+spotless {
+ java {
+
+ target("**/*.java")
+
+ // Use the default importOrder configuration
+ importOrder()
+ removeUnusedImports()
+
+ eclipse().configFile("../buildSrc/formatterConfig.xml")
+
+ trimTrailingWhitespace()
+ endWithNewline()
+ }
+}
+
publishing {
repositories{
if (version.toString().endsWith("SNAPSHOT")) {
maven("https://aws.oss.sonatype.org/content/repositories/snapshots/") {
- name = "snapshotRepo"
- credentials(PasswordCredentials::class)
+ name = "Snapshots"
+ credentials {
+ username = System.getenv("SONATYPE_USERNAME")
+ password = System.getenv("SONATYPE_PASSWORD")
+ }
}
}
- maven("${rootProject.buildDir}/repository") {
+ maven(rootProject.layout.buildDirectory.dir("repository")) {
name = "localRepo"
}
}
diff --git a/java-client/src/main/java/org/opensearch/client/ApiClient.java b/java-client/src/main/java/org/opensearch/client/ApiClient.java
index 1938dea4bb..327fc235ec 100644
--- a/java-client/src/main/java/org/opensearch/client/ApiClient.java
+++ b/java-client/src/main/java/org/opensearch/client/ApiClient.java
@@ -32,12 +32,11 @@
package org.opensearch.client;
-import org.opensearch.client.transport.TransportOptions;
-import org.opensearch.client.transport.Transport;
+import javax.annotation.Nullable;
import org.opensearch.client.json.JsonpDeserializer;
import org.opensearch.client.json.JsonpMapperBase;
-
-import javax.annotation.Nullable;
+import org.opensearch.client.transport.Transport;
+import org.opensearch.client.transport.TransportOptions;
public abstract class ApiClient> {
diff --git a/java-client/src/main/java/org/opensearch/client/json/AttributedJsonpMapper.java b/java-client/src/main/java/org/opensearch/client/json/AttributedJsonpMapper.java
index 92eb9d0b8f..baf834324a 100644
--- a/java-client/src/main/java/org/opensearch/client/json/AttributedJsonpMapper.java
+++ b/java-client/src/main/java/org/opensearch/client/json/AttributedJsonpMapper.java
@@ -72,7 +72,7 @@ public boolean ignoreUnknownFields() {
@SuppressWarnings("unchecked")
public T attribute(String name) {
if (this.name.equals(name)) {
- return (T)this.value;
+ return (T) this.value;
} else {
return mapper.attribute(name);
}
diff --git a/java-client/src/main/java/org/opensearch/client/json/BuildFunctionDeserializer.java b/java-client/src/main/java/org/opensearch/client/json/BuildFunctionDeserializer.java
index 677fb94098..aeb22671c2 100644
--- a/java-client/src/main/java/org/opensearch/client/json/BuildFunctionDeserializer.java
+++ b/java-client/src/main/java/org/opensearch/client/json/BuildFunctionDeserializer.java
@@ -33,7 +33,6 @@
package org.opensearch.client.json;
import jakarta.json.stream.JsonParser;
-
import java.util.function.Function;
/**
diff --git a/java-client/src/main/java/org/opensearch/client/json/DelegatingDeserializer.java b/java-client/src/main/java/org/opensearch/client/json/DelegatingDeserializer.java
index 84e96ef5dd..1cf864be7b 100644
--- a/java-client/src/main/java/org/opensearch/client/json/DelegatingDeserializer.java
+++ b/java-client/src/main/java/org/opensearch/client/json/DelegatingDeserializer.java
@@ -33,7 +33,6 @@
package org.opensearch.client.json;
import jakarta.json.stream.JsonParser;
-
import java.util.EnumSet;
public abstract class DelegatingDeserializer implements JsonpDeserializer {
@@ -68,7 +67,7 @@ public T deserialize(JsonParser parser, JsonpMapper mapper, JsonParser.Event eve
*/
public static JsonpDeserializer> unwrap(JsonpDeserializer> deserializer) {
while (deserializer instanceof DelegatingDeserializer) {
- deserializer = ((DelegatingDeserializer,?>) deserializer).unwrap();
+ deserializer = ((DelegatingDeserializer, ?>) deserializer).unwrap();
}
return deserializer;
}
diff --git a/java-client/src/main/java/org/opensearch/client/json/DelegatingJsonParser.java b/java-client/src/main/java/org/opensearch/client/json/DelegatingJsonParser.java
new file mode 100644
index 0000000000..c1b5b5c303
--- /dev/null
+++ b/java-client/src/main/java/org/opensearch/client/json/DelegatingJsonParser.java
@@ -0,0 +1,136 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+/*
+ * 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.
+ */
+
+/*
+ * Modifications Copyright OpenSearch Contributors. See
+ * GitHub history for details.
+ */
+
+package org.opensearch.client.json;
+
+import jakarta.json.JsonArray;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+import jakarta.json.stream.JsonLocation;
+import jakarta.json.stream.JsonParser;
+import java.math.BigDecimal;
+import java.util.Map;
+import java.util.stream.Stream;
+
+public abstract class DelegatingJsonParser implements JsonParser {
+
+ private final JsonParser parser;
+
+ public DelegatingJsonParser(JsonParser parser) {
+ this.parser = parser;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return parser.hasNext();
+ }
+
+ @Override
+ public Event next() {
+ return parser.next();
+ }
+
+ @Override
+ public String getString() {
+ return parser.getString();
+ }
+
+ @Override
+ public boolean isIntegralNumber() {
+ return parser.isIntegralNumber();
+ }
+
+ @Override
+ public int getInt() {
+ return parser.getInt();
+ }
+
+ @Override
+ public long getLong() {
+ return parser.getLong();
+ }
+
+ @Override
+ public BigDecimal getBigDecimal() {
+ return parser.getBigDecimal();
+ }
+
+ @Override
+ public JsonLocation getLocation() {
+ return parser.getLocation();
+ }
+
+ @Override
+ public JsonObject getObject() {
+ return parser.getObject();
+ }
+
+ @Override
+ public JsonValue getValue() {
+ return parser.getValue();
+ }
+
+ @Override
+ public JsonArray getArray() {
+ return parser.getArray();
+ }
+
+ @Override
+ public Stream getArrayStream() {
+ return parser.getArrayStream();
+ }
+
+ @Override
+ public Stream> getObjectStream() {
+ return parser.getObjectStream();
+ }
+
+ @Override
+ public Stream getValueStream() {
+ return parser.getValueStream();
+ }
+
+ @Override
+ public void skipArray() {
+ parser.skipArray();
+ }
+
+ @Override
+ public void skipObject() {
+ parser.skipObject();
+ }
+
+ @Override
+ public void close() {
+ parser.close();
+ }
+}
diff --git a/java-client/src/main/java/org/opensearch/client/json/ExternallyTaggedUnion.java b/java-client/src/main/java/org/opensearch/client/json/ExternallyTaggedUnion.java
index 84a6e6e7e4..4d5b954539 100644
--- a/java-client/src/main/java/org/opensearch/client/json/ExternallyTaggedUnion.java
+++ b/java-client/src/main/java/org/opensearch/client/json/ExternallyTaggedUnion.java
@@ -32,49 +32,66 @@
package org.opensearch.client.json;
-import org.opensearch.client.util.TaggedUnion;
+import static jakarta.json.stream.JsonParser.Event;
+
import jakarta.json.stream.JsonGenerator;
import jakarta.json.stream.JsonParser;
import jakarta.json.stream.JsonParsingException;
-
+import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
-
-import static jakarta.json.stream.JsonParser.Event;
+import java.util.function.Function;
+import javax.annotation.Nullable;
+import org.opensearch.client.util.TaggedUnion;
/**
* Utilities for union types whose discriminant is not directly part of the structure, either as an enclosing property name or as
- * an inner property. This is used for Elasticsearch aggregation results and suggesters, using the {@code typed_keys} parameter that
+ * an inner property. This is used for OpenSearch aggregation results and suggesters, using the {@code typed_keys} parameter that
* encodes a name+type in a single JSON property.
*
*/
-public interface ExternallyTaggedUnion {
+public class ExternallyTaggedUnion {
+
+ private ExternallyTaggedUnion() {}
/**
* A deserializer for externally-tagged unions. Since the union variant discriminant is provided externally, this cannot be a
* regular {@link JsonpDeserializer} as the caller has to provide the discriminant value.
*/
- class Deserializer, Member> {
+ public static class Deserializer, Member> {
private final Map> deserializers;
- private final BiFunction unionCtor;
+ private final Function unionCtor;
+ @Nullable
+ private final BiFunction unKnownUnionCtor;
- public Deserializer(Map> deserializers, BiFunction unionCtor) {
+ public Deserializer(Map> deserializers, Function unionCtor) {
this.deserializers = deserializers;
this.unionCtor = unionCtor;
+ this.unKnownUnionCtor = null;
}
- /**
- * Deserialize a union value, given its type.
- */
- public Union deserialize(String type, JsonParser parser, JsonpMapper mapper) {
+ public Deserializer(
+ Map> deserializers,
+ Function unionCtor,
+ BiFunction unKnownUnionCtor
+ ) {
+ this.deserializers = deserializers;
+ this.unionCtor = unionCtor;
+ this.unKnownUnionCtor = unKnownUnionCtor;
+ }
+
+ public Union deserialize(String type, JsonParser parser, JsonpMapper mapper, Event event) {
JsonpDeserializer extends Member> deserializer = deserializers.get(type);
if (deserializer == null) {
- throw new JsonParsingException("Unknown variant type '" + type + "'", parser.getLocation());
+ if (unKnownUnionCtor != null) {
+ return unKnownUnionCtor.apply(type, JsonData._DESERIALIZER.deserialize(parser, mapper, event));
+ }
}
- return unionCtor.apply(type, deserializer.deserialize(parser, mapper));
+ return unionCtor.apply(deserializer.deserialize(parser, mapper, event));
}
/**
@@ -86,8 +103,9 @@ public TypedKeysDeserializer typedKeys() {
}
}
- class TypedKeysDeserializer> extends JsonpDeserializerBase