diff --git a/.gitignore b/.gitignore index 22d0d82f8..54527ba06 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ vendor +tags diff --git a/.travis.yml b/.travis.yml index 9473c3205..38ea92490 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,20 @@ php: - 5.5 - 5.6 +before_install: + - sudo apt-get update + - sudo apt-get install libcurl4-openssl-dev libjson0-dev + - wget http://s3.amazonaws.com/influxdb/influxdb_latest_amd64.deb + - sudo useradd influxdb + - sudo dpkg -i influxdb_latest_amd64.deb + - sudo cp ./scripts/influxdb_conf.toml /opt/influxdb/shared/config.toml + - travis_retry sudo service influxdb restart + - sudo service influxdb status + before_script: - composer selfupdate - composer install --prefer-source script: - - vendor/bin/phpspec run + - vendor/bin/phpspec run -n + - vendor/bin/phpunit diff --git a/README.md b/README.md index 6d4a9547d..5fbc30cb3 100644 --- a/README.md +++ b/README.md @@ -3,23 +3,107 @@ * [![Build Status](https://travis-ci.org/corley/influxdb-php-sdk.svg?branch=master)](https://travis-ci.org/corley/influxdb-php-sdk) * [![Dependency Status](https://www.versioneye.com/user/projects/54104e789e1622492d000025/badge.svg?style=flat)](https://www.versioneye.com/user/projects/54104e789e1622492d000025) -Send metrics to InfluxDB. +Send metrics to InfluxDB and query for any data. + +Add new points: ```php -$client = new \InfluxDB\Client(); -$client->setAdapter(new \InfluxDB\Adapter\UdpAdapter()); - -$client->mark("search", [ - "query" => "php" +$client->mark("app.search", [ + "key" => "this is my search" ]); ``` +Retrieve existing points: + +```php +$results = $client->query("select * from app.search"); +``` + +## InfluxDB client adapters + +Actually we supports two adapters + + * UDP/IP - in order to send data via UDP (datagram) + * HTTP JSON - in order to send/retrieve using HTTP (connection oriented) + +### Using UDP/IP Adapter + +Actually "socket" php library is used for UDP/IP adapter + +``` +$options = new Options(); +$adapter = new UdpAdapter($options); + +$client = new Client(); +$client->setAdapter($adapter); +``` + +### Using HTTP Adapter + +Actually Guzzle is used as HTTP client library + +```php +setAdapter($adapter); +``` + +### Query InfluxDB + +You can query the time series database using the query method. + +```php +$influx->query("select * from mine"); +$influx->query("select * from mine", "s"); // with time_precision +``` + +You can query the database only if the adapter is queryable (implements `QueryableInterface`), +actually `GuzzleAdapter`. + +The adapter returns the json decoded body of the InfluxDB response, something like: + +``` +array(1) { + [0] => + class stdClass#1 (3) { + public $name => + string(8) "tcp.test" + public $columns => + array(3) { + [0] => + string(4) "time" + [1] => + string(15) "sequence_number" + [2] => + string(4) "mark" + } + public $points => + array(1) { + [0] => + array(3) { + [0] => + int(1410545635590) + [1] => + int(2390001) + [2] => + string(7) "element" + } + } + } +} +``` + ## Install it Just use composer ```shell -php composer.phar require corley/influxdb-sdk:* +php composer.phar require corley/influxdb-sdk:dev-master ``` Or place it in your require section @@ -28,8 +112,37 @@ Or place it in your require section { "require": { // ... - "corley/influxdb-sdk": "*" + "corley/influxdb-sdk": "dev-master" } } ``` + +## Prepare lib dependencies + +Use your DiC or Service Locator in order to provide a configured client + +```php +setHost("analytics.mine.domain.tld"); +$options->setPort(8086); +$options->setUsername("root"); +$options->setPassword("root"); +$options->setDatabase("mine"); + +$guzzleHttp = new GuzzleHttpClient(); +$adapter = new InfluxHttpAdapter($guzzleHttp, $options); + +$influx = new Client(); +$influx->setAdapter($adapter); + +$influx->mark("tcp.test", ["mark" => "element"]); +``` + diff --git a/composer.json b/composer.json index c9db8a5a6..ea532ed47 100644 --- a/composer.json +++ b/composer.json @@ -2,8 +2,12 @@ "name": "corley/influxdb-sdk", "license": "MIT", "description": "Send your app metrics to InfluxDB", + "require": { + "guzzlehttp/guzzle": "~4" + }, "require-dev": { - "phpspec/phpspec": "2.*" + "phpspec/phpspec": "2.*", + "phpunit/phpunit": "4.*" }, "homepage": "http://www.corley.it/", "keywords": ["influxdb", "udp", "sdk"], @@ -23,7 +27,12 @@ ], "autoload": { "psr-0": { - "InfluxDB": "./src/" + "InfluxDB\\": ["./src/", "./tests"] } + }, + "suggests": { + "fabpot/pimple": "Allows to prepare the client dependencies in order to require an initialized instance", + "zendframework/zend-servicemanager": "Use a service locator in order to prepare a valid instance", + "symfony/dependency-injection": "Prepare a valid instance via the symfony DiC" } } diff --git a/composer.lock b/composer.lock index 4abb61a3f..18269867e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,11 +4,241 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "ebef29b39aea3cab015d3bf51e00121e", + "hash": "17fa2295e2cd007935278098484ab7cc", "packages": [ - + { + "name": "guzzlehttp/guzzle", + "version": "4.2.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "9c4fbbf6457768f5036fbd88f1229f3fca812a5d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9c4fbbf6457768f5036fbd88f1229f3fca812a5d", + "reference": "9c4fbbf6457768f5036fbd88f1229f3fca812a5d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/streams": "~2.1", + "php": ">=5.4.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0", + "psr/log": "~1.0" + }, + "suggest": { + "ext-curl": "Guzzle will use specific adapters if cURL is present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2014-09-08 22:11:58" + }, + { + "name": "guzzlehttp/streams", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/streams.git", + "reference": "f91b721d73f0e561410903b3b3c90a5d0e40b534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/streams/zipball/f91b721d73f0e561410903b3b3c90a5d0e40b534", + "reference": "f91b721d73f0e561410903b3b3c90a5d0e40b534", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Stream\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple abstraction over streams of data (Guzzle 4+)", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "stream" + ], + "time": "2014-08-17 21:15:53" + } ], "packages-dev": [ + { + "name": "ocramius/instantiator", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/Instantiator.git", + "reference": "e24a12178906ff2e7471b8aaf3a0eb789b59f881" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/Instantiator/zipball/e24a12178906ff2e7471b8aaf3a0eb789b59f881", + "reference": "e24a12178906ff2e7471b8aaf3a0eb789b59f881", + "shasum": "" + }, + "require": { + "ocramius/lazy-map": "1.0.*", + "php": "~5.3" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "2.0.*@ALPHA" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Instantiator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/Ocramius/Instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2014-08-25 14:48:16" + }, + { + "name": "ocramius/lazy-map", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/LazyMap.git", + "reference": "7fe3d347f5e618bcea7d39345ff83f3651d8b752" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/LazyMap/zipball/7fe3d347f5e618bcea7d39345ff83f3651d8b752", + "reference": "7fe3d347f5e618bcea7d39345ff83f3651d8b752", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "athletic/athletic": "~0.1.6", + "phpmd/phpmd": "1.5.*", + "phpunit/phpunit": ">=3.7", + "satooshi/php-coveralls": "~0.6", + "squizlabs/php_codesniffer": "1.4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "LazyMap\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/", + "role": "Developer" + } + ], + "description": "A library that provides lazy instantiation logic for a map of objects", + "homepage": "https://github.com/Ocramius/LazyMap", + "keywords": [ + "lazy", + "lazy instantiation", + "lazy loading", + "map", + "service location" + ], + "time": "2013-11-09 22:30:54" + }, { "name": "phpdocumentor/reflection-docblock", "version": "2.0.3", @@ -223,6 +453,650 @@ ], "time": "2014-07-18 21:26:55" }, + { + "name": "phpunit/php-code-coverage", + "version": "2.0.11", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "53603b3c995f5aab6b59c8e08c3a663d2cc810b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/53603b3c995f5aab6b59c8e08c3a663d2cc810b7", + "reference": "53603b3c995f5aab6b59c8e08c3a663d2cc810b7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "~1.0", + "sebastian/version": "~1.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4.1" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2014-08-31 06:33:04" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.3.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "File/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2013-10-10 15:34:57" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "Text/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2014-01-30 17:20:04" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2013-08-02 07:42:54" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "f8d5d08c56de5cfd592b3340424a81733259a876" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/f8d5d08c56de5cfd592b3340424a81733259a876", + "reference": "f8d5d08c56de5cfd592b3340424a81733259a876", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2014-08-31 06:12:13" + }, + { + "name": "phpunit/phpunit", + "version": "4.2.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "c3abe5953d1e60a0bf23012b1bc8c4d07f4832d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c3abe5953d1e60a0bf23012b1bc8c4d07f4832d7", + "reference": "c3abe5953d1e60a0bf23012b1bc8c4d07f4832d7", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpunit/php-code-coverage": "~2.0", + "phpunit/php-file-iterator": "~1.3.1", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "~1.0.2", + "phpunit/phpunit-mock-objects": "~2.2", + "sebastian/comparator": "~1.0", + "sebastian/diff": "~1.1", + "sebastian/environment": "~1.0", + "sebastian/exporter": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "", + "../../symfony/yaml/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2014-09-06 18:38:27" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "b241b18d87a47093f20fae8b0ba40379b00bd53a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/b241b18d87a47093f20fae8b0ba40379b00bd53a", + "reference": "b241b18d87a47093f20fae8b0ba40379b00bd53a", + "shasum": "" + }, + "require": { + "ocramius/instantiator": "~1.0", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2014-09-06 17:32:37" + }, + { + "name": "sebastian/comparator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2", + "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.1", + "sebastian/exporter": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2014-05-02 07:05:58" + }, + { + "name": "sebastian/diff", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d", + "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2013-08-03 16:46:33" + }, + { + "name": "sebastian/environment", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/79517609ec01139cd7e9fded0dd7ce08c952ef6a", + "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "4.0.*@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2014-02-18 16:17:19" + }, + { + "name": "sebastian/exporter", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529", + "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "4.0.*@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net", + "role": "Lead" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2014-02-16 08:26:31" + }, + { + "name": "sebastian/version", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", + "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2014-03-07 15:35:33" + }, { "name": "symfony/console", "version": "v2.5.4", diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 000000000..ada74cb23 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,20 @@ + + + + tests + + + + + src + + + diff --git a/scripts/influxdb_conf.toml b/scripts/influxdb_conf.toml new file mode 100644 index 000000000..4c946e0b3 --- /dev/null +++ b/scripts/influxdb_conf.toml @@ -0,0 +1,187 @@ +# Welcome to the InfluxDB configuration file. + +# If hostname (on the OS) doesn't return a name that can be resolved by the other +# systems in the cluster, you'll have to set the hostname to an IP or something +# that can be resolved here. +# hostname = "" + +bind-address = "0.0.0.0" + +# Once every 24 hours InfluxDB will report anonymous data to m.influxdb.com +# The data includes raft name (random 8 bytes), os, arch and version +# We don't track ip addresses of servers reporting. This is only used +# to track the number of instances running and the versions which +# is very helpful for us. +# Change this option to true to disable reporting. +reporting-disabled = false + +[logging] +# logging level can be one of "debug", "info", "warn" or "error" +level = "info" +file = "/opt/influxdb/shared/log.txt" # stdout to log to standard out + +# Configure the admin server +[admin] +port = 8083 # binding is disabled if the port isn't set +assets = "/opt/influxdb/current/admin" + +# Configure the http api +[api] +port = 8086 # binding is disabled if the port isn't set +# ssl-port = 8084 # Ssl support is enabled if you set a port and cert +# ssl-cert = /path/to/cert.pem + +# connections will timeout after this amount of time. Ensures that clients that misbehave +# and keep alive connections they don't use won't end up connection a million times. +# However, if a request is taking longer than this to complete, could be a problem. +read-timeout = "5s" + +[input_plugins] + + # Configure the graphite api + [input_plugins.graphite] + enabled = false + # port = 2003 + # database = "" # store graphite data in this database + # udp_enabled = true # enable udp interface on the same port as the tcp interface + + # Configure the udp api + #[input_plugins.udp] + #enabled = true + #port = 4444 + # database = "" + + # Configure multiple udp apis each can write to separate db. Just + # repeat the following section to enable multiple udp apis on + # different ports. + [[input_plugins.udp_servers]] # array of tables + enabled = true + port = 5551 + database = "udp.test" + +# Raft configuration +[raft] +# The raft port should be open between all servers in a cluster. +# However, this port shouldn't be accessible from the internet. + +port = 8090 + +# Where the raft logs are stored. The user running InfluxDB will need read/write access. +dir = "/opt/influxdb/shared/data/raft" + +# election-timeout = "1s" + +[storage] + +dir = "/opt/influxdb/shared/data/db" +# How many requests to potentially buffer in memory. If the buffer gets filled then writes +# will still be logged and once the local storage has caught up (or compacted) the writes +# will be replayed from the WAL +write-buffer-size = 10000 + +# the engine to use for new shards, old shards will continue to use the same engine +default-engine = "rocksdb" + +# The default setting on this is 0, which means unlimited. Set this to something if you want to +# limit the max number of open files. max-open-files is per shard so this * that will be max. +max-open-shards = 0 + +# The default setting is 100. This option tells how many points will be fetched from LevelDb before +# they get flushed into backend. +point-batch-size = 100 + +# The number of points to batch in memory before writing them to leveldb. Lowering this number will +# reduce the memory usage, but will result in slower writes. +write-batch-size = 5000000 + +# The server will check this often for shards that have expired that should be cleared. +retention-sweep-period = "10m" + +[storage.engines.leveldb] + +# Maximum mmap open files, this will affect the virtual memory used by +# the process +max-open-files = 1000 + +# LRU cache size, LRU is used by leveldb to store contents of the +# uncompressed sstables. You can use `m` or `g` prefix for megabytes +# and gigabytes, respectively. +lru-cache-size = "200m" + +[storage.engines.rocksdb] + +# Maximum mmap open files, this will affect the virtual memory used by +# the process +max-open-files = 1000 + +# LRU cache size, LRU is used by rocksdb to store contents of the +# uncompressed sstables. You can use `m` or `g` prefix for megabytes +# and gigabytes, respectively. +lru-cache-size = "200m" + +[storage.engines.hyperleveldb] + +# Maximum mmap open files, this will affect the virtual memory used by +# the process +max-open-files = 1000 + +# LRU cache size, LRU is used by rocksdb to store contents of the +# uncompressed sstables. You can use `m` or `g` prefix for megabytes +# and gigabytes, respectively. +lru-cache-size = "200m" + +[storage.engines.lmdb] + +map-size = "100g" + +[cluster] +# A comma separated list of servers to seed +# this server. this is only relevant when the +# server is joining a new cluster. Otherwise +# the server will use the list of known servers +# prior to shutting down. Any server can be pointed to +# as a seed. It will find the Raft leader automatically. + +# Here's an example. Note that the port on the host is the same as the raft port. +# seed-servers = ["hosta:8090","hostb:8090"] + +# Replication happens over a TCP connection with a Protobuf protocol. +# This port should be reachable between all servers in a cluster. +# However, this port shouldn't be accessible from the internet. + +protobuf_port = 8099 +protobuf_timeout = "2s" # the write timeout on the protobuf conn any duration parseable by time.ParseDuration +protobuf_heartbeat = "200ms" # the heartbeat interval between the servers. must be parseable by time.ParseDuration +protobuf_min_backoff = "1s" # the minimum backoff after a failed heartbeat attempt +protobuf_max_backoff = "10s" # the maxmimum backoff after a failed heartbeat attempt + +# How many write requests to potentially buffer in memory per server. If the buffer gets filled then writes +# will still be logged and once the server has caught up (or come back online) the writes +# will be replayed from the WAL +write-buffer-size = 1000 + +# the maximum number of responses to buffer from remote nodes, if the +# expected number of responses exceed this number then querying will +# happen sequentially and the buffer size will be limited to this +# number +max-response-buffer-size = 100 + +# When queries get distributed out to shards, they go in parallel. This means that results can get buffered +# in memory since results will come in any order, but have to be processed in the correct time order. +# Setting this higher will give better performance, but you'll need more memory. Setting this to 1 will ensure +# that you don't need to buffer in memory, but you won't get the best performance. +concurrent-shard-query-limit = 10 + +[wal] + +dir = "/opt/influxdb/shared/data/wal" +flush-after = 1000 # the number of writes after which wal will be flushed, 0 for flushing on every write +bookmark-after = 1000 # the number of writes after which a bookmark will be created + +# the number of writes after which an index entry is created pointing +# to the offset of the first request, default to 1k +index-after = 1000 + +# the number of requests per one log file, if new requests came in a +# new log file will be created +requests-per-logfile = 10000 diff --git a/spec/InfluxDB/Adapter/GuzzleAdapterSpec.php b/spec/InfluxDB/Adapter/GuzzleAdapterSpec.php new file mode 100644 index 000000000..815fa87a7 --- /dev/null +++ b/spec/InfluxDB/Adapter/GuzzleAdapterSpec.php @@ -0,0 +1,90 @@ +getHttpSeriesEndpoint()->willReturn("localhost"); + $options->getHttpDatabaseEndpoint()->willReturn("localhost"); + $options->getUsername()->willReturn("one"); + $options->getPassword()->willReturn("two"); + $this->beConstructedWith($client, $options); + } + + function it_is_initializable() + { + $this->shouldHaveType('InfluxDB\Adapter\GuzzleAdapter'); + } + + function it_should_send_data_via_post(Client $client, Options $options) + { + $client->post("localhost", [ + 'auth' => ["one", "two"], + 'body' => json_encode(['pippo']) + ])->shouldBeCalledTimes(1); + + $this->send(["pippo"]); + } + + function it_should_query_data(Client $client, Options $options) + { + $client->get( + "localhost", + [ + "auth" => ["one", "two"], + "query" => [ + "q" => "select * from tcp.test", + ] + ] + )->willReturn(new Response(200,[],null)); + $this->query("select * from tcp.test")->shouldReturn(null); + } + + function it_should_query_data_with_time_precision(Client $client, Options $options) + { + $client->get( + "localhost", + [ + "auth" => ["one", "two"], + "query" => [ + "time_precision" => "s", + "q" => "select * from tcp.test", + ] + ] + )->willReturn(new Response(200, [], null)); + $this->query("select * from tcp.test", "s")->shouldReturn(null); + } + + function it_should_list_all_databases(Client $client, Options $options) + { + $client->get( + "localhost", + [ + "auth" => ["one", "two"] + ] + )->shouldBeCalledTimes(1)->willReturn(new Response(200, [], null)); + + $this->getDatabases()->shouldReturn(null); + } + + function it_should_create_a_new_database(Client $client, Options $options) + { + $client->post( + "localhost", + [ + "auth" => ["one", "two"], + "body" => json_encode(["name" => "db_name"]) + ] + )->shouldBeCalledTimes(1)->willReturn(new Response(200, [], null)); + + $this->createDatabase("db_name")->shouldReturn(null); + } +} diff --git a/spec/InfluxDB/Adapter/UdpAdapterSpec.php b/spec/InfluxDB/Adapter/UdpAdapterSpec.php index 1e65698b9..48e14198f 100644 --- a/spec/InfluxDB/Adapter/UdpAdapterSpec.php +++ b/spec/InfluxDB/Adapter/UdpAdapterSpec.php @@ -4,12 +4,13 @@ namespace spec\InfluxDB\Adapter; use PhpSpec\ObjectBehavior; use Prophecy\Argument; +use InfluxDB\Options; class UdpAdapterSpec extends ObjectBehavior { - function let() + function let(Options $options) { - $this->beConstructedWith(); + $this->beConstructedWith($options); } function it_is_initializable() diff --git a/spec/InfluxDB/ClientSpec.php b/spec/InfluxDB/ClientSpec.php index ce1918e31..a0ee5ae02 100644 --- a/spec/InfluxDB/ClientSpec.php +++ b/spec/InfluxDB/ClientSpec.php @@ -1,9 +1,12 @@ setAdapter($adapter); } + function it_is_initializable() { $this->shouldHaveType('InfluxDB\Client'); } - function it_should_send_data(\InfluxDB\Adapter\AdapterInterface $adapter) + function it_should_send_data(AdapterInterface $adapter) { $adapter->send([[ "name" => "video.search", @@ -31,4 +35,35 @@ class ClientSpec extends ObjectBehavior "title" => "Autogrill" ]); } + + function it_should_query_on_querable_adapter(GuzzleAdapter $adapter) + { + $this->setAdapter($adapter); + $adapter->query("select * from tcp.test", false)->willReturn([]); + + $this->query("select * from tcp.test")->shouldReturn([]); + } + + function it_should_query_with_time_precision(GuzzleAdapter $adapter) + { + $this->setAdapter($adapter); + $adapter->query("select * from tcp.test", "s")->willReturn([]); + + $this->query("select * from tcp.test", "s")->shouldReturn([]); + } + + function it_should_query_but_skip_invalid_time_precision(GuzzleAdapter $adapter) + { + $this->setAdapter($adapter); + $adapter->query("select * from tcp.test", false)->willReturn([]); + + $this->query("select * from tcp.test", "r")->shouldReturn([]); + } + + function it_should_thrown_an_exception_on_unquerable_adapter(UdpAdapter $adapter) + { + $this->setAdapter($adapter); + + $this->shouldThrow("\\BadMethodCallException")->duringQuery("select * from tcp.test"); + } } diff --git a/spec/InfluxDB/OptionsSpec.php b/spec/InfluxDB/OptionsSpec.php new file mode 100644 index 000000000..d926faf83 --- /dev/null +++ b/spec/InfluxDB/OptionsSpec.php @@ -0,0 +1,40 @@ +shouldHaveType('InfluxDB\Options'); + } + + function it_should_create_a_valid_tcp_endpoint() + { + $this->setDatabase("mine"); + $this->getHttpSeriesEndpoint() + ->shouldReturn("http://localhost:8086/db/mine/series"); + } + + function it_should_allows_option_override_for_tcp_endpoint() + { + $this->setHost("influx.1.prod.tld"); + $this->setPort(19385); + $this->setUsername("walter"); + $this->setPassword("walter"); + $this->setDatabase("me"); + $this->getHttpSeriesEndpoint() + ->shouldReturn("http://influx.1.prod.tld:19385/db/me/series"); + } + + function it_should_allows_https_for_tcp_endpoint() + { + $this->setProtocol("https"); + $this->setDatabase("me"); + $this->getHttpSeriesEndpoint() + ->shouldReturn("https://localhost:8086/db/me/series"); + } +} diff --git a/src/InfluxDB/Adapter/AdapterInterface.php b/src/InfluxDB/Adapter/AdapterInterface.php index a1509c311..d0b9e539a 100644 --- a/src/InfluxDB/Adapter/AdapterInterface.php +++ b/src/InfluxDB/Adapter/AdapterInterface.php @@ -1,13 +1,7 @@ httpClient = $httpClient; + $this->options = $options; + } + + public function send($message) + { + $httpMessage = [ + "auth" => [$this->options->getUsername(), $this->options->getPassword()], + "body" => json_encode($message) + ]; + + $endpoint = $this->options->getHttpSeriesEndpoint(); + return $this->httpClient->post($endpoint, $httpMessage); + } + + public function query($query, $timePrecision = false) + { + $options = [ + "auth" => [$this->options->getUsername(), $this->options->getPassword()], + 'query' => [ + "q" => $query, + ] + ]; + + if ($timePrecision) { + $options["query"]["time_precision"] = $timePrecision; + } + + $endpoint = $this->options->getHttpSeriesEndpoint(); + + return $this->httpClient->get($endpoint, $options)->json(); + } + + public function getDatabases() + { + $options = [ + "auth" => [$this->options->getUsername(), $this->options->getPassword()], + ]; + + $endpoint = $this->options->getHttpDatabaseEndpoint(); + + return $this->httpClient->get($endpoint, $options)->json(); + } + + public function createDatabase($name) + { + $httpMessage = [ + "auth" => [$this->options->getUsername(), $this->options->getPassword()], + "body" => json_encode(["name" => $name]) + ]; + + $endpoint = $this->options->getHttpDatabaseEndpoint(); + return $this->httpClient->post($endpoint, $httpMessage)->json(); + } + + public function deleteDatabase($name) + { + $httpMessage = [ + "auth" => [$this->options->getUsername(), $this->options->getPassword()], + ]; + + $endpoint = $this->options->getHttpDatabaseEndpoint($name); + return $this->httpClient->delete($endpoint, $httpMessage)->json(); + } +} diff --git a/src/InfluxDB/Adapter/QueryableInterface.php b/src/InfluxDB/Adapter/QueryableInterface.php new file mode 100644 index 000000000..164f30bf4 --- /dev/null +++ b/src/InfluxDB/Adapter/QueryableInterface.php @@ -0,0 +1,10 @@ +host = $host; - $this->port = $port; - $this->username = $user; - $this->password = $password; - } - - public function getSocket() - { - return $this->socket; - } - - public function getName() - { - return $this->name; - } - - public function connect() - { - $this->socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); - return $this; - } - - public function disconnect() - { - socket_close($this->getSocket()); + $this->options = $options; } public function send($message) { $message = json_encode($message); - socket_sendto($this->getSocket(), $message, strlen($message), 0, $this->host, $this->port); - } + $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); + socket_sendto($socket, $message, strlen($message), 0, $this->options->getHost(), $this->options->getPort()); + socket_close($socket); + } } diff --git a/src/InfluxDB/Client.php b/src/InfluxDB/Client.php index e92a889fb..6971d71ba 100644 --- a/src/InfluxDB/Client.php +++ b/src/InfluxDB/Client.php @@ -2,6 +2,9 @@ namespace InfluxDB; +use InfluxDb\Adapter\QueryableInterface; +use InfluxDb\Adapter\ConnectableInterface; + class Client { private $adapter; @@ -17,16 +20,6 @@ class Client return $this->adapter; } - public function connect() - { - return $this->getAdapter()->connect(); - } - - public function disconnect() - { - return $this->getAdapter()->disconnect(); - } - public function mark($name, array $values) { $data =[]; @@ -36,4 +29,53 @@ class Client return $this->getAdapter()->send([$data]); } + + public function query($query, $timePrecision = false) + { + if (!($this->getAdapter() instanceOf QueryableInterface)) { + throw new \BadMethodCallException("You can query the database only if the adapter supports it!"); + } + + $timePrecision = $this->clearTimePrecision($timePrecision); + + return $this->getAdapter()->query($query, $timePrecision); + } + + public function getDatabases() + { + if (!($this->getAdapter() instanceOf QueryableInterface)) { + throw new \BadMethodCallException("You can query the database only if the adapter supports it!"); + } + return $this->getAdapter()->getDatabases(); + } + + public function createDatabase($name) + { + if (!($this->getAdapter() instanceOf QueryableInterface)) { + throw new \BadMethodCallException("You can query the database only if the adapter supports it!"); + } + return $this->getAdapter()->createDatabase($name); + } + + public function deleteDatabase($name) + { + if (!($this->getAdapter() instanceOf QueryableInterface)) { + throw new \BadMethodCallException("You can query the database only if the adapter supports it!"); + } + return $this->getAdapter()->deleteDatabase($name); + } + + private function clearTimePrecision($timePrecision) + { + switch ($timePrecision) { + case 's': + case 'u': + case 'ms': + break; + default: + $timePrecision = false; + } + + return $timePrecision; + } } diff --git a/src/InfluxDB/Options.php b/src/InfluxDB/Options.php new file mode 100644 index 000000000..a9478ba44 --- /dev/null +++ b/src/InfluxDB/Options.php @@ -0,0 +1,116 @@ +host = "localhost"; + $this->port = 8086; + $this->username = "root"; + $this->password = "root"; + $this->setProtocol("http"); + } + + public function getProtocol() + { + return $this->protocol; + } + + public function setProtocol($protocol) + { + $this->protocol = $protocol; + return $this; + } + + public function getHost() + { + return $this->host; + } + + public function setHost($host) + { + $this->host = $host; + return $this; + } + + public function getPort() + { + return $this->port; + } + + public function setPort($port) + { + $this->port = $port; + return $this; + } + + public function getUsername() + { + return $this->username; + } + + public function setUsername($username) + { + $this->username = $username; + return $this; + } + + public function getPassword() + { + return $this->password; + } + + public function setPassword($password) + { + $this->password = $password; + return $this; + } + + public function getDatabase() + { + return $this->database; + } + + public function setDatabase($database) + { + $this->database = $database; + return $this; + } + + public function getHttpSeriesEndpoint() + { + return sprintf( + "%s://%s:%d/db/%s/series", + $this->getProtocol(), + $this->getHost(), + $this->getPort(), + $this->getDatabase() + ); + } + + public function getHttpDatabaseEndpoint($name = false) + { + $url = sprintf( + "%s://%s:%d/db", + $this->getProtocol(), + $this->getHost(), + $this->getPort() + ); + + if ($name !== false) { + $url .= "/{$name}"; + } + + return $url; + } +} diff --git a/tests/InfluxDB/ClientTest.php b/tests/InfluxDB/ClientTest.php new file mode 100644 index 000000000..5d0dc8af1 --- /dev/null +++ b/tests/InfluxDB/ClientTest.php @@ -0,0 +1,150 @@ +rawOptions = $options; + + $tcpOptions = $options["tcp"]; + + $options = new Options(); + $options->setHost($tcpOptions["host"]); + $options->setPort($tcpOptions["port"]); + $options->setUsername($tcpOptions["username"]); + $options->setPassword($tcpOptions["password"]); + $options->setDatabase($tcpOptions["database"]); + + $this->options = $options; + + $guzzleHttp = new GuzzleHttpClient(); + $adapter = new InfluxHttpAdapter($guzzleHttp, $options); + + $influx = new Client(); + $influx->setAdapter($adapter); + $this->object = $influx; + + $databases = $this->object->getDatabases(); + foreach ($databases as $database) { + $this->object->deleteDatabase($database["name"]); + } + + $this->object->createDatabase($this->rawOptions["udp"]["database"]); + $this->object->createDatabase($this->rawOptions["tcp"]["database"]); + } + + /** + * @group tcp + */ + public function testGuzzleHttpApiWorksCorrectly() + { + $this->object->mark("tcp.test", ["mark" => "element"]); + + $body = $this->object->query("select * from tcp.test"); + $this->assertCount(1, $body[0]["points"]); + $this->assertEquals("element", $body[0]["points"][0][2]); + } + + /** + * @group tcp + */ + public function testGuzzleHttpQueryApiWorksCorrectly() + { + $this->object->mark("tcp.test", ["mark" => "element"]); + + $body = $this->object->query("select * from tcp.test"); + + $this->assertCount(1, $body); + $this->assertEquals("tcp.test", $body[0]["name"]); + $this->assertEquals("element", $body[0]["points"][0][2]); + } + + /** + * @group tcp + */ + public function testGuzzleHttpQueryApiWithMultipleData() + { + $this->object->mark("tcp.test", ["mark" => "element"]); + $this->object->mark("tcp.test", ["mark" => "element2"]); + $this->object->mark("tcp.test", ["mark" => "element3"]); + + $body = $this->object->query("select mark from tcp.test", "s"); + + $this->assertCount(3, $body[0]["points"]); + $this->assertEquals("tcp.test", $body[0]["name"]); + } + + /** + * @group tcp + */ + public function testGuzzleHttpQueryApiWithTimePrecision() + { + $this->object->mark("tcp.test", ["mark" => "element"]); + + $body = $this->object->query("select mark from tcp.test", "s"); + + $this->assertCount(1, $body[0]["points"]); + $this->assertEquals("tcp.test", $body[0]["name"]); + } + + /** + * @group udp + */ + public function testUdpIpWriteData() + { + $rawOptions = $this->rawOptions; + $options = new Options(); + $options->setHost($rawOptions["udp"]["host"]); + $options->setUsername($rawOptions["udp"]["username"]); + $options->setPassword($rawOptions["udp"]["password"]); + $options->setPort($rawOptions["udp"]["port"]); + + $adapter = new UdpAdapter($options); + $object = new Client(); + $object->setAdapter($adapter); + + $object->mark("udp.test", ["mark" => "element"]); + $object->mark("udp.test", ["mark" => "element1"]); + $object->mark("udp.test", ["mark" => "element2"]); + $object->mark("udp.test", ["mark" => "element3"]); + + // Wait UDP/IP message arrives + usleep(200e3); + + $this->options->setDatabase("udp.test"); + $body = $this->object->query("select * from udp.test"); + + $this->assertCount(4, $body[0]["points"]); + $this->assertEquals("udp.test", $body[0]["name"]); + } + + public function testListActiveDatabses() + { + $databases = $this->object->getDatabases(); + + $this->assertCount(2, $databases); + } + + public function testCreateANewDatabase() + { + $this->object->createDatabase("walter"); + $databases = $this->object->getDatabases(); + + $this->assertCount(3, $databases); + + $this->object->deleteDatabase("walter"); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 000000000..99b776def --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,18 @@ + [ + "host" => "localhost", + "port" => 8086, + "protocol" => "http", + "database" => "tcp.test", + "username" => "root", + "password" => "root", + ], + "udp" => [ + "host" => "localhost", + "port" => 5551, + "database" => "udp.test", + "username" => "root", + "password" => "root" + ], +];