From 3f4a1e91010dbebbc9adc764f6b2afd8810039e7 Mon Sep 17 00:00:00 2001 From: Shyim Date: Wed, 2 Nov 2022 01:15:28 +0100 Subject: [PATCH] added sample code to user_guide.md Signed-off-by: Micheal A. --- .github/workflows/test.yml | 164 +++++++++--- .github/workflows/test_unreleased.yml | 8 - .gitignore | 3 +- CHANGELOG.md | 3 + README.md | 7 +- USER_GUIDE.md | 349 ++++++++++++++++++++------ composer.json | 7 +- phpunit-integration-tests.xml | 18 -- phpunit.xml.dist | 16 +- 9 files changed, 432 insertions(+), 143 deletions(-) delete mode 100644 phpunit-integration-tests.xml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d3ff9b11f..d7e972e07 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,10 +1,101 @@ -name: PHP test +name: PHP -on: [push, pull_request] +on: + push: + paths: + - "**.php" + pull_request: jobs: - test: - name: Test + code-style: + name: Code Style + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Use PHP 8.1 + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + extensions: yaml, zip, curl + env: + COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies + run: | + composer install --prefer-dist + + - name: PHP CS Fixer + run: | + composer run-script php-cs + + static-analyse: + name: PHPStan + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Use PHP 8.1 + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + extensions: yaml, zip, curl + env: + COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies + run: | + composer install --prefer-dist + + - name: PHP Static Analysis Tool + run: | + composer run-script phpstan + + coverage: + name: Coverage + runs-on: ubuntu-latest + services: + search-server: + image: opensearchproject/opensearch:2.2.1 + ports: + - 9200:9200 + env: + discovery.type: single-node + plugins.security.disabled: 'true' + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Use PHP 8.1 + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + extensions: yaml, zip, curl, pcov + env: + COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies + run: | + composer install --prefer-dist + + - name: Wait for Search server + run: php ./.github/wait_for_es.php + + - name: PHPUnit + run: | + composer run-script phpunit + env: + OPENSEARCH_URL: 'http://localhost:9200' + + - uses: codecov/codecov-action@v3 + with: + file: ./clover.xml + + unit-test: + name: "Unit Test" runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -15,24 +106,45 @@ jobs: - '8.0' - '8.1' - '8.2' + os: + - ubuntu-latest + - macos-latest + - windows-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Use PHP ${{ matrix.php-version }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: yaml, zip, curl + env: + COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies + run: | + composer install --prefer-dist + + - name: Unit tests + run: | + composer run unit + + integration-test: + name: Tntegration Test + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: os: - ubuntu-latest search-server-image: - docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.0 - - opensearchproject/opensearch:1.0.0 - - opensearchproject/opensearch:1.0.1 - opensearchproject/opensearch:1.1.0 - - opensearchproject/opensearch:1.2.0 - - opensearchproject/opensearch:1.2.1 - - opensearchproject/opensearch:1.2.2 - - opensearchproject/opensearch:1.2.3 - opensearchproject/opensearch:1.2.4 - - opensearchproject/opensearch:1.3.0 - - opensearchproject/opensearch:1.3.1 - - opensearchproject/opensearch:1.3.2 - - opensearchproject/opensearch:1.3.3 - - opensearchproject/opensearch:2.0.0 - - opensearchproject/opensearch:2.0.1 + - opensearchproject/opensearch:1.3.6 + - opensearchproject/opensearch:2.1.0 + - opensearchproject/opensearch:2.2.1 services: search-server: image: ${{ matrix.search-server-image }} @@ -46,10 +158,10 @@ jobs: - name: Checkout uses: actions/checkout@v2 - - name: Use PHP ${{ matrix.php-version }} + - name: Use PHP 8.1 uses: shivammathur/setup-php@v2 with: - php-version: ${{ matrix.php-version }} + php-version: 8.1 extensions: yaml, zip, curl env: COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -58,25 +170,9 @@ jobs: run: | composer install --prefer-dist - - name: PHP CS Fixer - if: matrix.php-version == '8.1' - run: | - composer run-script php-cs - - - name: PHP Static Analysis Tool - if: matrix.php-version == '8.1' - run: | - composer run-script phpstan - - name: Wait for Search server run: php ./.github/wait_for_es.php - - name: Unit tests - run: | - composer run unit - env: - TEST_SUITE: free - - name: Integration tests run: | composer run integration diff --git a/.github/workflows/test_unreleased.yml b/.github/workflows/test_unreleased.yml index 7d8668bcf..43dfb6433 100644 --- a/.github/workflows/test_unreleased.yml +++ b/.github/workflows/test_unreleased.yml @@ -53,14 +53,6 @@ jobs: run: | composer install --prefer-dist - - name: PHP CS Fixer - run: | - composer run-script php-cs - - - name: PHP Static Analysis Tool - run: | - composer run-script phpstan - - name: Wait for Search server run: php ./.github/wait_for_es.php diff --git a/.gitignore b/.gitignore index f09d6318e..493411a58 100755 --- a/.gitignore +++ b/.gitignore @@ -35,7 +35,8 @@ util/doctum.phar .phpunit.result.cache # Code coverage -build +/clover.xml + # Do not ignore Doctum docs built files !/docs/build diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ca2628fa..aa823ddc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ### Changed +- Added Windows and macOS jobs to CI +- Added Coverage reporting to Codecov + ### Deprecated ### Removed diff --git a/README.md b/README.md index b9783e2cc..62c2c163c 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ - [Welcome!](#welcome) - [Project Resources](#project-resources) - [Code of Conduct](#code-of-conduct) +- [Sample code](#sample-code) - [Compatibility with OpenSearch](#compatibility-with-opensearch) - [License](#license) - [Copyright](#copyright) @@ -14,7 +15,7 @@ ## Project Resources * [Project Website](https://opensearch.org/) -* [User Guide](https://github.com/opensearch-project/opensearch-php/blob/main/USER_GUIDE.md) +* [User Guide And Sample Code](https://github.com/opensearch-project/opensearch-php/blob/main/USER_GUIDE.md) * [Developer Guide](https://github.com/opensearch-project/opensearch-php/blob/main/DEVELOPER_GUIDE.md) * [Downloads](https://opensearch.org/downloads.html). * [Documentation](https://opensearch.org/docs/latest/) @@ -30,6 +31,10 @@ This project has adopted the [Amazon Open Source Code of Conduct](https://github.com/opensearch-project/opensearch-php/blob/main/CODE_OF_CONDUCT.md). For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq), or contact [opensource-codeofconduct@amazon.com](mailto:opensource-codeofconduct@amazon.com) with any additional questions or comments. +## Sample code + +See [Sample Code](https://github.com/opensearch-project/opensearch-php/blob/main/USER_GUIDE.md). + ## Compatibility with OpenSearch See [Compatibility](COMPATIBILITY.md). diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 8bca1091b..4f4649ecd 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -7,84 +7,291 @@ Install this client using Composer into your project `composer req opensearch-pr ## Example usage ```php -setHosts(['https://localhost:9200']) - ->setBasicAuthentication('admin', 'admin') // For testing only. Don't store credentials in code. - // or, if using AWS SigV4 authentication: - ->setSigV4Region('us-east-2') - ->setSigV4CredentialProvider(true) - ->setSSLVerification(false) // For testing only. Use certificate for validation - ->build(); - -$indexName = 'test-index-name'; - -// Print OpenSearch version information on console. -var_dump($client->info()); - -// Create an index with non-default settings. -$client->indices()->create([ - 'index' => $indexName, - 'body' => [ - 'settings' => [ - 'index' => [ - 'number_of_shards' => 4 +define('INDEX_NAME', 'test_elastic_index_name2'); + +class MyOpenSearchClass +{ + + protected ?\OpenSearch\Client $client; + protected $existingID = 1668504743; + protected $deleteID = 1668504743; + protected $bulkIds = []; + + + public function __construct() + { + //simple Setup + $this->client = OpenSearch\ClientBuilder::fromConfig([ + 'hosts' => [ + 'https://localhost:9200' + ], + 'retries' => 2, + 'handler' => OpenSearch\ClientBuilder::multiHandler() + ]); + + // OR via Builder + // $this->client = (new \OpenSearch\ClientBuilder()) + // ->setHosts(['https://localhost:9200']) + // ->setBasicAuthentication('admin', 'admin') // For testing only. Don't store credentials in code. + // // or, if using AWS SigV4 authentication: + // ->setSigV4Region('us-east-2') + // ->setSigV4CredentialProvider(true) + // ->setSSLVerification(false) // For testing only. Use certificate for validation + // ->build(); + } + + + // Create an index with non-default settings. + public function createIndex() + { + $this->client->indices()->create([ + 'index' => INDEX_NAME, + 'body' => [ + 'settings' => [ + 'index' => [ + 'number_of_shards' => 4 + ] + ] ] - ] - ] -]); - -// Create a document passing the id -$client->create([ - 'index' => $indexName, - 'id' => 1, - 'body' => [ - 'title' => 'Moneyball', - 'director' => 'Bennett Miller', - 'year' => 2011 - ] -]); - -// Create a document without passing the id (will be generated automatically) -$client->create([ - 'index' => $indexName, - 'body' => [ - 'title' => 'Remember the Titans', - 'director' => 'Boaz Yakin', - 'year' => 2000 - ] -]); - -// Search for it -var_dump( - $client->search([ - 'index' => $indexName, - 'body' => [ - 'size' => 5, - 'query' => [ - 'multi_match' => [ - 'query' => 'miller', - 'fields' => ['title^2', 'director'] + ]); + } + + public function info() + { + // Print OpenSearch version information on console. + var_dump($this->client->info()); + } + + // Create a document + public function create() + { + $time = time(); + $this->existingID = $time; + $this->deleteID = $time . '_uniq'; + + + // Create a document passing the id + $this->client->create([ + 'id' => $time, + 'index' => INDEX_NAME, + 'body' => $this->getData($time) + ]); + + // Create a document passing the id + $this->client->create([ + 'id' => $this->deleteID, + 'index' => INDEX_NAME, + 'body' => $this->getData($time) + ]); + + // Create a document without passing the id (will be generated automatically) + $this->client->create([ + 'index' => INDEX_NAME, + 'body' => $this->getData($time + 1) + ]); + + //This should throw an exception because ID already exists + // $this->client->create([ + // 'id' => $this->existingID, + // 'index' => INDEX_NAME, + // 'body' => $this->getData($this->existingID) + // ]); + } + + public function update() + { + $this->client->update([ + 'id' => $this->existingID, + 'index' => INDEX_NAME, + 'body' => [ + //data must be wrapped in 'doc' object + 'doc' => ['name' => 'updated'] + ] + ]); + } + + public function bulk() + { + $bulkData = []; + $time = time(); + for ($i = 0; $i < 20; $i++) { + $id = ($time + $i) . rand(10, 200); + $bulkData[] = [ + 'index' => [ + '_index' => INDEX_NAME, + '_id' => $id, + ] + ]; + $this->bulkIds[] = $id; + $bulkData[] = $this->getData($time + $i); + } + //will not throw exception! check $response for error + $response = $this->client->bulk([ + //default index + 'index' => INDEX_NAME, + 'body' => $bulkData + ]); + + //give elastic a little time to create before update + sleep(2); + + // bulk update + for ($i = 0; $i < 15; $i++) { + $bulkData[] = [ + 'update' => [ + '_index' => INDEX_NAME, + '_id' => $this->bulkIds[$i], + ] + ]; + $bulkData[] = [ + 'doc' => [ + 'name' => 'bulk updated' + ] + ]; + } + + //will not throw exception! check $response for error + $response = $this->client->bulk([ + //default index + 'index' => INDEX_NAME, + 'body' => $bulkData + ]); + } + public function deleteByQuery(string $query) + { + if ($query == '') { + return; + } + $this->client->deleteByQuery([ + 'index' => INDEX_NAME, + 'q' => $query + ]); + } + + // Delete a single document + public function deleteByID() + { + $this->client->delete([ + 'id' => $this->deleteID, + 'index' => INDEX_NAME, + ]); + } + + public function search() + { + $docs = $this->client->search([ + //index to search in or '_all' for all indices + 'index' => INDEX_NAME, + 'size' => 1000, + 'body' => [ + 'query' => [ + 'prefix' => [ + 'name' => 'wrecking' + ] ] ] - ] - ]) -); - -// Delete a single document -$client->delete([ - 'index' => $indexName, - 'id' => 1, -]); - + ]); + var_dump($docs['hits']['total']['value'] > 0); + + // Search for it + $docs = $this->client->search([ + 'index' => INDEX_NAME, + 'body' => [ + 'size' => 5, + 'query' => [ + 'multi_match' => [ + 'query' => 'miller', + 'fields' => ['title^2', 'director'] + ] + ] + ] + ]); + var_dump($docs['hits']['total']['value'] > 0); + } + + public function getMultipleDocsByIDs() + { + $docs = $this->client->search([ + //index to search in or '_all' for all indices + 'index' => INDEX_NAME, + 'body' => [ + 'query' => [ + 'ids' => [ + 'values' => $this->bulkIds + ] + ] + ] + ]); + var_dump($docs['hits']['total']['value'] > 0); + } + + public function getOneByID() + { + $docs = $this->client->search([ + //index to search in or '_all' for all indices + 'index' => INDEX_NAME, + 'size' => 1, + 'body' => [ + 'query' => [ + 'bool' => [ + 'filter' => [ + 'term' => [ + '_id' => $this->existingID + ] + ] + ] + ] + ] + ]); + var_dump($docs['hits']['total']['value'] > 0); + } + + // Delete index + public function deleteByIndex() + { + $this->client->indices()->delete([ + 'index' => INDEX_NAME + ]); + } + + //simple data to index + public function getData($time = -1) + { + if ($time == -1) { + $time = time(); + } + return [ + 'name' => date('c', $time) . " - i came in like a wrecking ball", + 'time' => $time, + 'date' => date('c', $time) + ]; + } +} + +try { + + $e = new MyOpenSearchClass(); + $e->info(); + $e->createIndex(); + $e->create(); + //give elastic a little time to create before update + sleep(2); + $e->update(); + $e->bulk(); + $e->getOneByID(); + $e->getMultipleDocsByIDs(); + $e->search(); + $e->deleteByQuery(''); + $e->deleteByID(); + $e->deleteByIndex(); +} catch (\Throwable $th) { + echo 'uncaught error ' . $th->getMessage() . "\n"; +} -// Delete index -$client->indices()->delete([ - 'index' => $indexName -]); ``` ## ClientBuilder diff --git a/composer.json b/composer.json index 7a54d707f..2a7508923 100644 --- a/composer.json +++ b/composer.json @@ -55,10 +55,13 @@ "phpstan analyse --no-progress" ], "unit": [ - "phpunit" + "phpunit --exclude-group Integration" ], "integration": [ - "phpunit -c phpunit-integration-tests.xml" + "phpunit --group Integration" + ], + "phpunit": [ + "phpunit" ] } } diff --git a/phpunit-integration-tests.xml b/phpunit-integration-tests.xml deleted file mode 100644 index 2c83e3ccc..000000000 --- a/phpunit-integration-tests.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - src - - - - - tests - - - - - Integration - - - diff --git a/phpunit.xml.dist b/phpunit.xml.dist index b53250964..86ac7d340 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,18 +1,18 @@ - - src - + + ./src/ + + + + + + tests - - - Integration - -