diff --git a/lib/influxdb-php-sdk/.gitignore b/lib/influxdb-php-sdk/.gitignore
new file mode 100644
index 0000000000..b7f1a2785f
--- /dev/null
+++ b/lib/influxdb-php-sdk/.gitignore
@@ -0,0 +1,3 @@
+vendor
+tags
+composer.lock
diff --git a/lib/influxdb-php-sdk/.scrutinizer.yml b/lib/influxdb-php-sdk/.scrutinizer.yml
new file mode 100644
index 0000000000..963a7af45c
--- /dev/null
+++ b/lib/influxdb-php-sdk/.scrutinizer.yml
@@ -0,0 +1,3 @@
+tools:
+ external_code_coverage:
+ timeout: 600
diff --git a/lib/influxdb-php-sdk/CONTRIBUTING.md b/lib/influxdb-php-sdk/CONTRIBUTING.md
new file mode 100644
index 0000000000..778ffc64c9
--- /dev/null
+++ b/lib/influxdb-php-sdk/CONTRIBUTING.md
@@ -0,0 +1,13 @@
+# Contributing to InfluxDB PHP SDK
+
+## Pull requests are always welcome
+
+Not sure if that typo is worth a pull request? Found a bug and know how to fix
+it? Do it! We will appreciate it. Any significant improvement should be
+documented as a GitHub issue before anybody starts working on it.
+
+We are always thrilled to receive pull requests. We do our best to process them
+quickly. If your pull request is not accepted on the first try, don't get
+discouraged!
+
+Just branch on master and prepare your PR.
diff --git a/lib/influxdb-php-sdk/LICENSE b/lib/influxdb-php-sdk/LICENSE
new file mode 100644
index 0000000000..db1e02eebe
--- /dev/null
+++ b/lib/influxdb-php-sdk/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015 Corley S.r.l.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/lib/influxdb-php-sdk/README.md b/lib/influxdb-php-sdk/README.md
new file mode 100644
index 0000000000..09662befed
--- /dev/null
+++ b/lib/influxdb-php-sdk/README.md
@@ -0,0 +1,347 @@
+# InfluxDB PHP SDK
+
+[](https://circleci.com/gh/corley/influxdb-php-sdk/tree/master)
+[](https://scrutinizer-ci.com/g/corley/influxdb-php-sdk/?branch=master)
+[](https://scrutinizer-ci.com/g/corley/influxdb-php-sdk/?branch=master)
+[](https://packagist.org/packages/corley/influxdb-sdk)
+[](https://packagist.org/packages/corley/influxdb-sdk)
+
+Send metrics to InfluxDB and query for any data.
+
+This project support InfluxDB API `>= 0.9` - **For InfluxDB v0.8 checkout branch 0.3**
+
+Supported adapters:
+
+ * HTTP
+ * UDP/IP
+
+## Install it
+
+Just use composer
+
+```json
+{
+ "require": {
+ // ...
+ "corley/influxdb-sdk": ">=0.4"
+ }
+}
+```
+
+## Use it
+
+Add new points:
+
+```php
+$client->mark("app-search", [
+ "key" => "this is my search"
+]);
+```
+
+Or use InfluxDB direct messages
+
+```php
+$client->mark([
+ "tags" => [
+ "dc" => "eu-west-1",
+ ],
+ "points" => [
+ [
+ "measurement" => "instance",
+ "fields" => [
+ "cpu" => 18.12,
+ "free" => 712423,
+ ],
+ ],
+ ]
+]);
+```
+
+Retrieve existing points:
+
+```php
+$results = $client->query('select * from "app-search"');
+```
+
+## InfluxDB client adapters
+
+Actually we supports two network adapters
+
+ * UDP/IP - in order to send data via UDP/IP (datagram)
+ * HTTP JSON - in order to send/retrieve using HTTP messages (connection oriented)
+
+### Using UDP/IP Adapter
+
+In order to use the UDP/IP adapter your must have PHP compiled with the `sockets` extension.
+
+**Usage**
+
+```php
+$options = new Options();
+$adapter = new UdpAdapter($options);
+
+$client = new Client($adapter);
+```
+
+### Using HTTP Adapters
+
+Actually Guzzle is used as HTTP client library
+
+```php
+ [
+ "name" => "InfluxDB\\Adapter\\GuzzleAdapter",
+ "options" => [
+ // guzzle options
+ ],
+ ],
+ "options" => [
+ "host" => "my.influx.domain.tld",
+ "db" => "mydb",
+ "retention_policy" => "myPolicy",
+ "tags" => [
+ "env" => "prod",
+ "app" => "myApp",
+ ],
+ ]
+];
+$client = \InfluxDB\ClientFactory::create($options);
+```
+
+Of course you can always use a DiC (eg `symfony/dependency-injection`) or your service manager in order to create
+a valid client instance.
+
+### Query InfluxDB
+
+You can query the time series database using the query method.
+
+```php
+$influx->query('select * from "mine"');
+```
+
+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) {
+ 'results' =>
+ array(1) {
+ [0] =>
+ array(1) {
+ 'series' =>
+ array(1) {
+ ...
+ }
+ }
+ }
+}
+```
+
+## UDP/IP support
+
+As you know InfluxDB support UDP/IP with a "line protocol", that is a string
+line, like:
+
+```
+cpu,region=us-west,env=prod,zone=1c cpu=18.12,free=712432 1257894000
+```
+
+In order to simplify the SDK usage, you will use a single method signature
+for both adapters, UDP/IP and HTTP:
+
+**Concise Format**
+
+```php
+$client->mark("serie-name", [
+ "power" => 124.21,
+ "voltage" => 12.4,
+]);
+```
+
+**Extended Format**
+
+```php
+$client->mark([
+ "tags" => [
+ "region" => "us-west",
+ "host" => "serverA",
+ "env" => "prod",
+ "target" => "servers",
+ "zone" => "1c",
+ ],
+ "time" => "2009-11-10T23:00:00Z",
+ "points" => [
+ [
+ "measurement" => "cpu",
+ "fields" => [
+ "cpu" => 18.12,
+ "free" => 712432,
+ ],
+ ],
+ ],
+]);
+```
+
+If you want to use the inline protocol directly you have to use the UDP/IP adapter directly
+
+```
+$udp = new UdpAdapter($options);
+$udp->write("cpu,region=us-west,host=serverA,env=prod,target=servers,zone=1c cpu=18.12,free=712432 1257894000");
+```
+
+## Database operations
+
+You can create, list or destroy databases using dedicated methods
+
+```php
+$client->getDatabases(); // list all databases
+$client->createDatabase("my.name"); // create a new database with name "my.name"
+$client->deleteDatabase("my.name"); // delete an existing database with name "my.name"
+```
+
+Actually only queryable adapters can handle databases (implements the
+`QueryableInterface`)
+
+## Global tags and retention policy
+
+You can set a set of default tags, that the SDK will add to your metrics:
+
+```php
+$options = new Options();
+$options->setTags([
+ "env" => "prod",
+ "region" => "eu-west-1",
+]);
+```
+
+The SDK mark all point adding those tags.
+
+You can set a default retentionPolicy using
+
+```
+$options->setRetentionPolicy("myPolicy");
+```
+
+In that way the SDK use that policy instead of `default` policy.
+
+## Proxies and InfluxDB
+
+If you proxy your InfluxDB typically you have a prefix in your endpoints.
+
+```
+$option->setHost("proxy.influxdb.tld");
+$option->setPort(80);
+$option->setPrefix("/influxdb"); // your prefix is: /influxdb
+
+// final url will be: http://proxy.influxdb.tld:80/influxdb/write
+
+$client->mark("serie", ["data" => "my-data"]);
+```
+
+## Benchmarks
+
+Simple benchmarks executed on a Sony Vaio T13 (SVT1311C5E)
+
+### Adapters
+
+The impact using UDP/IP or HTTP adapters
+
+```
+Corley\Benchmarks\InfluxDB\AdapterEvent
+ Method Name Iterations Average Time Ops/second
+ ------------------------ ------------ -------------- -------------
+ sendDataUsingHttpAdapter: [1,000 ] [0.0167509446144] [59.69813]
+ sendDataUsingUdpAdapter : [1,000 ] [0.0000905156136] [11,047.81773]
+```
+
+### Message to inline protocol conversion
+
+As you know the SDK will provide a single interface in order to send data to
+InfluxDB (concise or expanded).
+
+The impact of message to inline protocol conversion is:
+
+```
+Corley\Benchmarks\InfluxDB\MessageToInlineProtocolEvent
+ Method Name Iterations Average Time Ops/second
+ ---------------------------------------------------- ------------ -------------- -------------
+ convertMessageToInlineProtocolWithNoTags : [10,000 ] [0.0000343696594] [29,095.42942]
+ convertMessageToInlineProtocolWithGlobalTags : [10,000 ] [0.0000437165260] [22,874.64469]
+ convertMessageToInlineProtocolWithDifferentTagLevels: [10,000 ] [0.0000493728638] [20,254.04086]
+```
+
+### Query Builder
+
+Interested in a Query Builder?
+
+https://github.com/corley/dbal-influxdb
+
+Thanks to Doctrine DBAL (Abstract Layer) you can use the query builder
+
+```
+$qb = $conn->createQueryBuilder();
+
+$qb->select("*")
+ ->from("cpu_load_short")
+ ->where("time = ?")
+ ->setParameter(0, 1434055562000000000);
+
+$data = $qb->execute();
+foreach ($data->fetchAll() as $element) {
+ // Use your element
+}
+```
+
+```php
+$config = new \Doctrine\DBAL\Configuration();
+//..
+$connectionParams = array(
+ 'dbname' => 'mydb',
+ 'user' => 'root',
+ 'password' => 'root',
+ 'host' => 'localhost',
+ 'port' => 8086,
+ "driverClass" => "Corley\\DBAL\\Driver\\InfluxDB",
+);
+$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
+```
+
+
+## FAQ
+
+### Add sockets support to your PHP
+
+To verify if you have the `sockets` extension just issue a:
+
+```bash
+php -m | grep sockets
+```
+
+If you don't have the `sockets` extension, you can proceed in two ways:
+
+ - Recompile your PHP whith the `--enable-sockets` flag
+ - Or just compile the `sockets` extension extracting it from the PHP source.
+
+ 1. Download the source relative to the PHP version that you on from [here](https://github.com/php/php-src/releases)
+ 2. Enter in the `ext/sockets` directory
+ 3. Issue a `phpize && ./configure && make -j && sudo make install`
+ 4. Add `extension=sockets.so` to your php.ini
+
diff --git a/lib/influxdb-php-sdk/VERSION b/lib/influxdb-php-sdk/VERSION
new file mode 100644
index 0000000000..8f0916f768
--- /dev/null
+++ b/lib/influxdb-php-sdk/VERSION
@@ -0,0 +1 @@
+0.5.0
diff --git a/lib/influxdb-php-sdk/benchmarks/Benchmarks/InfluxDB/AdapterEvent.php b/lib/influxdb-php-sdk/benchmarks/Benchmarks/InfluxDB/AdapterEvent.php
new file mode 100644
index 0000000000..d3d37f6e5e
--- /dev/null
+++ b/lib/influxdb-php-sdk/benchmarks/Benchmarks/InfluxDB/AdapterEvent.php
@@ -0,0 +1,54 @@
+setHost("localhost");
+ $options->setPort(8086);
+ $options->setUsername("root");
+ $options->setPassword("root");
+ $options->setDatabase("tcp.test");
+
+ $client = new Client(new GuzzleAdapter(new HttpClient(), $options));
+ $client->createDatabase("tcp.test");
+ $client->createDatabase("udp.test");
+
+ $this->httpClient = $client;
+
+ $opts = new Options();
+ $opts->setPort(4444);
+
+ $client = new Client(new UdpAdapter($opts));
+
+ $this->udpClient = $client;
+ }
+
+ /**
+ * @iterations 1000
+ */
+ public function sendDataUsingHttpAdapter()
+ {
+ $this->httpClient->mark("metric.name", ["key" => "value"]);
+ }
+
+ /**
+ * @iterations 1000
+ */
+ public function sendDataUsingUdpAdapter()
+ {
+ $this->udpClient->mark("metric.name", ["key" => "value"]);
+ }
+}
diff --git a/lib/influxdb-php-sdk/benchmarks/Benchmarks/InfluxDB/MessageToInlineProtocolEvent.php b/lib/influxdb-php-sdk/benchmarks/Benchmarks/InfluxDB/MessageToInlineProtocolEvent.php
new file mode 100644
index 0000000000..964fdc34e6
--- /dev/null
+++ b/lib/influxdb-php-sdk/benchmarks/Benchmarks/InfluxDB/MessageToInlineProtocolEvent.php
@@ -0,0 +1,76 @@
+ [
+ [
+ "measurement" => "vm-serie",
+ "fields" => [
+ "cpu" => 18.12,
+ "free" => 712423,
+ ],
+ ],
+ ]
+ ]
+ );
+ }
+
+ /**
+ * @iterations 10000
+ */
+ public function convertMessageToInlineProtocolWithGlobalTags()
+ {
+ \InfluxDB\Adapter\message_to_inline_protocol(
+ [
+ "tags" => [
+ "dc" => "eu-west-1",
+ ],
+ "points" => [
+ [
+ "measurement" => "vm-serie",
+ "fields" => [
+ "cpu" => 18.12,
+ "free" => 712423,
+ ],
+ ],
+ ]
+ ]
+ );
+ }
+
+ /**
+ * @iterations 10000
+ */
+ public function convertMessageToInlineProtocolWithDifferentTagLevels()
+ {
+ \InfluxDB\Adapter\message_to_inline_protocol(
+ [
+ "tags" => [
+ "dc" => "eu-west-1",
+ ],
+ "points" => [
+ [
+ "measurement" => "vm-serie",
+ "tags" => [
+ "server" => "tc12",
+ ],
+ "fields" => [
+ "cpu" => 18.12,
+ "free" => 712423,
+ ],
+ ],
+ ]
+ ]
+ );
+ }
+}
diff --git a/lib/influxdb-php-sdk/circle.yml b/lib/influxdb-php-sdk/circle.yml
new file mode 100644
index 0000000000..4ccd1fe06a
--- /dev/null
+++ b/lib/influxdb-php-sdk/circle.yml
@@ -0,0 +1,51 @@
+machine:
+ timezone:
+ Europe/Rome
+ php:
+ version: 5.6.5
+
+dependencies:
+ pre:
+ - sudo apt-get update
+ - sudo apt-get install nginx
+ - wget https://s3.amazonaws.com/influxdb/influxdb_latest_amd64.deb
+ - sudo useradd influxdb
+ - sudo dpkg -i influxdb_latest_amd64.deb
+ - sudo cp ./scripts/influxdb_conf.toml /etc/opt/influxdb/influxdb.conf
+ - sudo /opt/influxdb/influxd -config /etc/opt/influxdb/influxdb.conf: {background: true}
+ - sudo cp scripts/nginx_proxy.conf /etc/nginx/conf.d/proxy.conf
+ - sudo service nginx stop
+ - sleep 2
+ - sudo service nginx start
+ - sed -i 's/^;//' ~/.phpenv/versions/$(phpenv global)/etc/conf.d/xdebug.ini
+ override:
+ - phpenv global 5.6.5
+ - composer install --prefer-source --no-interaction
+ - phpenv global 5.5.21
+ - composer install --prefer-source --no-interaction
+
+test:
+ override:
+ - phpenv global 5.6.5
+ - composer require guzzlehttp/guzzle:~6 --prefer-source --no-interaction --update-with-dependencies
+ - composer show -i
+ - vendor/bin/phpunit --coverage-clover clover.xml
+ - composer require guzzlehttp/guzzle:~5 --prefer-source --no-interaction --update-with-dependencies
+ - composer show -i
+ - vendor/bin/phpunit
+ - composer require guzzlehttp/guzzle:~4 --prefer-source --no-interaction --update-with-dependencies
+ - composer show -i
+ - vendor/bin/phpunit
+ - phpenv global 5.5.21
+ - composer require guzzlehttp/guzzle:~6 --prefer-source --no-interaction --update-with-dependencies
+ - composer show -i
+ - vendor/bin/phpunit
+ - composer require guzzlehttp/guzzle:~5 --prefer-source --no-interaction --update-with-dependencies
+ - composer show -i
+ - vendor/bin/phpunit
+ - composer require guzzlehttp/guzzle:~4 --prefer-source --no-interaction --update-with-dependencies
+ - composer show -i
+ - vendor/bin/phpunit
+ post:
+ - wget https://scrutinizer-ci.com/ocular.phar
+ - php ocular.phar code-coverage:upload --format=php-clover clover.xml
diff --git a/lib/influxdb-php-sdk/composer.json b/lib/influxdb-php-sdk/composer.json
new file mode 100644
index 0000000000..6abce12da7
--- /dev/null
+++ b/lib/influxdb-php-sdk/composer.json
@@ -0,0 +1,53 @@
+{
+ "name": "corley/influxdb-sdk",
+ "license": "MIT",
+ "description": "Send your app metrics to InfluxDB",
+ "require": {
+ "php": ">=5.4",
+ "guzzlehttp/guzzle": "~4|~5|~6",
+ "zendframework/zend-stdlib": "~2",
+ "zendframework/zend-filter": "~2",
+ "zendframework/zend-servicemanager": "~2"
+ },
+ "require-dev": {
+ "codeclimate/php-test-reporter": "dev-master",
+ "phpunit/phpunit": "4.*",
+ "athletic/athletic": "~0.1",
+ "ext-sockets": "*"
+ },
+ "homepage": "http://www.corley.it/",
+ "keywords": ["influxdb", "udp", "sdk"],
+ "authors": [
+ {
+ "name": "Gianluca Arbezzano",
+ "email": "gianluca.arbezzano@corley.it"
+ },
+ {
+ "name": "Walter Dal Mut",
+ "email": "walter.dalmut@corley.it"
+ },
+ {
+ "name": "Gabriele Mittica",
+ "email": "gabriele.mittica@corley.it"
+ }
+ ],
+ "autoload": {
+ "psr-4": {
+ "InfluxDB\\": ["./src/"],
+ "Corley\\": ["./benchmarks/"]
+ },
+ "files": ["src/Adapter/helpers.php"]
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "InfluxDB\\": ["./tests/unit"],
+ "InfluxDB\\Integration\\": ["./tests/integration"]
+ }
+ },
+ "suggest": {
+ "corley/dbal-influxdb": "This library help you to build query",
+ "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/lib/influxdb-php-sdk/phpunit.xml.dist b/lib/influxdb-php-sdk/phpunit.xml.dist
new file mode 100644
index 0000000000..36a9debbef
--- /dev/null
+++ b/lib/influxdb-php-sdk/phpunit.xml.dist
@@ -0,0 +1,22 @@
+
+
+
+ tests/integration
+
+
+ tests/unit
+
+
+
+
+ src
+
+
+
diff --git a/lib/influxdb-php-sdk/scripts/influxdb_conf.toml b/lib/influxdb-php-sdk/scripts/influxdb_conf.toml
new file mode 100644
index 0000000000..9c2568114b
--- /dev/null
+++ b/lib/influxdb-php-sdk/scripts/influxdb_conf.toml
@@ -0,0 +1,74 @@
+[meta]
+ dir = "/var/opt/influxdb/meta"
+ hostname = "localhost"
+ bind-address = ":8088"
+ retention-autocreate = true
+ election-timeout = "1s"
+ heartbeat-timeout = "1s"
+ leader-lease-timeout = "500ms"
+ commit-timeout = "50ms"
+
+[data]
+ dir = "/var/opt/influxdb/data"
+ retention-auto-create = true
+ retention-check-enabled = true
+ retention-check-period = "10m0s"
+ retention-create-period = "45m0s"
+
+[cluster]
+ shard-writer-timeout = "5s"
+
+[retention]
+ enabled = true
+ check-interval = "10m0s"
+
+[admin]
+ enabled = true
+ bind-address = ":8083"
+
+[http]
+ enabled = true
+ bind-address = ":8086"
+ auth-enabled = false
+ log-enabled = true
+ write-tracing = false
+ pprof-enabled = false
+
+[collectd]
+ enabled = false
+ bind-address = ""
+ database = ""
+ typesdb = ""
+
+[opentsdb]
+ enabled = false
+ bind-address = ""
+ database = ""
+ retention-policy = ""
+
+[udp]
+ enabled = true
+ bind-address = ":4444"
+ database = "udp.test"
+ batch-size = 0
+ batch-timeout = "10ns"
+
+[monitoring]
+ enabled = false
+ write-interval = "1m0s"
+
+[continuous_queries]
+ enabled = true
+ recompute-previous-n = 2
+ recompute-no-older-than = "10m0s"
+ compute-runs-per-interval = 10
+ compute-no-more-than = "2m0s"
+
+[hinted-handoff]
+ enabled = true
+ dir = "/var/opt/influxdb/hh"
+ max-size = 1073741824
+ max-age = "168h0m0s"
+ retry-rate-limit = 0
+ retry-interval = "1s"
+
diff --git a/lib/influxdb-php-sdk/scripts/nginx_proxy.conf b/lib/influxdb-php-sdk/scripts/nginx_proxy.conf
new file mode 100644
index 0000000000..f92d10a30a
--- /dev/null
+++ b/lib/influxdb-php-sdk/scripts/nginx_proxy.conf
@@ -0,0 +1,25 @@
+server {
+ listen 9000 default_server;
+ listen [::]:9000 default_server ipv6only=on;
+
+ root /usr/share/nginx/html;
+ index index.html index.htm;
+
+ server_name localhost;
+
+ location / {
+ try_files $uri $uri/ =404;
+ }
+
+ location /influxdb {
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header Host $http_host;
+ proxy_set_header X-NginX-Proxy true;
+
+ rewrite ^/influxdb/?(.*) /$1 break;
+
+ proxy_pass http://localhost:8086;
+ proxy_redirect off;
+ }
+}
diff --git a/lib/influxdb-php-sdk/src/Adapter/AdapterAbstract.php b/lib/influxdb-php-sdk/src/Adapter/AdapterAbstract.php
new file mode 100644
index 0000000000..342b40bda7
--- /dev/null
+++ b/lib/influxdb-php-sdk/src/Adapter/AdapterAbstract.php
@@ -0,0 +1,31 @@
+options = $options;
+ }
+
+ public function getOptions()
+ {
+ return $this->options;
+ }
+
+ protected function getMessageDefaults()
+ {
+ return [
+ "database" => $this->getOptions()->getDatabase(),
+ "retentionPolicy" => $this->getOptions()->getRetentionPolicy(),
+ "tags" => $this->getOptions()->getTags(),
+ ];
+ }
+
+ abstract public function send(array $message);
+}
diff --git a/lib/influxdb-php-sdk/src/Adapter/GuzzleAdapter.php b/lib/influxdb-php-sdk/src/Adapter/GuzzleAdapter.php
new file mode 100644
index 0000000000..a7f4ca7a93
--- /dev/null
+++ b/lib/influxdb-php-sdk/src/Adapter/GuzzleAdapter.php
@@ -0,0 +1,81 @@
+httpClient = $httpClient;
+ }
+
+ public function send(array $message)
+ {
+ $message = array_replace_recursive($this->getMessageDefaults(), $message);
+
+ if (!count($message["tags"])) {
+ unset($message["tags"]);
+ }
+
+ $httpMessage = [
+ "auth" => [$this->getOptions()->getUsername(), $this->getOptions()->getPassword()],
+ 'query' => [
+ "db" => $message["database"],
+ "retentionPolicy" => $message["retentionPolicy"],
+ ],
+ "body" => message_to_inline_protocol($message)
+ ];
+
+ $endpoint = $this->getHttpSeriesEndpoint();
+ return $this->httpClient->post($endpoint, $httpMessage);
+ }
+
+ public function query($query)
+ {
+ $options = [
+ "auth" => [$this->getOptions()->getUsername(), $this->getOptions()->getPassword()],
+ 'query' => [
+ "q" => $query,
+ "db" => $this->getOptions()->getDatabase(),
+ ]
+ ];
+
+ return $this->get($options);
+ }
+
+ private function get(array $httpMessage)
+ {
+ $endpoint = $this->getHttpQueryEndpoint();
+ return json_decode($this->httpClient->get($endpoint, $httpMessage)->getBody(), true);
+ }
+
+ protected function getHttpSeriesEndpoint()
+ {
+ return $this->getHttpEndpoint("write");
+ }
+
+ protected function getHttpQueryEndpoint()
+ {
+ return $this->getHttpEndpoint("query");
+ }
+
+ private function getHttpEndpoint($operation)
+ {
+ $url = sprintf(
+ "%s://%s:%d%s/%s",
+ $this->getOptions()->getProtocol(),
+ $this->getOptions()->getHost(),
+ $this->getOptions()->getPort(),
+ $this->getOptions()->getPrefix(),
+ $operation
+ );
+
+ return $url;
+ }
+}
diff --git a/lib/influxdb-php-sdk/src/Adapter/QueryableInterface.php b/lib/influxdb-php-sdk/src/Adapter/QueryableInterface.php
new file mode 100644
index 0000000000..9ce4440dc3
--- /dev/null
+++ b/lib/influxdb-php-sdk/src/Adapter/QueryableInterface.php
@@ -0,0 +1,7 @@
+getMessageDefaults(), $message);
+
+ if (array_key_exists("tags", $message)) {
+ $message["tags"] = array_replace_recursive($this->getOptions()->getTags(), $message["tags"]);
+ }
+
+ $message = message_to_inline_protocol($message);
+
+ $this->write($message);
+ }
+
+ public function write($message)
+ {
+ // Create a handler in order to handle the 'Host is down' message
+ set_error_handler(function() {
+ // Suppress the error, this is the UDP adapter and if we can't send
+ // it then we shouldn't inturrupt their application.
+ });
+
+ $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
+ socket_sendto($socket, $message, strlen($message), 0, $this->getOptions()->getHost(), $this->getOptions()->getPort());
+ socket_close($socket);
+
+ // Remove our error handler.
+ restore_error_handler();
+ }
+}
diff --git a/lib/influxdb-php-sdk/src/Adapter/WritableInterface.php b/lib/influxdb-php-sdk/src/Adapter/WritableInterface.php
new file mode 100644
index 0000000000..8d5d7291c9
--- /dev/null
+++ b/lib/influxdb-php-sdk/src/Adapter/WritableInterface.php
@@ -0,0 +1,7 @@
+format("U") * 1e9);
+ }
+
+ $lines = [];
+ foreach ($message["points"] as $point) {
+ $tags = array_key_exists("tags", $message) ? $message["tags"] : [];
+ if (array_key_exists("tags", $point)) {
+ $tags = array_replace_recursive($tags, $point["tags"]);
+ }
+
+ if (!$tags) {
+ $lines[] = trim(
+ sprintf(
+ "%s %s %d",
+ $point["measurement"], list_to_string($point["fields"], true), $unixepoch
+ )
+ );
+ } else {
+ $lines[] = trim(
+ sprintf(
+ "%s,%s %s %d",
+ $point["measurement"], list_to_string($tags), list_to_string($point["fields"], true), $unixepoch
+ )
+ );
+ }
+ }
+
+ return implode("\n", $lines);
+}
+
+function list_to_string(array $elements, $escape = false)
+{
+ array_walk($elements, function(&$value, $key) use ($escape) {
+ if ($escape && is_string($value)) {
+ $value = "\"{$value}\"";
+ }
+
+ $value = "{$key}={$value}";
+ });
+
+ return implode(",", $elements);
+}
diff --git a/lib/influxdb-php-sdk/src/Client.php b/lib/influxdb-php-sdk/src/Client.php
new file mode 100644
index 0000000000..121d398914
--- /dev/null
+++ b/lib/influxdb-php-sdk/src/Client.php
@@ -0,0 +1,67 @@
+adapter = $adapter;
+ }
+
+ public function getAdapter()
+ {
+ return $this->adapter;
+ }
+
+ public function mark($name, array $values = [])
+ {
+ if (!($this->getAdapter() instanceOf WritableInterface)) {
+ throw new \BadMethodCallException("You can write data to database only if the adapter supports it!");
+ }
+
+ $data = $name;
+ if (!is_array($name)) {
+ $data =[];
+
+ $data['points'][0]['measurement'] = $name;
+ $data['points'][0]['fields'] = $values;
+ }
+
+ return $this->getAdapter()->send($data);
+ }
+
+ public function query($query)
+ {
+ if (!($this->getAdapter() instanceOf QueryableInterface)) {
+ throw new \BadMethodCallException("You can query the database only if the adapter supports it!");
+ }
+
+ $return = $this->getAdapter()->query($query);
+
+ return $return;
+ }
+
+ public function getDatabases()
+ {
+ return $this->getAdapter()->query("show databases");
+ }
+
+ public function createDatabase($name)
+ {
+ return $this->getAdapter()->query("create database \"{$name}\"");
+ }
+
+ public function deleteDatabase($name)
+ {
+ return $this->getAdapter()->query("drop database \"{$name}\"");
+ }
+}
diff --git a/lib/influxdb-php-sdk/src/ClientFactory.php b/lib/influxdb-php-sdk/src/ClientFactory.php
new file mode 100644
index 0000000000..690dbbd329
--- /dev/null
+++ b/lib/influxdb-php-sdk/src/ClientFactory.php
@@ -0,0 +1,51 @@
+ [
+ "name" => false,
+ "options" => [],
+ ],
+ "options" => [],
+ ];
+ $options = array_replace_recursive($defaultOptions, $options);
+
+ $adapterOptions = new Options();
+
+ $hydrator = new ClassMethods();
+ $hydrator->hydrate($options["options"], $adapterOptions);
+
+ $adapter = null;
+ $adapterName = $options["adapter"]["name"];
+ switch ($adapterName) {
+ case 'InfluxDB\\Adapter\\UdpAdapter':
+ $adapter = new $adapterName($adapterOptions);
+ break;
+ case 'InfluxDB\\Adapter\\GuzzleAdapter':
+ $adapter = new $adapterName(new GuzzleClient($options["adapter"]["options"]), $adapterOptions);
+ break;
+ default:
+ throw new \InvalidArgumentException("Missing adapter {$adapter}");
+ }
+
+ $client = new Client($adapter);
+
+ return $client;
+ }
+}
diff --git a/lib/influxdb-php-sdk/src/Options.php b/lib/influxdb-php-sdk/src/Options.php
new file mode 100644
index 0000000000..15b1581f24
--- /dev/null
+++ b/lib/influxdb-php-sdk/src/Options.php
@@ -0,0 +1,142 @@
+setHost("localhost");
+ $this->setPort(8086);
+ $this->setUsername("root");
+ $this->setPassword("root");
+ $this->setProtocol("http");
+ $this->setPrefix("");
+
+ $this->setRetentionPolicy("default");
+ $this->setTags([]);
+ }
+
+ public function getPrefix()
+ {
+ return $this->prefix;
+ }
+
+ public function setPrefix($prefix)
+ {
+ $this->prefix = $prefix;
+ return $this;
+ }
+
+ public function getTags()
+ {
+ return $this->tags;
+ }
+
+ public function setTags($tags)
+ {
+ $this->tags = $tags;
+ return $this;
+ }
+
+ public function getRetentionPolicy()
+ {
+ return $this->retentionPolicy;
+ }
+
+ public function setRetentionPolicy($retentionPolicy)
+ {
+ $this->retentionPolicy = $retentionPolicy;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ 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;
+ }
+}
diff --git a/lib/influxdb-php-sdk/tests/integration/Adapter/GuzzleAdapterTest.php b/lib/influxdb-php-sdk/tests/integration/Adapter/GuzzleAdapterTest.php
new file mode 100644
index 0000000000..eed5132c1d
--- /dev/null
+++ b/lib/influxdb-php-sdk/tests/integration/Adapter/GuzzleAdapterTest.php
@@ -0,0 +1,72 @@
+getClient()->createDatabase("tcp.test");
+
+ $options = new Options();
+ $options->setPort(8086);
+ $options->setDatabase("tcp.test");
+
+ $http = new GuzzleHttpClient();
+ $adapter = new GuzzleAdapter($http, $options);
+
+ $adapter->send([
+ "points" => [
+ [
+ "measurement" => "vm-serie",
+ "fields" => [
+ "cpu" => 18.12,
+ "free" => 712423,
+ ],
+ ],
+ ]
+ ]);
+
+ $this->assertSerieExists("tcp.test", "vm-serie");
+ $this->assertSerieCount("tcp.test", "vm-serie", 1);
+ $this->assertValueExistsInSerie("tcp.test", "vm-serie", "cpu", 18.12);
+ $this->assertValueExistsInSerie("tcp.test", "vm-serie", "free", 712423);
+ }
+
+ public function testWorksWithProxies()
+ {
+ $this->getClient()->createDatabase("proxy.test");
+
+ $options = new Options();
+ $options->setPort(9000);
+ $options->setDatabase("proxy.test");
+ $options->setPrefix("/influxdb");
+
+ $http = new GuzzleHttpClient();
+ $adapter = new GuzzleAdapter($http, $options);
+
+ $adapter->send([
+ "points" => [
+ [
+ "measurement" => "vm-serie",
+ "fields" => [
+ "cpu" => 18.12,
+ "free" => 712423,
+ ],
+ ],
+ ]
+ ]);
+
+ $this->assertSerieExists("proxy.test", "vm-serie");
+ $this->assertSerieCount("proxy.test", "vm-serie", 1);
+ $this->assertValueExistsInSerie("proxy.test", "vm-serie", "cpu", 18.12);
+ $this->assertValueExistsInSerie("proxy.test", "vm-serie", "free", 712423);
+ }
+}
diff --git a/lib/influxdb-php-sdk/tests/integration/Adapter/UdpAdapterTest.php b/lib/influxdb-php-sdk/tests/integration/Adapter/UdpAdapterTest.php
new file mode 100644
index 0000000000..33c1c89044
--- /dev/null
+++ b/lib/influxdb-php-sdk/tests/integration/Adapter/UdpAdapterTest.php
@@ -0,0 +1,55 @@
+setPort(4444);
+ $adapter = new UdpAdapter($options);
+
+ $this->getClient()->createDatabase("udp.test");
+
+ $adapter->write("cpu value=12.33 " . (int)(microtime(true)*1e9));
+
+ sleep(2);
+
+ $this->assertSerieExists("udp.test", "cpu");
+ $this->assertSerieCount("udp.test", "cpu", 1);
+ $this->assertValueExistsInSerie("udp.test", "cpu", "value", 12.33);
+ }
+
+ public function testWriteSimplePointsUsingSendMethod()
+ {
+ $options = (new Options())
+ ->setPort(4444);
+ $adapter = new UdpAdapter($options);
+
+ $this->getClient()->createDatabase("udp.test");
+
+ $adapter->send([
+ "retentionPolicy" => "default",
+ "points" => [
+ [
+ "measurement" => "mem",
+ "fields" => [
+ "value" => 1233,
+ "with_string" => "this is a string",
+ ],
+ ],
+ ],
+ ]);
+
+ sleep(2);
+
+ $this->assertSerieExists("udp.test", "mem");
+ $this->assertSerieCount("udp.test", "mem", 1);
+ $this->assertValueExistsInSerie("udp.test", "mem", "value", 1233);
+ $this->assertValueExistsInSerie("udp.test", "mem", "with_string", "this is a string");
+ }
+}
diff --git a/lib/influxdb-php-sdk/tests/integration/ClientTest.php b/lib/influxdb-php-sdk/tests/integration/ClientTest.php
new file mode 100644
index 0000000000..1b56232e6b
--- /dev/null
+++ b/lib/influxdb-php-sdk/tests/integration/ClientTest.php
@@ -0,0 +1,166 @@
+getClient()->createDatabase("tcp.test");
+ $this->getClient()->createDatabase("udp.test");
+ }
+
+ public function testSimpleMarkPublicSignature()
+ {
+ $options = new Options();
+ $options->setDatabase("tcp.test");
+
+ $guzzleHttp = new GuzzleHttpClient();
+ $adapter = new InfluxHttpAdapter($guzzleHttp, $options);
+ $client = new Client($adapter);
+
+ $client->mark("vm", ["mark" => "element"]);
+
+ $this->assertSerieExists("tcp.test", "vm");
+ $this->assertSerieCount("tcp.test", "vm", 1);
+ $this->assertValueExistsInSerie("tcp.test", "vm", "mark", "element");
+ }
+
+ public function testDirectMessagesMarkPublicSignature()
+ {
+ $options = new Options();
+ $options->setDatabase("tcp.test");
+
+ $guzzleHttp = new GuzzleHttpClient();
+ $adapter = new InfluxHttpAdapter($guzzleHttp, $options);
+ $client = new Client($adapter);
+
+ $client->mark([
+ "database" => "tcp.test",
+ "retentionPolicy" => "default",
+ "points" => [
+ [
+ "measurement" => "tt",
+ "fields" => [
+ "cpu" => 1,
+ "mem" => 2,
+ ],
+ ]
+ ],
+ ]);
+
+ $this->assertSerieExists("tcp.test", "tt");
+ $this->assertSerieCount("tcp.test", "tt", 1);
+ $this->assertValueExistsInSerie("tcp.test", "tt", "cpu", 1);
+ $this->assertValueExistsInSerie("tcp.test", "tt", "mem", 2);
+ }
+
+ public function testListActiveDatabases()
+ {
+ $options = new Options();
+ $guzzleHttp = new GuzzleHttpClient();
+ $adapter = new InfluxHttpAdapter($guzzleHttp, $options);
+ $client = new Client($adapter);
+
+ $databases = $client->getDatabases();
+
+ $this->assertCount(2, $databases["results"][0]["series"][0]["values"]);
+ }
+
+ public function testCreateANewDatabase()
+ {
+ $options = new Options();
+ $guzzleHttp = new GuzzleHttpClient();
+ $adapter = new InfluxHttpAdapter($guzzleHttp, $options);
+
+ $client = new Client($adapter);
+
+ $client->createDatabase("walter");
+
+ $databases = $client->getDatabases();
+
+ $this->assertCount(3, $databases["results"][0]["series"][0]["values"]);
+ }
+
+ public function testDropExistingDatabase()
+ {
+ $options = new Options();
+ $guzzleHttp = new GuzzleHttpClient();
+ $adapter = new InfluxHttpAdapter($guzzleHttp, $options);
+
+ $client = new Client($adapter);
+
+ $client->createDatabase("walter");
+ $this->assertDatabasesCount(3);
+
+ $client->deleteDatabase("walter");
+ $this->assertDatabasesCount(2);
+ }
+
+ /**
+ * Test that we handle socket problems correctly in the UDP
+ * adapter, and that they don't inturrupt the user's application.
+ *
+ * @group udp
+ */
+ public function testReplicateIssue27()
+ {
+ $options = new \InfluxDB\Options();
+
+ // Configure options
+ $options->setHost('172.16.1.182');
+ $options->setPort(4444);
+ $options->setDatabase('...');
+ $options->setUsername('root');
+ $options->setPassword('root');
+
+ $httpAdapter = new \InfluxDB\Adapter\UdpAdapter($options);
+
+ $client = new \InfluxDB\Client($httpAdapter);
+ $client->mark("udp.test", ["mark" => "element"]);
+ }
+
+ /**
+ * @group udp
+ */
+ public function testWriteUDPPackagesToNoOne()
+ {
+ $options = new Options();
+ $options->setHost("127.0.0.1");
+ $options->setUsername("nothing");
+ $options->setPassword("nothing");
+ $options->setPort(64071); //This is a wrong port
+
+ $adapter = new UdpAdapter($options);
+ $object = new Client($adapter);
+
+ $object->mark("udp.test", ["mark" => "element"]);
+ }
+
+ /**
+ * @group udp
+ */
+ public function testWriteUDPPackagesToInvalidHostname()
+ {
+ $options = new Options();
+ $options->setHost("www.test-invalid.this-is-not-a-tld");
+ $options->setUsername("nothing");
+ $options->setPassword("nothing");
+ $options->setPort(15984);
+
+ $adapter = new UdpAdapter($options);
+ $object = new Client($adapter);
+
+ $object->mark("udp.test", ["mark" => "element"]);
+ }
+}
diff --git a/lib/influxdb-php-sdk/tests/integration/Framework/TestCase.php b/lib/influxdb-php-sdk/tests/integration/Framework/TestCase.php
new file mode 100644
index 0000000000..6f6d151070
--- /dev/null
+++ b/lib/influxdb-php-sdk/tests/integration/Framework/TestCase.php
@@ -0,0 +1,91 @@
+options = new Options();
+ $guzzleHttp = new GuzzleHttpClient();
+ $adapter = new InfluxHttpAdapter($guzzleHttp, $options);
+
+ $client = $this->client = new Client($adapter);
+
+ $this->dropAll();
+ }
+
+ public function tearDown()
+ {
+ $this->dropAll();
+ }
+
+ private function dropAll()
+ {
+ $databases = $this->getClient()->getDatabases();
+ if (array_key_exists("values", $databases["results"][0]["series"][0])) {
+ foreach ($databases["results"][0]["series"][0]["values"] as $database) {
+ $this->getClient()->deleteDatabase($database[0]);
+ }
+ }
+ }
+
+ public function assertValueExistsInSerie($database, $serieName, $column, $value)
+ {
+ $this->getOptions()->setDatabase($database);
+ $body = $this->getClient()->query("select {$column} from \"{$serieName}\"");
+
+ foreach ($body["results"][0]["series"][0]["values"] as $result) {
+ if ($result[1] == $value) {
+ return $this->assertTrue(true);
+ }
+ }
+
+ return $this->fail("Missing value '{$value}'");
+ }
+
+ public function assertSerieCount($database, $serieName, $count)
+ {
+ $this->getOptions()->setDatabase($database);
+ $body = $this->getClient()->query("select * from \"{$serieName}\"");
+
+ $this->assertCount(1, $body["results"][0]["series"][0]["values"]);
+ }
+
+ public function assertSerieExists($database, $serieName)
+ {
+ $this->getOptions()->setDatabase($database);
+ $body = $this->getClient()->query("show measurements");
+
+ foreach ($body["results"][0]["series"][0]["values"] as $result) {
+ if ($result[0] == $serieName) {
+ return $this->assertTrue(true);
+ }
+ }
+
+ return $this->fail("Missing serie with name '{$serieName}' in database '{$database}'");
+ }
+
+ public function assertDatabasesCount($count)
+ {
+ $databases = $this->client->getDatabases();
+ $this->assertCount($count, $databases["results"][0]["series"][0]["values"]);
+ }
+
+ public function getOptions()
+ {
+ return $this->options;
+ }
+
+ public function getClient()
+ {
+ return $this->client;
+ }
+}
diff --git a/lib/influxdb-php-sdk/tests/unit/Adapter/GuzzleAdapterTest.php b/lib/influxdb-php-sdk/tests/unit/Adapter/GuzzleAdapterTest.php
new file mode 100644
index 0000000000..57aaf5b724
--- /dev/null
+++ b/lib/influxdb-php-sdk/tests/unit/Adapter/GuzzleAdapterTest.php
@@ -0,0 +1,225 @@
+getMethod("getHttpSeriesEndpoint");
+ $method->setAccessible(true);
+
+ $endpoint = $method->invokeArgs($adapter, []);
+ $this->assertEquals($final, $endpoint);
+ }
+
+ public function getWriteEndpoints()
+ {
+ return [
+ ["http://localhost:9000/write", (new Options())->setHost("localhost")->setPort(9000)],
+ ["https://localhost:9000/write", (new Options())->setHost("localhost")->setPort(9000)->setProtocol("https")],
+ ["http://localhost:9000/influxdb/write", (new Options())->setHost("localhost")->setPort(9000)->setPrefix("/influxdb")],
+ ];
+ }
+
+ /**
+ * @group tcp
+ * @group proxy
+ * @dataProvider getQueryEndpoints
+ */
+ public function testQueryEndpointGeneration($final, $options)
+ {
+ $guzzleHttp = new GuzzleHttpClient();
+ $adapter = new InfluxHttpAdapter($guzzleHttp, $options);
+
+ $reflection = new \ReflectionClass(get_class($adapter));
+ $method = $reflection->getMethod("getHttpQueryEndpoint");
+ $method->setAccessible(true);
+
+ $endpoint = $method->invokeArgs($adapter, []);
+ $this->assertEquals($final, $endpoint);
+ }
+
+ public function getQueryEndpoints()
+ {
+ return [
+ ["http://localhost:9000/query", (new Options())->setHost("localhost")->setPort(9000)],
+ ["https://localhost:9000/query", (new Options())->setHost("localhost")->setPort(9000)->setProtocol("https")],
+ ["http://localhost:9000/influxdb/query", (new Options())->setHost("localhost")->setPort(9000)->setPrefix("/influxdb")],
+ ];
+ }
+
+ public function testMergeWithDefaultOptions()
+ {
+ $options = new Options();
+ $options->setDatabase("db");
+ $httpClient = $this->prophesize("GuzzleHttp\\Client");
+ $httpClient->post(Argument::Any(), [
+ "auth" => ["root", "root"],
+ "query" => [
+ "db" => "db",
+ "retentionPolicy" => "default",
+ ],
+ "body" => null,
+ ])->shouldBeCalledTimes(1);
+
+ $adapter = new InfluxHttpAdapter($httpClient->reveal(), $options);
+ $adapter->send([]);
+ }
+
+ public function testAdapterPrepareJsonDataCorrectly()
+ {
+ $guzzleHttp = $this->prophesize("GuzzleHttp\Client");
+ $guzzleHttp->post("http://localhost:8086/write", [
+ "auth" => ["root", "root"],
+ "query" => [
+ "db" => "db",
+ "retentionPolicy" => "default",
+ ],
+ "body" => 'tcp.test mark="element" 1257894000000000000',
+ ])->shouldBeCalledTimes(1);
+ $options = (new Options())->setDatabase("db");
+ $adapter = new InfluxHttpAdapter($guzzleHttp->reveal(), $options);
+
+ $adapter->send([
+ "time" => "2009-11-10T23:00:00Z",
+ "points" => [
+ [
+ "measurement" => "tcp.test",
+ "fields" => [
+ "mark" => "element"
+ ]
+ ]
+ ]
+ ]);
+ }
+
+ public function testDefaultOptionOverwrite()
+ {
+ $options = new Options();
+ $options->setDatabase("db");
+ $httpClient = $this->prophesize("GuzzleHttp\\Client");
+ $httpClient->post(Argument::Any(), [
+ "auth" => ["root", "root"],
+ "query" => [
+ "db" => "mydb",
+ "retentionPolicy" => "myPolicy",
+ ],
+ "body" => null,
+ ])->shouldBeCalledTimes(1);
+
+ $adapter = new InfluxHttpAdapter($httpClient->reveal(), $options);
+ $adapter->send([
+ "database" => "mydb",
+ "retentionPolicy" => "myPolicy"
+ ]);
+ }
+
+ public function testEmptyTagsFieldIsRemoved()
+ {
+ $options = new Options();
+ $options->setDatabase("db");
+ $httpClient = $this->prophesize("GuzzleHttp\\Client");
+ $httpClient->post(Argument::Any(), [
+ "auth" => ["root", "root"],
+ "query" => [
+ "db" => "db",
+ "retentionPolicy" => "default",
+ ],
+ "body" => 'tcp.test mark="element" 1257894000000000000',
+ ])->shouldBeCalledTimes(1);
+
+ $adapter = new InfluxHttpAdapter($httpClient->reveal(), $options);
+ $adapter->send([
+ "time" => "2009-11-10T23:00:00Z",
+ "points" => [
+ [
+ "measurement" => "tcp.test",
+ "fields" => [
+ "mark" => "element"
+ ]
+ ]
+ ]
+ ]);
+ }
+
+ public function testGlobalTagsAreInPlace()
+ {
+ $options = new Options();
+ $options->setDatabase("db");
+ $options->setTags([
+ "dc" => "us-west",
+ ]);
+ $httpClient = $this->prophesize("GuzzleHttp\\Client");
+ $httpClient->post(Argument::Any(), [
+ "auth" => ["root", "root"],
+ "query" => [
+ "db" => "db",
+ "retentionPolicy" => "default",
+ ],
+ "body" => 'tcp.test,dc=us-west mark="element" 1257894000000000000',
+ ])->shouldBeCalledTimes(1);
+
+ $adapter = new InfluxHttpAdapter($httpClient->reveal(), $options);
+ $adapter->send([
+ "time" => "2009-11-10T23:00:00Z",
+ "points" => [
+ [
+ "measurement" => "tcp.test",
+ "fields" => [
+ "mark" => "element"
+ ]
+ ]
+ ]
+ ]);
+ }
+
+ public function testTagsFieldIsMergedWithGlobalTags()
+ {
+ $options = new Options();
+ $options->setDatabase("db");
+ $options->setTags([
+ "dc" => "us-west",
+ ]);
+ $httpClient = $this->prophesize("GuzzleHttp\\Client");
+ $httpClient->post(Argument::Any(), [
+ "auth" => ["root", "root"],
+ "query" => [
+ "db" => "db",
+ "retentionPolicy" => "default",
+ ],
+ "body" => 'tcp.test,dc=us-west,region=us mark="element" 1257894000000000000',
+ ])->shouldBeCalledTimes(1);
+
+ $adapter = new InfluxHttpAdapter($httpClient->reveal(), $options);
+ $adapter->send([
+ "time" => "2009-11-10T23:00:00Z",
+ "tags" => ["region" => "us"],
+ "points" => [
+ [
+ "measurement" => "tcp.test",
+ "fields" => [
+ "mark" => "element"
+ ]
+ ]
+ ]
+ ]);
+ }
+}
diff --git a/lib/influxdb-php-sdk/tests/unit/Adapter/HelpersTest.php b/lib/influxdb-php-sdk/tests/unit/Adapter/HelpersTest.php
new file mode 100644
index 0000000000..cc3776413f
--- /dev/null
+++ b/lib/influxdb-php-sdk/tests/unit/Adapter/HelpersTest.php
@@ -0,0 +1,23 @@
+assertEquals($result, list_to_string($message, $escape));
+ }
+
+ public function getElements()
+ {
+ return [
+ [["one" => "two"], "one=two", false],
+ [["one" => "two"], "one=\"two\"", true],
+ [["one" => "two", "three" => "four"], "one=two,three=four", false],
+ [["one" => "two", "three" => "four"], "one=\"two\",three=\"four\"", true],
+ ];
+ }
+}
diff --git a/lib/influxdb-php-sdk/tests/unit/Adapter/UdpAdapterTest.php b/lib/influxdb-php-sdk/tests/unit/Adapter/UdpAdapterTest.php
new file mode 100644
index 0000000000..68271bac49
--- /dev/null
+++ b/lib/influxdb-php-sdk/tests/unit/Adapter/UdpAdapterTest.php
@@ -0,0 +1,299 @@
+getMockBuilder("InfluxDB\Adapter\UdpAdapter")
+ ->setConstructorArgs([new Options()])
+ ->setMethods(["write"])
+ ->getMock();
+ $object->expects($this->once())
+ ->method("write")
+ ->with($response);
+
+ $object->send($input);
+ }
+
+ public function getMessages()
+ {
+ return [
+ [
+ [
+ "time" => "2009-11-10T23:00:00Z",
+ "points" => [
+ [
+ "measurement" => "cpu",
+ "fields" => [
+ "value" => 1,
+ ],
+ ],
+ ],
+ ],
+ "cpu value=1 1257894000000000000"
+ ],
+ [
+ [
+ "time" => "2009-11-10T23:00:00Z",
+ "points" => [
+ [
+ "measurement" => "cpu",
+ "fields" => [
+ "value" => 1,
+ "string" => "escape",
+ ],
+ ],
+ ],
+ ],
+ "cpu value=1,string=\"escape\" 1257894000000000000"
+ ],
+ [
+ [
+ "tags" => [
+ "region" => "us-west",
+ "host" => "serverA",
+ "env" => "prod",
+ "target" => "servers",
+ "zone" => "1c",
+ ],
+ "time" => "2009-11-10T23:00:00Z",
+ "points" => [
+ [
+ "measurement" => "cpu",
+ "fields" => [
+ "cpu" => 18.12,
+ "free" => 712432,
+ ],
+ ],
+ ],
+ ],
+ "cpu,region=us-west,host=serverA,env=prod,target=servers,zone=1c cpu=18.12,free=712432 1257894000000000000"
+ ],
+ [
+ [
+ "tags" => [
+ "region" => "us-west",
+ "host" => "serverA",
+ "env" => "prod",
+ "target" => "servers",
+ "zone" => "1c",
+ ],
+ "time" => "2009-11-10T23:00:00Z",
+ "points" => [
+ [
+ "measurement" => "cpu",
+ "fields" => [
+ "cpu" => 18.12,
+ ],
+ ],
+ [
+ "measurement" => "mem",
+ "fields" => [
+ "free" => 712432,
+ ],
+ ],
+ ],
+ ],
+ <<setDatabase("test");
+ $adapter = $this->getMockBuilder("InfluxDB\\Adapter\\UdpAdapter")
+ ->setConstructorArgs([$options])
+ ->setMethods(["write", "generateTimeInNanoSeconds"])
+ ->getMock();
+
+ $adapter->expects($this->any())
+ ->method("generateTimeInNanoSeconds")
+ ->will($this->returnValue(1245));
+
+ $adapter->expects($this->once())
+ ->method("write")
+ ->with($this->matchesRegularExpression("/udp.test mark=\"element\" \d+/i"));
+
+ $adapter->send([
+ "points" => [
+ [
+ "measurement" => "udp.test",
+ "fields" => [
+ "mark" => "element"
+ ]
+ ]
+ ]
+ ]);
+ }
+
+ /**
+ * @group udp
+ */
+ public function testSendMultipleMeasurementWithUdpIp()
+ {
+ $options = (new Options())->setDatabase("test");
+ $adapter = $this->getMockBuilder("InfluxDB\\Adapter\\UdpAdapter")
+ ->setConstructorArgs([$options])
+ ->setMethods(["write", "generateTimeInNanoSeconds"])
+ ->getMock();
+
+ $adapter->expects($this->any())
+ ->method("generateTimeInNanoSeconds")
+ ->will($this->onConsecutiveCalls(1245, 1246));
+
+ $adapter->expects($this->once())
+ ->method("write")
+ ->with($this->matchesRegularExpression(<<send([
+ "points" => [
+ [
+ "measurement" => "mem",
+ "fields" => [
+ "free" => 712423,
+ ],
+ ],
+ [
+ "measurement" => "cpu",
+ "fields" => [
+ "cpu" => 18.12,
+ ],
+ ],
+ ]
+ ]);
+ }
+
+ /**
+ * @group udp
+ */
+ public function testFillWithGlobalTags()
+ {
+ $options = (new Options())
+ ->setDatabase("test")
+ ->setTags(["dc" => "eu-west"]);
+ $adapter = $this->getMockBuilder("InfluxDB\\Adapter\\UdpAdapter")
+ ->setConstructorArgs([$options])
+ ->setMethods(["write"])
+ ->getMock();
+
+ $adapter->expects($this->once())
+ ->method("write")
+ ->with($this->matchesRegularExpression("/mem,dc=eu-west free=712423 \d+/i"));
+
+ $adapter->send([
+ "points" => [
+ [
+ "measurement" => "mem",
+ "fields" => [
+ "free" => 712423,
+ ],
+ ],
+ ]
+ ]);
+ }
+
+ /**
+ * @group udp
+ */
+ public function testMergeGlobalTags()
+ {
+ $options = (new Options())
+ ->setDatabase("test")
+ ->setTags(["dc" => "eu-west"]);
+ $adapter = $this->getMockBuilder("InfluxDB\\Adapter\\UdpAdapter")
+ ->setConstructorArgs([$options])
+ ->setMethods(["write", "generateTimeInNanoSeconds"])
+ ->getMock();
+
+ $adapter->expects($this->any())
+ ->method("generateTimeInNanoSeconds")
+ ->will($this->returnValue(1245));
+
+ $adapter->expects($this->once())
+ ->method("write")
+ ->with($this->matchesRegularExpression(<<send([
+ "tags" => [
+ "region" => "eu-west-1",
+ ],
+ "points" => [
+ [
+ "measurement" => "mem",
+ "fields" => [
+ "free" => 712423,
+ ],
+ ],
+ ]
+ ]);
+ }
+
+ /**
+ * @group udp
+ */
+ public function testMergeFullTagsPositions()
+ {
+ $options = (new Options())
+ ->setDatabase("test")
+ ->setTags(["dc" => "eu-west"]);
+ $adapter = $this->getMockBuilder("InfluxDB\\Adapter\\UdpAdapter")
+ ->setConstructorArgs([$options])
+ ->setMethods(["write", "generateTimeInNanoSeconds"])
+ ->getMock();
+
+ $adapter->expects($this->any())
+ ->method("generateTimeInNanoSeconds")
+ ->will($this->returnValue(1245));
+
+ $adapter->expects($this->once())
+ ->method("write")
+ ->with($this->matchesRegularExpression(<<send([
+ "tags" => [
+ "region" => "eu-west-1",
+ ],
+ "points" => [
+ [
+ "measurement" => "mem",
+ "tags" => [
+ "location" => "ireland",
+ ],
+ "fields" => [
+ "free" => 712423,
+ ],
+ ],
+ ]
+ ]);
+ }
+}
diff --git a/lib/influxdb-php-sdk/tests/unit/ClientFactoryTest.php b/lib/influxdb-php-sdk/tests/unit/ClientFactoryTest.php
new file mode 100644
index 0000000000..8143b00bf0
--- /dev/null
+++ b/lib/influxdb-php-sdk/tests/unit/ClientFactoryTest.php
@@ -0,0 +1,135 @@
+ ["name" => "UdpAdapter"]]);
+ }
+
+ /**
+ * @group factory
+ * @group udp
+ */
+ public function testCreateUdpClient()
+ {
+ $options = [
+ "adapter" => [
+ "name" => "InfluxDB\\Adapter\\UdpAdapter",
+ ],
+ "options" => [
+ "host" => "127.0.0.1",
+ "username" => "user",
+ "password" => "pass",
+ ],
+ ];
+
+ $client = ClientFactory::create($options);
+ $this->assertInstanceOf("InfluxDB\\Client", $client);
+
+ $this->assertInstanceOf("InfluxDB\\Adapter\\UdpAdapter", $client->getAdapter());
+ $this->assertEquals("127.0.0.1", $client->getAdapter()->getOptions()->getHost());
+ $this->assertEquals("user", $client->getAdapter()->getOptions()->getUsername());
+ $this->assertEquals("pass", $client->getAdapter()->getOptions()->getPassword());
+ }
+
+ /**
+ * @group factory
+ * @group tcp
+ * @dataProvider getHttpAdapters
+ */
+ public function testCreateTcpClient($adapter)
+ {
+ $options = [
+ "adapter" => [
+ "name" => $adapter,
+ ],
+ "options" => [
+ "host" => "127.0.0.1",
+ "username" => "user",
+ "password" => "pass",
+ ],
+ ];
+
+ $client = ClientFactory::create($options);
+ $this->assertInstanceOf("InfluxDB\\Client", $client);
+
+ $this->assertInstanceOf($adapter, $client->getAdapter());
+ $this->assertEquals("127.0.0.1", $client->getAdapter()->getOptions()->getHost());
+ $this->assertEquals("user", $client->getAdapter()->getOptions()->getUsername());
+ $this->assertEquals("pass", $client->getAdapter()->getOptions()->getPassword());
+ }
+
+ /**
+ * @group factory
+ * @dataProvider getHttpAdapters
+ */
+ public function testCreateTcpClientWithAllOptions($adapter)
+ {
+ $options = [
+ "adapter" => [
+ "name" => $adapter,
+ ],
+ "options" => [
+ "host" => "127.0.0.1",
+ "username" => "user",
+ "password" => "pass",
+ "retention_policy" => "too_many_data",
+ "tags" => [
+ "region" => "eu",
+ "env" => "prod",
+ ],
+ ],
+ ];
+
+ $client = ClientFactory::create($options);
+ $this->assertInstanceOf("InfluxDB\\Client", $client);
+
+ $this->assertInstanceOf($adapter, $client->getAdapter());
+ $this->assertEquals("127.0.0.1", $client->getAdapter()->getOptions()->getHost());
+ $this->assertEquals("user", $client->getAdapter()->getOptions()->getUsername());
+ $this->assertEquals("pass", $client->getAdapter()->getOptions()->getPassword());
+ $this->assertEquals(["region" => "eu", "env" => "prod"], $client->getAdapter()->getOptions()->getTags());
+ $this->assertEquals("too_many_data", $client->getAdapter()->getOptions()->getRetentionPolicy());
+ }
+
+ public function getHttpAdapters()
+ {
+ return [
+ ["InfluxDB\\Adapter\\GuzzleAdapter"],
+ ];
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ * @dataProvider getInvalidClasses
+ */
+ public function testInvalidProviderThrowsException($class)
+ {
+ $client = ClientFactory::create([
+ "adapter" => [
+ "name" => $class,
+ ],
+ ]);
+ }
+
+ public function getInvalidClasses()
+ {
+ return [["InvalidClass"],["stdClass"]];
+ }
+}
diff --git a/lib/influxdb-php-sdk/tests/unit/ClientTest.php b/lib/influxdb-php-sdk/tests/unit/ClientTest.php
new file mode 100644
index 0000000000..da6586ec52
--- /dev/null
+++ b/lib/influxdb-php-sdk/tests/unit/ClientTest.php
@@ -0,0 +1,83 @@
+prophesize("InfluxDB\\Adapter\\WritableInterface");
+ $mock->send([
+ "points" => [
+ [
+ "measurement" => "tcp.test",
+ "fields" => [
+ "mark" => "element"
+ ]
+ ]
+ ]
+ ])->shouldBeCalledTimes(1);
+
+ $object = new Client($mock->reveal());
+ $object->mark("tcp.test", ["mark" => "element"]);
+ }
+
+ public function testWriteDirectMessages()
+ {
+ $mock = $this->prophesize("InfluxDB\\Adapter\\WritableInterface");
+ $mock->send([
+ "tags" => [
+ "dc" => "eu-west-1",
+ ],
+ "points" => [
+ [
+ "measurement" => "vm-serie",
+ "fields" => [
+ "cpu" => 18.12,
+ "free" => 712423,
+ ]
+ ]
+ ]
+ ])->shouldBeCalledTimes(1);
+ $object = new Client($mock->reveal());
+
+ $object->mark([
+ "tags" => [
+ "dc" => "eu-west-1",
+ ],
+ "points" => [
+ [
+ "measurement" => "vm-serie",
+ "fields" => [
+ "cpu" => 18.12,
+ "free" => 712423,
+ ],
+ ],
+ ]
+ ]);
+ }
+
+ /**
+ * @expectedException BadMethodCallException
+ */
+ public function testNeedWritableInterfaceDuringMark()
+ {
+ $client = new Client(new \stdClass());
+ $client->mark("OK", []);
+ }
+
+ /**
+ * @expectedException BadMethodCallException
+ */
+ public function testNeedQueryableInterfaceDuringQuery()
+ {
+ $client = new Client(new \stdClass());
+ $client->query("OK", []);
+ }
+}