├── .gitignore ├── .php_cs ├── .phpstorm.meta.php ├── .travis.yml ├── README.md ├── composer.json ├── phpunit.xml ├── src └── CoroutineHandler.php └── tests ├── .env ├── .env.example ├── Cases ├── AbstractTestCase.php ├── DocumentTest.php ├── ElasticsearchTest.php ├── ExampleTest.php └── IndicesTest.php ├── Testing └── Constants.php ├── bootstrap.php ├── ci.ini ├── co-phpunit ├── config ├── beans │ ├── base.php │ └── log.php ├── define.php ├── properties │ ├── app.php │ └── es_docs.php └── server.php ├── download_and_run_es.sh ├── init.php ├── runtime └── .gitkeep └── swoole.install.sh /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | composer.lock 3 | *.cache 4 | *.log -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | setRiskyAllowed(true) 14 | ->setRules([ 15 | '@PSR2' => true, 16 | 'header_comment' => [ 17 | 'commentType' => 'PHPDoc', 18 | 'header' => $header, 19 | 'separate' => 'none' 20 | ], 21 | 'array_syntax' => [ 22 | 'syntax' => 'short' 23 | ], 24 | 'single_quote' => true, 25 | 'class_attributes_separation' => true, 26 | 'no_unused_imports' => true, 27 | 'standardize_not_equals' => true, 28 | ]) 29 | ->setFinder( 30 | PhpCsFixer\Finder::create() 31 | ->exclude('public') 32 | ->exclude('resources') 33 | ->exclude('config') 34 | ->exclude('runtime') 35 | ->exclude('vendor') 36 | ->in(__DIR__) 37 | ) 38 | ->setUsingCache(false); 39 | -------------------------------------------------------------------------------- /.phpstorm.meta.php: -------------------------------------------------------------------------------- 1 | \Swoft\Defer\Defer::class, 14 | ]; 15 | override(\bean(0), map($map)); 16 | override(\Swoft\App::getBean(0), map($map)); 17 | override(\Swoft\Core\ApplicationContext::getBean(0), map($map)); 18 | override(\Swoft\Bean\BeanFactory::getBean(0), map($map)); 19 | 20 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | dist: trusty 4 | sudo: true 5 | 6 | matrix: 7 | fast_finish: true 8 | include: 9 | - php: 7.1 10 | env: ES_VERSION="6.0" 11 | - php: 7.1 12 | env: ES_VERSION="6.x" 13 | 14 | - php: 7.2 15 | env: ES_VERSION="6.0" 16 | 17 | - php: nightly 18 | env: ES_VERSION="6.0" 19 | allow_failures: 20 | - php: nightly 21 | - env: ES_VERSION="6.x" 22 | 23 | git: 24 | depth: 1 25 | 26 | env: 27 | global: 28 | - ES_TEST_HOST=http://localhost:9200 29 | - JAVA_HOME="/usr/lib/jvm/java-8-oracle/jre" 30 | 31 | services: 32 | - redis-server 33 | 34 | before_install: 35 | - export PHP_MAJOR="$(`phpenv which php` -r 'echo phpversion();' | cut -d '.' -f 1)" 36 | - export PHP_MINOR="$(`phpenv which php` -r 'echo phpversion();' | cut -d '.' -f 2)" 37 | - echo $PHP_MAJOR 38 | - echo $PHP_MINOR 39 | 40 | install: 41 | - cd $TRAVIS_BUILD_DIR 42 | # 更新ES 43 | - sudo update-java-alternatives -s java-8-oracle 44 | - bash tests/download_and_run_es.sh 45 | # 更新扩展 46 | - wget https://github.com/redis/hiredis/archive/v0.13.3.tar.gz -O hiredis.tar.gz && mkdir -p hiredis && tar -xf hiredis.tar.gz -C hiredis --strip-components=1 && cd hiredis && sudo make -j$(nproc) && sudo make install && sudo ldconfig && cd .. 47 | - bash tests/swoole.install.sh 48 | - phpenv config-rm xdebug.ini 49 | - phpenv config-add tests/ci.ini 50 | - cp -rf $TRAVIS_BUILD_DIR/tests/.env.example $TRAVIS_BUILD_DIR/tests/.env 51 | # 安装项目 52 | - composer self-update 53 | - cd $TRAVIS_BUILD_DIR 54 | - composer install --prefer-dist --optimize-autoloader 55 | - php tests/init.php 56 | - sleep 5 57 | 58 | script: 59 | - cd $TRAVIS_BUILD_DIR 60 | - composer test -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # swoft-elasticsearch 2 | 3 | [![Build Status](https://travis-ci.org/limingxinleo/swoft-elasticsearch.svg?branch=master)](https://travis-ci.org/limingxinleo/swoft-elasticsearch) 4 | 5 | ## 安装 6 | ~~~ 7 | composer require limingxinleo/swoft-elasticsearch 8 | ~~~ 9 | 10 | ## 使用 11 | 12 | 使用方法与官方ES客户端一致 13 | 14 | ~~~php 15 | 2 22 | ]); 23 | 24 | $client = ClientBuilder::create() 25 | ->setHosts(['127.0.0.1:9200']) 26 | ->setHandler($handler) 27 | ->build(); 28 | 29 | go(function() use ($client){ 30 | print_r($client->info()); 31 | }); 32 | ~~~ -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "limingxinleo/swoft-elasticsearch", 3 | "type": "library", 4 | "license": "MIT", 5 | "keywords": [ 6 | "php", 7 | "swoole", 8 | "swoft", 9 | "db", 10 | "model" 11 | ], 12 | "description": "基于Swoft的Elasticsearch客户端组件", 13 | "authors": [ 14 | { 15 | "name": "李铭昕", 16 | "email": "limingxin@swoft.org" 17 | } 18 | ], 19 | "autoload": { 20 | "psr-4": { 21 | "Swoftx\\Elasticsearch\\": "src/" 22 | } 23 | }, 24 | "autoload-dev": { 25 | "psr-4": { 26 | "SwoftTest\\": "tests" 27 | } 28 | }, 29 | "require": { 30 | "php": ">=7.0", 31 | "elasticsearch/elasticsearch": "^6.0" 32 | }, 33 | "require-dev": { 34 | "swoft/swoole-ide-helper": "dev-master", 35 | "phpunit/phpunit": "^7.0" 36 | }, 37 | "scripts": { 38 | "cs-fix": "php-cs-fixer fix $1", 39 | "test": "./tests/co-phpunit -c phpunit.xml --colors=always" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | ./tests/ 14 | 15 | -------------------------------------------------------------------------------- /src/CoroutineHandler.php: -------------------------------------------------------------------------------- 1 | options = $options; 31 | } 32 | 33 | public function __invoke($request) 34 | { 35 | $method = $request['http_method'] ?? 'GET'; 36 | $scheme = $request['scheme'] ?? 'http'; 37 | $ssl = $scheme === 'https'; 38 | $uri = $request['uri'] ?? '/'; 39 | $body = $request['body'] ?? ''; 40 | $effectiveUrl = Core::url($request); 41 | $params = parse_url($effectiveUrl); 42 | $host = $params['host']; 43 | if (! isset($params['port'])) { 44 | $params['port'] = $ssl ? 443 : 80; 45 | } 46 | $port = $params['port']; 47 | $path = $params['path'] ?? '/'; 48 | if (isset($params['query']) && is_string($params['query'])) { 49 | $path .= '?' . $params['query']; 50 | } 51 | 52 | $client = new Client($host, $port, $ssl); 53 | $client->setMethod($method); 54 | $client->setData($body); 55 | 56 | // 初始化Headers 57 | $this->initHeaders($client, $request); 58 | $settings = $this->getSettings($this->options); 59 | 60 | // 设置客户端参数 61 | if (! empty($settings)) { 62 | $client->set($settings); 63 | } 64 | 65 | $btime = microtime(true); 66 | $client->execute($path); 67 | 68 | $ex = $this->checkStatusCode($client, $request); 69 | if ($ex !== true) { 70 | return [ 71 | 'status' => null, 72 | 'reason' => null, 73 | 'headers' => [], 74 | 'error' => $ex, 75 | ]; 76 | } 77 | 78 | return $this->getResponse($client, $btime, $effectiveUrl); 79 | } 80 | 81 | protected function getSettings($options): array 82 | { 83 | $settings = []; 84 | if (isset($options['delay'])) { 85 | Coroutine::sleep((float) $options['delay'] / 1000); 86 | } 87 | 88 | // 超时 89 | if (isset($options['timeout']) && $options['timeout'] > 0) { 90 | $settings['timeout'] = $options['timeout']; 91 | } 92 | 93 | return $settings; 94 | } 95 | 96 | protected function initHeaders(Client $client, $request) 97 | { 98 | $headers = []; 99 | foreach ($request['headers'] ?? [] as $name => $value) { 100 | $headers[$name] = implode(',', $value); 101 | } 102 | 103 | $clientConfig = $request['client']['curl'] ?? []; 104 | if (isset($clientConfig[CURLOPT_USERPWD])) { 105 | $userInfo = $clientConfig[CURLOPT_USERPWD]; 106 | $headers['Authorization'] = sprintf('Basic %s', base64_encode($userInfo)); 107 | } 108 | 109 | // TODO: 不知道为啥,这个扔进来就400 110 | unset($headers['Content-Length']); 111 | $client->setHeaders($headers); 112 | } 113 | 114 | protected function getResponse(Client $client, $btime, $effectiveUrl) 115 | { 116 | return new CompletedFutureArray([ 117 | 'transfer_stats' => [ 118 | 'total_time' => microtime(true) - $btime, 119 | ], 120 | 'effective_url' => $effectiveUrl, 121 | 'headers' => isset($client->headers) ? $client->headers : [], 122 | 'status' => $client->statusCode, 123 | 'body' => $this->getStream($client->body), 124 | ]); 125 | } 126 | 127 | protected function checkStatusCode($client, $request) 128 | { 129 | $statusCode = $client->statusCode; 130 | $errCode = $client->errCode; 131 | 132 | if ($statusCode === -1) { 133 | return new RingException(sprintf('Connection timed out errCode=%s', $errCode)); 134 | } 135 | if ($statusCode === -2) { 136 | return new RingException('Request timed out'); 137 | } 138 | 139 | return true; 140 | } 141 | 142 | protected function getStream(string $resource) 143 | { 144 | $stream = fopen('php://temp', 'r+'); 145 | if ($resource !== '') { 146 | fwrite($stream, $resource); 147 | fseek($stream, 0); 148 | } 149 | 150 | return $stream; 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /tests/.env: -------------------------------------------------------------------------------- 1 | # the pool of master nodes pool 2 | DB_NAME=default.master 3 | DB_URI=127.0.0.1:3306/test?user=root&password=&charset=utf8 4 | DB_MIN_ACTIVE=1 5 | DB_MAX_ACTIVE=60 6 | DB_MAX_WAIT=10 7 | DB_MAX_WAIT_TIME=10 8 | DB_MAX_IDLE_TIME=60 9 | DB_TIMEOUT=2 10 | DB_USE_PROVIDER=false 11 | DB_BALANCER=random 12 | DB_PROVIDER=consul2 13 | 14 | # the pool of slave nodes pool 15 | DB_SLAVE_NAME=default.slave 16 | DB_SLAVE_URI=127.0.0.1:3306/test?user=root&password=&charset=utf8 17 | DB_SLAVE_MIN_ACTIVE=1 18 | DB_SLAVE_MAX_ACTIVE=60 19 | DB_SLAVE_MAX_WAIT=10 20 | DB_SLAVE_MAX_WAIT_TIME=10 21 | DB_SLAVE_MAX_IDLE_TIME=60 22 | DB_SLAVE_TIMEOUT=3 23 | DB_SLAVE_USE_PROVIDER=false 24 | DB_SLAVE_BALANCER=random 25 | DB_SLAVE_PROVIDER=consul2 26 | 27 | # Redis 28 | REDIS_NAME=redis 29 | REDIS_DB=0 30 | REDIS_PREFIX= 31 | REDIS_URI=127.0.0.1:6379 32 | REDIS_MIN_ACTIVE=5 33 | REDIS_MAX_ACTIVE=10 34 | REDIS_MAX_WAIT=20 35 | REDIS_MAX_WAIT_TIME=3 36 | REDIS_MAX_IDLE_TIME=60 37 | REDIS_TIMEOUT=3 38 | REDIS_SERIALIZE=1 39 | 40 | ELASTICSEARCH_CLIENT_TIMEOUT=5 41 | -------------------------------------------------------------------------------- /tests/.env.example: -------------------------------------------------------------------------------- 1 | # the pool of master nodes pool 2 | DB_NAME=default.master 3 | DB_URI=127.0.0.1:3306/test?user=root&password=&charset=utf8 4 | DB_MIN_ACTIVE=1 5 | DB_MAX_ACTIVE=60 6 | DB_MAX_WAIT=10 7 | DB_MAX_WAIT_TIME=10 8 | DB_MAX_IDLE_TIME=60 9 | DB_TIMEOUT=2 10 | DB_USE_PROVIDER=false 11 | DB_BALANCER=random 12 | DB_PROVIDER=consul2 13 | 14 | # the pool of slave nodes pool 15 | DB_SLAVE_NAME=default.slave 16 | DB_SLAVE_URI=127.0.0.1:3306/test?user=root&password=&charset=utf8 17 | DB_SLAVE_MIN_ACTIVE=1 18 | DB_SLAVE_MAX_ACTIVE=60 19 | DB_SLAVE_MAX_WAIT=10 20 | DB_SLAVE_MAX_WAIT_TIME=10 21 | DB_SLAVE_MAX_IDLE_TIME=60 22 | DB_SLAVE_TIMEOUT=3 23 | DB_SLAVE_USE_PROVIDER=false 24 | DB_SLAVE_BALANCER=random 25 | DB_SLAVE_PROVIDER=consul2 26 | 27 | # Redis 28 | REDIS_NAME=redis 29 | REDIS_DB=0 30 | REDIS_PREFIX= 31 | REDIS_URI=127.0.0.1:6379 32 | REDIS_MIN_ACTIVE=5 33 | REDIS_MAX_ACTIVE=10 34 | REDIS_MAX_WAIT=20 35 | REDIS_MAX_WAIT_TIME=3 36 | REDIS_MAX_IDLE_TIME=60 37 | REDIS_TIMEOUT=3 38 | REDIS_SERIALIZE=1 39 | 40 | ELASTICSEARCH_CLIENT_TIMEOUT=2 41 | -------------------------------------------------------------------------------- /tests/Cases/AbstractTestCase.php: -------------------------------------------------------------------------------- 1 | setHosts(['127.0.0.1:9200']); 33 | if (extension_loaded('swoole') && Coroutine::getuid() > 0) { 34 | $handler = new CoroutineHandler([ 35 | 'timeout' => 2 36 | ]); 37 | 38 | $builder->setHandler($handler); 39 | } 40 | return $builder->build(); 41 | } 42 | 43 | protected function tearDown() 44 | { 45 | parent::tearDown(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/Cases/DocumentTest.php: -------------------------------------------------------------------------------- 1 | Constants::INDEX, 20 | 'type' => Constants::TYPE, 21 | 'id' => 0, 22 | ]; 23 | $expect = $this->getClient()->get($params); 24 | $actual = $this->getClient()->get($params); 25 | $this->assertEquals($expect, $actual); 26 | } 27 | 28 | public function testAddDocument() 29 | { 30 | try { 31 | $this->getClient()->delete([ 32 | 'index' => Constants::INDEX, 33 | 'type' => Constants::TYPE, 34 | 'id' => 999 35 | ]); 36 | } catch (\Exception $ex) { 37 | } 38 | 39 | $body = [ 40 | 'name' => 'Mr.999', 41 | 'age' => 99, 42 | 'birthday' => '1990-01-01', 43 | 'book' => [ 44 | 'author' => 'limx', 45 | 'name' => '长寿的秘诀', 46 | 'publish' => '2018-01-01', 47 | 'desc' => '多睡觉' 48 | ], 49 | 'location' => [ 50 | 'lat' => 0, 51 | 'lon' => 0, 52 | ], 53 | 'randnum' => 999 54 | ]; 55 | 56 | $params = [ 57 | 'index' => Constants::INDEX, 58 | 'type' => Constants::TYPE, 59 | 'id' => 999, 60 | 'body' => $body, 61 | ]; 62 | 63 | $expect = $this->getClient()->index($params); 64 | $this->assertEquals('created', $expect['result']); 65 | $version = $expect['_version']; 66 | 67 | $actual = $this->getClient()->index($params); 68 | 69 | $this->assertEquals('updated', $actual['result']); 70 | $this->assertEquals($version + 1, $actual['_version']); 71 | } 72 | 73 | public function testCurdDocument() 74 | { 75 | $body = [ 76 | 'name' => 'Mr.998', 77 | 'age' => 99, 78 | 'birthday' => '1990-01-01', 79 | 'book' => [ 80 | 'author' => 'limx', 81 | 'name' => '长寿的秘诀', 82 | 'publish' => '2018-01-01', 83 | 'desc' => '多睡觉' 84 | ], 85 | 'location' => [ 86 | 'lat' => 0, 87 | 'lon' => 0, 88 | ], 89 | 'randnum' => 998 90 | ]; 91 | $params = [ 92 | 'index' => Constants::INDEX, 93 | 'type' => Constants::TYPE, 94 | 'id' => 998, 95 | 'body' => $body, 96 | ]; 97 | 98 | $this->getClient()->index($params); 99 | 100 | $params = [ 101 | 'index' => Constants::INDEX, 102 | 'type' => Constants::TYPE, 103 | 'id' => 998, 104 | 'body' => [ 105 | 'doc' => [ 106 | 'book' => [ 107 | 'publish' => '2018-01-02', 108 | ], 109 | ], 110 | 'doc_as_upsert' => true, 111 | ], 112 | 'retry_on_conflict' => 5, 113 | ]; 114 | $this->getClient()->update($params); 115 | 116 | $params2 = [ 117 | 'index' => Constants::INDEX, 118 | 'type' => Constants::TYPE, 119 | 'id' => 998, 120 | ]; 121 | $expect = $this->getClient()->get($params2); 122 | 123 | $this->assertEquals('limx', $expect['_source']['book']['author']); 124 | $this->assertEquals('2018-01-02', $expect['_source']['book']['publish']); 125 | 126 | $params['body']['doc']['book']['publish'] = '2018-01-03'; 127 | $this->getClient()->update($params); 128 | $actual = $this->getClient()->get($params2); 129 | 130 | $this->assertEquals($expect['_version'] + 1, $actual['_version']); 131 | $this->assertEquals('limx', $actual['_source']['book']['author']); 132 | $this->assertEquals('2018-01-03', $actual['_source']['book']['publish']); 133 | 134 | // 删除 135 | $res = $this->getClient()->delete($params2); 136 | 137 | $this->assertEquals('deleted', $res['result']); 138 | $this->assertEquals(1, $res['_shards']['successful']); 139 | $this->assertEquals(0, $res['_shards']['failed']); 140 | } 141 | 142 | public function testBoolGeoQuery() 143 | { 144 | $lat = 31.249162; 145 | $lon = 121.487899; 146 | 147 | $params = [ 148 | 'index' => Constants::INDEX, 149 | 'type' => Constants::TYPE, 150 | 'body' => [ 151 | 'query' => [ 152 | 'bool' => [ 153 | 'filter' => [ 154 | 'geo_distance' => [ 155 | 'distance' => '1km', 156 | 'location' => [ 157 | 'lat' => $lat, 158 | 'lon' => $lon 159 | ], 160 | ], 161 | ], 162 | ] 163 | ], 164 | 'from' => 0, 165 | 'size' => 5, 166 | 'sort' => [ 167 | '_geo_distance' => [ 168 | 'location' => [ 169 | 'lat' => $lat, 170 | 'lon' => $lon 171 | ], 172 | 'order' => 'asc', 173 | 'unit' => 'km', 174 | 'mode' => 'min', 175 | ], 176 | ], 177 | ], 178 | ]; 179 | 180 | $expect = $this->getClient()->search($params); 181 | $this->assertEquals(3, $expect['hits']['total']); 182 | 183 | $actual = $this->getClient()->search($params); 184 | $this->assertEquals(3, $actual['hits']['total']); 185 | $this->assertEquals($expect['hits'], $actual['hits']); 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /tests/Cases/ElasticsearchTest.php: -------------------------------------------------------------------------------- 1 | getClient()->info(); 17 | $actual = $this->getClient()->info(); 18 | $this->assertEquals($expect, $actual); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/Cases/ExampleTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/Cases/IndicesTest.php: -------------------------------------------------------------------------------- 1 | getClient()->indices(); 19 | $expect = $indexes->exists(['index' => Constants::INDEX]); 20 | $indexes = $this->getClient()->indices(); 21 | $actual = $indexes->exists(['index' => Constants::INDEX]); 22 | $this->assertEquals($expect, $actual); 23 | } 24 | 25 | public function testIndicesInfo() 26 | { 27 | $indexes = $this->getClient()->indices(); 28 | $expect = $indexes->get(['index' => Constants::INDEX]); 29 | $indexes = $this->getClient()->indices(); 30 | $actual = $indexes->get(['index' => Constants::INDEX]); 31 | $this->assertEquals($expect, $actual); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/Testing/Constants.php: -------------------------------------------------------------------------------- 1 | self::INDEX, 20 | 'type' => self::TYPE, 21 | 'body' => [ 22 | 'properties' => [ 23 | 'id' => ['type' => 'long'], 24 | 'name' => ['type' => 'text'], 25 | 'book' => [ 26 | 'type' => 'object', 27 | 'properties' => [ 28 | 'author' => ['type' => 'text'], 29 | 'name' => ['type' => 'text'], 30 | 'publish' => ['type' => 'date'], 31 | 'desc' => [ 32 | 'type' => 'text', 33 | ], 34 | ], 35 | ], 36 | 'age' => ['type' => 'short'], 37 | 'birthday' => ['type' => 'date'], 38 | 'location' => ['type' => 'geo_point'], 39 | 'randnum' => ['type' => 'long'], 40 | ], 41 | ], 42 | ]; 43 | } 44 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | ')) { 5 | fwrite( 6 | STDERR, 7 | sprintf( 8 | 'This version of PHPUnit is supported on PHP 7.1 and PHP 7.2.' . PHP_EOL . 9 | 'You are using PHP %s (%s).' . PHP_EOL, 10 | PHP_VERSION, 11 | PHP_BINARY 12 | ) 13 | ); 14 | 15 | die(1); 16 | } 17 | 18 | if (!ini_get('date.timezone')) { 19 | ini_set('date.timezone', 'UTC'); 20 | } 21 | 22 | foreach (array(__DIR__ . '/../../autoload.php', __DIR__ . '/../vendor/autoload.php', __DIR__ . '/vendor/autoload.php') as $file) { 23 | if (file_exists($file)) { 24 | define('PHPUNIT_COMPOSER_INSTALL', $file); 25 | 26 | break; 27 | } 28 | } 29 | 30 | unset($file); 31 | 32 | if (!defined('PHPUNIT_COMPOSER_INSTALL')) { 33 | fwrite( 34 | STDERR, 35 | 'You need to set up the project dependencies using Composer:' . PHP_EOL . PHP_EOL . 36 | ' composer install' . PHP_EOL . PHP_EOL . 37 | 'You can learn all about Composer on https://getcomposer.org/.' . PHP_EOL 38 | ); 39 | 40 | die(1); 41 | } 42 | 43 | $options = getopt('', array('prepend:')); 44 | 45 | if (isset($options['prepend'])) { 46 | require $options['prepend']; 47 | } 48 | 49 | unset($options); 50 | 51 | require PHPUNIT_COMPOSER_INSTALL; 52 | 53 | PHPUnit\TextUI\Command::main(false); 54 | }); 55 | -------------------------------------------------------------------------------- /tests/config/beans/base.php: -------------------------------------------------------------------------------- 1 | [ 12 | 'class' => \Swoft\Event\EventManager::class, 13 | ], 14 | ]; 15 | -------------------------------------------------------------------------------- /tests/config/beans/log.php: -------------------------------------------------------------------------------- 1 | [ 12 | 'class' => \Swoft\Log\FileHandler::class, 13 | 'logFile' => '@runtime/logs/notice.log', 14 | 'formatter' => '${lineFormatter}', 15 | 'levels' => [ 16 | \Swoft\Log\Logger::NOTICE, 17 | \Swoft\Log\Logger::INFO, 18 | \Swoft\Log\Logger::DEBUG, 19 | \Swoft\Log\Logger::TRACE, 20 | ] 21 | ], 22 | 'applicationHandler' => [ 23 | 'class' => \Swoft\Log\FileHandler::class, 24 | 'logFile' => '@runtime/logs/error.log', 25 | 'formatter' => '${lineFormatter}', 26 | 'levels' => [ 27 | \Swoft\Log\Logger::ERROR, 28 | \Swoft\Log\Logger::WARNING 29 | ] 30 | ], 31 | 'logger' => [ 32 | 'class' => \Swoft\Log\Logger::class, 33 | 'name' => APP_NAME, 34 | 'flushInterval' => 100, 35 | 'flushRequest' => true, 36 | 'handlers' => [ 37 | '${noticeHandler}', 38 | '${applicationHandler}' 39 | ] 40 | ], 41 | ]; 42 | -------------------------------------------------------------------------------- /tests/config/define.php: -------------------------------------------------------------------------------- 1 | BASE_PATH, 24 | '@app' => '@root/app', 25 | '@res' => '@root/resources', 26 | '@runtime' => '@root/runtime', 27 | '@configs' => '@root/config', 28 | '@resources' => '@root/resources', 29 | '@beans' => '@configs/beans', 30 | '@properties' => '@configs/properties', 31 | '@console' => '@beans/console.php', 32 | ]; 33 | App::setAliases($aliases); 34 | -------------------------------------------------------------------------------- /tests/config/properties/app.php: -------------------------------------------------------------------------------- 1 | '1.0', 13 | 'autoInitBean' => true, 14 | 'beanScan' => [], 15 | 'docs' => require 'es_docs.php', 16 | 'components' => [ 17 | 'custom' => [ 18 | 'Swoftx\\Elasticsearch' => BASE_PATH . '/../src' 19 | ] 20 | ], 21 | ]; 22 | -------------------------------------------------------------------------------- /tests/config/properties/es_docs.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | return [ 10 | [ 11 | 'id' => 0, 12 | 'name' => 'limx', 13 | 'age' => 27, 14 | 'birthday' => '1991-01-23', 15 | 'book' => [ 16 | 'author' => 'limx', 17 | 'name' => '14天放弃PHP', 18 | 'publish' => '2017-01-01', 19 | 'desc' => '14天学会PHP后,你就会放弃它了' 20 | ], 21 | 'location' => [ 22 | 'lat' => 31.249162, 23 | 'lon' => 121.487899, 24 | ], 25 | 'randnum' => 100 26 | ], 27 | [ 28 | 'id' => 1, 29 | 'name' => 'Agnes', 30 | 'age' => 27, 31 | 'birthday' => '1991-05-21', 32 | 'book' => [ 33 | 'author' => 'Agnes', 34 | 'name' => '30天精通java', 35 | 'publish' => '2017-01-02', 36 | 'desc' => '30天精通java的基本语法,哈哈哈' 37 | ], 38 | 'location' => [ 39 | 'lat' => 31.249160, 40 | 'lon' => 121.487897, 41 | ], 42 | 'randnum' => 201 43 | ], 44 | [ 45 | 'id' => 2, 46 | 'name' => '李铭昕', 47 | 'age' => 28, 48 | 'birthday' => '1990-08-08', 49 | 'book' => [ 50 | 'author' => 'limx', 51 | 'name' => '5天学会GO', 52 | 'publish' => '2017-02-02', 53 | 'desc' => '5天学会GO,你就发现也不过尔尔' 54 | ], 55 | 'location' => [ 56 | 'lat' => 30.249160, 57 | 'lon' => 121.487897, 58 | ], 59 | 'randnum' => 444 60 | ], 61 | [ 62 | 'id' => 3, 63 | 'name' => '李大神', 64 | 'age' => 28, 65 | 'birthday' => '1990-08-08', 66 | 'book' => [ 67 | 'author' => 'limx', 68 | 'name' => '1天学会GO', 69 | 'publish' => '2017-02-02', 70 | 'desc' => '1天学会GO,你就发现Go的牛逼之处' 71 | ], 72 | 'location' => [ 73 | 'lat' => 31.249162, 74 | 'lon' => 121.487900, 75 | ], 76 | 'randnum' => 666 77 | ], 78 | ]; -------------------------------------------------------------------------------- /tests/config/server.php: -------------------------------------------------------------------------------- 1 | [ 13 | 'pfile' => env('PFILE', '/tmp/swoft.pid'), 14 | 'pname' => env('PNAME', 'php-swoft'), 15 | 'tcpable' => env('TCPABLE', true), 16 | 'cronable' => env('CRONABLE', false), 17 | 'autoReload' => env('AUTO_RELOAD', true), 18 | ], 19 | 'tcp' => [ 20 | 'host' => env('TCP_HOST', '0.0.0.0'), 21 | 'port' => env('TCP_PORT', 8099), 22 | 'mode' => env('TCP_MODE', SWOOLE_PROCESS), 23 | 'type' => env('TCP_TYPE', SWOOLE_SOCK_TCP), 24 | 'package_max_length' => env('TCP_PACKAGE_MAX_LENGTH', 2048), 25 | 'open_eof_check' => env('TCP_OPEN_EOF_CHECK', false), 26 | 'open_eof_split' => env('TCP_OPEN_EOF_SPLIT', true), 27 | 'package_eof' => "\r\n", 28 | 'client' => [ 29 | 'package_max_length' => env('TCP_CLIENT_PACKAGE_MAX_LENGTH', 1024 * 1024 * 2), 30 | 'open_eof_check' => env('TCP_CLIENT_OPEN_EOF_CHECK', false), 31 | 'open_eof_split' => env('TCP_CLIENT_OPEN_EOF_SPLIT', true), 32 | 'package_eof' => "\r\n", 33 | ], 34 | ], 35 | 'http' => [ 36 | 'host' => env('HTTP_HOST', '0.0.0.0'), 37 | 'port' => env('HTTP_PORT', 80), 38 | 'mode' => env('HTTP_MODE', SWOOLE_PROCESS), 39 | 'type' => env('HTTP_TYPE', SWOOLE_SOCK_TCP), 40 | ], 41 | 'ws' => [ 42 | // enable handle http request ? 43 | 'enable_http' => env('WS_ENABLE_HTTP', true), 44 | // other settings will extend the 'http' config 45 | // you can define separately to overwrite existing settings 46 | ], 47 | 'crontab' => [ 48 | 'task_count' => env('CRONTAB_TASK_COUNT', 1024), 49 | 'task_queue' => env('CRONTAB_TASK_QUEUE', 2048), 50 | ], 51 | 'setting' => [ 52 | 'worker_num' => env('WORKER_NUM', 1), 53 | 'max_request' => env('MAX_REQUEST', 10000), 54 | 'daemonize' => env('DAEMONIZE', 0), 55 | 'dispatch_mode' => env('DISPATCH_MODE', 2), 56 | 'log_file' => env('LOG_FILE', '@runtime/logs/swoole.log'), 57 | 'task_worker_num' => env('TASK_WORKER_NUM', 1), 58 | 'package_max_length' => env('PACKAGE_MAX_LENGTH', 2048), 59 | 'upload_tmp_dir' => env('UPLOAD_TMP_DIR', '@runtime/uploadfiles'), 60 | 'document_root' => env('DOCUMENT_ROOT', BASE_PATH . '/public'), 61 | 'enable_static_handler' => env('ENABLE_STATIC_HANDLER', true), 62 | 'open_http2_protocol' => env('OPEN_HTTP2_PROTOCOL', false), 63 | 'ssl_cert_file' => env('SSL_CERT_FILE', ''), 64 | 'ssl_key_file' => env('SSL_KEY_FILE', ''), 65 | 'task_ipc_mode' => env('TASK_IPC_MODE', 1), 66 | 'message_queue_key' => env('MESSAGE_QUEUE_KEY', 0x70001001), 67 | 'task_tmpdir' => env('TASK_TMPDIR', '/tmp'), 68 | ], 69 | ]; 70 | -------------------------------------------------------------------------------- /tests/download_and_run_es.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ -z $ES_VERSION ]; then 3 | echo "No ES_VERSION specified"; 4 | exit 1; 5 | fi; 6 | 7 | killall java 2>/dev/null 8 | 9 | which java 10 | java -version 11 | 12 | 13 | echo "Downloading Elasticsearch v${ES_VERSION}-SNAPSHOT..." 14 | 15 | ES_URL=$(curl -sS "https://esvm-props.kibana.rocks/builds" | jq -r ".branches[\"$ES_VERSION\"].zip") 16 | 17 | curl -L -o elasticsearch-latest-SNAPSHOT.zip $ES_URL 18 | unzip "elasticsearch-latest-SNAPSHOT.zip" 19 | 20 | echo "Adding repo to config..." 21 | find . -name "elasticsearch.yml" | while read TXT ; do echo 'repositories.url.allowed_urls: ["http://*"]' >> $TXT ; done 22 | find . -name "elasticsearch.yml" | while read TXT ; do echo 'path.repo: ["/tmp"]' >> $TXT ; done 23 | find . -name "elasticsearch.yml" | while read TXT ; do echo 'node.max_local_storage_nodes: 1' >> $TXT ; done 24 | find . -name "elasticsearch.yml" | while read TXT ; do echo 'cluster.routing.allocation.disk.watermark.low: 0.1%' >> $TXT ; done 25 | find . -name "elasticsearch.yml" | while read TXT ; do echo 'cluster.routing.allocation.disk.watermark.high: 0.1%' >> $TXT ; done 26 | find . -name "elasticsearch.yml" | while read TXT ; do echo 'node.attr.testattr: test' >> $TXT ; done 27 | find . -name "elasticsearch.yml" | while read TXT ; do echo 'script.max_compilations_rate: 2048/1m' >> $TXT ; done 28 | 29 | echo "Starting Elasticsearch v${ES_VERSION}" 30 | 31 | ./elasticsearch-*/bin/elasticsearch -d 32 | 33 | 34 | sleep 3 35 | -------------------------------------------------------------------------------- /tests/init.php: -------------------------------------------------------------------------------- 1 | setHosts(['127.0.0.1:9200'])->build(); 16 | 17 | // 删除已存在的索引 18 | $indices = $client->indices(); 19 | $index = Constants::INDEX; 20 | $type = Constants::TYPE; 21 | $mapping = Constants::MAPPING; 22 | 23 | $params = [ 24 | 'index' => $index, 25 | ]; 26 | 27 | if ($indices->exists($params)) { 28 | $res = $indices->delete($params); 29 | if ($res['acknowledged']) { 30 | echo "删除索引[{$index}]成功" . PHP_EOL; 31 | } 32 | } 33 | 34 | // 创建索引 35 | try { 36 | $res = $indices->create($params); 37 | if ($res['acknowledged']) { 38 | echo "索引[{$index}]创建成功" . PHP_EOL; 39 | } 40 | } catch (\Exception $ex) { 41 | $res = json_decode($ex->getMessage(), true); 42 | echo $res['error']['reason'] . PHP_EOL; 43 | } 44 | 45 | // 创建Mapping 46 | $params = $mapping; 47 | $res = $indices->putMapping($params); 48 | 49 | if ($res['acknowledged']) { 50 | echo 'Mapping 设置成功' . PHP_EOL; 51 | } 52 | 53 | // 导入数据 54 | $docs = require 'config/properties/es_docs.php'; 55 | 56 | foreach ($docs as $id => $doc) { 57 | $param = [ 58 | 'index' => $index, 59 | 'type' => $type, 60 | 'id' => $id, 61 | 'body' => $doc 62 | ]; 63 | 64 | $res = $client->index($param); 65 | } 66 | echo '测试文档导入成功' . PHP_EOL; 67 | -------------------------------------------------------------------------------- /tests/runtime/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aquarmini/swoft-elasticsearch/1918f12056104515efb196d3786853a451fcf827/tests/runtime/.gitkeep -------------------------------------------------------------------------------- /tests/swoole.install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | wget https://github.com/swoole/swoole-src/archive/v4.3.4.tar.gz -O swoole.tar.gz 3 | mkdir -p swoole 4 | tar -xf swoole.tar.gz -C swoole --strip-components=1 5 | rm swoole.tar.gz 6 | cd swoole 7 | phpize 8 | ./configure --enable-async-redis --enable-openssl 9 | make -j$(nproc) 10 | make install 11 | --------------------------------------------------------------------------------