mirror of
https://github.com/stylersnico/librenms.git
synced 2026-07-28 00:24:21 +02:00
Merge pull request #29 from corley/feature/influxdb-0.9
Support InfluxDB v0.9 Actually Release Candidate 33 is supported
This commit is contained in:
+18
-15
@@ -1,23 +1,26 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 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
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install libcurl4-openssl-dev libjson0-dev
|
||||
- wget http://get.influxdb.org/influxdb_0.9.0-rc33_amd64.deb
|
||||
- sudo useradd influxdb
|
||||
- sudo dpkg -i influxdb_0.9.0-rc33_amd64.deb
|
||||
- sudo cp ./scripts/influxdb_conf.toml /etc/opt/influxdb/influxdb.conf
|
||||
- travis_retry sudo service influxdb restart
|
||||
- sudo service influxdb status
|
||||
|
||||
before_script:
|
||||
- composer selfupdate
|
||||
- composer install --prefer-source
|
||||
- composer selfupdate
|
||||
- composer install --prefer-source
|
||||
|
||||
script:
|
||||
- vendor/bin/phpspec run -n
|
||||
- vendor/bin/phpunit
|
||||
- vendor/bin/phpunit
|
||||
|
||||
notifications:
|
||||
slack:
|
||||
secure: UN4V33CfLzEcb+5/LWcfcbwROZobbUawgFSiM3TzagBC+7w0DH2rK8DczxkUBs5rNAaYBj+DkxmmF9tiDb0BLB7Jezlq0vmrNBOhregLodOG44/bFwg58YOwTGxt/Iak38A+8VskGj0sSybNq4TB1/K0040wXS5bA+M/9NqyQeo=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2014 Corley S.r.l.
|
||||
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
|
||||
|
||||
@@ -7,6 +7,13 @@
|
||||
|
||||
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
|
||||
@@ -34,22 +41,41 @@ $client->mark("app.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");
|
||||
$results = $client->query('select * from "app.search"');
|
||||
```
|
||||
|
||||
## InfluxDB client adapters
|
||||
|
||||
Actually we supports two adapters
|
||||
Actually we supports two network adapters
|
||||
|
||||
* UDP/IP - in order to send data via UDP (datagram)
|
||||
* HTTP JSON - in order to send/retrieve using HTTP (connection oriented)
|
||||
* 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.
|
||||
|
||||
To verify if you have the `sockets` extension just issue a:
|
||||
@@ -60,8 +86,9 @@ 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.
|
||||
- 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`
|
||||
@@ -83,23 +110,16 @@ Actually Guzzle is used as HTTP client library
|
||||
|
||||
```php
|
||||
<?php
|
||||
$http = new \GuzzleHttp\Client();
|
||||
|
||||
$options = new Options();
|
||||
$adapter = new HttpAdapter($options);
|
||||
$adapter = new GuzzleAdapter($http, $options);
|
||||
|
||||
$client = new Client();
|
||||
$client->setAdapter($adapter);
|
||||
```
|
||||
|
||||
#### Supported types of exceptions
|
||||
|
||||
* InfluxGeneralException
|
||||
* InfluxAuthorizationException (extends InfluxGeneralException)
|
||||
* InfluxBadResponseException (extends InfluxGeneralException)
|
||||
* InfluxNoSeriesException (extends InfluxGeneralException)
|
||||
* InfluxUnexpectedResponseException (extends InfluxGeneralException)
|
||||
|
||||
### Create your client with the factory method
|
||||
## Create your client with the factory method
|
||||
|
||||
Effectively the client creation is not so simple, for that
|
||||
reason you can you the factory method provided with the library.
|
||||
@@ -107,81 +127,108 @@ reason you can you the factory method provided with the library.
|
||||
```php
|
||||
$options = [
|
||||
"adapter" => [
|
||||
"name" => "InfluxDB\\Adapter\\HttpAdapter",
|
||||
"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);
|
||||
|
||||
$client->mark("error.404", ["page" => "/a-missing-page"]);
|
||||
```
|
||||
|
||||
Of course you can always use the DiC or your service manager in order to create
|
||||
Of course you can always use a DiC (eg `symfony/dependency-injection`) or your service manager in order to create
|
||||
a valid client instance.
|
||||
|
||||
### Time Precision write/read queries
|
||||
|
||||
You can set the `time_precision` for query query
|
||||
|
||||
```php
|
||||
$client->mark("app.search", $points, "s"); //points contains "time" that is in seconds
|
||||
```
|
||||
|
||||
```php
|
||||
$client->query("select * from app.search", "s"); // retrieve points using seconds for time column
|
||||
```
|
||||
|
||||
### 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
|
||||
$influx->query('select * from "mine"');
|
||||
```
|
||||
|
||||
You can query the database only if the adapter is queryable (implements
|
||||
`QueryableInterface`), actually `HttpAdapter`.
|
||||
`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 =>
|
||||
'results' =>
|
||||
array(1) {
|
||||
[0] =>
|
||||
array(1) {
|
||||
[0] =>
|
||||
array(3) {
|
||||
[0] =>
|
||||
int(1410545635590)
|
||||
[1] =>
|
||||
int(2390001)
|
||||
[2] =>
|
||||
string(7) "element"
|
||||
'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,host=serverA,env=prod,target=servers,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
|
||||
@@ -195,16 +242,57 @@ $client->deleteDatabase("my.name"); // delete an existing database with name "my
|
||||
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.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Simple benchmarks executed on a Sony Vaio T13 (SVT1311C5E)
|
||||
|
||||
### Adapters
|
||||
|
||||
The impact using UDP or HTTP adapters
|
||||
The impact using UDP/IP or HTTP adapters
|
||||
|
||||
```
|
||||
Corley\Benchmarks\InfluxDB\AdapterEvent
|
||||
Method Name Iterations Average Time Ops/second
|
||||
------------------------ ------------ -------------- -------------
|
||||
sendDataUsingHttpAdapter: [1,000 ] [0.0026700308323] [374.52751]
|
||||
sendDataUsingUdpAdapter : [1,000 ] [0.0000436344147] [22,917.69026]
|
||||
sendDataUsingHttpAdapter: [1,000 ] [0.0162619416714] [61.49327]
|
||||
sendDataUsingUdpAdapter : [1,000 ] [0.0000890662670] [11,227.59529]
|
||||
```
|
||||
|
||||
### 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.0000230122805] [43,455.05877]
|
||||
convertMessageToInlineProtocolWithGlobalTags : [10,000 ] [0.0000301691532] [33,146.43911]
|
||||
convertMessageToInlineProtocolWithDifferentTagLevels: [10,000 ] [0.0000327563763] [30,528.40741]
|
||||
```
|
||||
|
||||
|
||||
+8
-2
@@ -17,16 +17,22 @@ class AdapterEvent extends AthleticEvent
|
||||
{
|
||||
$client = new Client();
|
||||
$options = new Options();
|
||||
$options->setHost("localhost");
|
||||
$options->setPort(8086);
|
||||
$options->setUsername("root");
|
||||
$options->setPassword("root");
|
||||
$options->setDatabase("bench");
|
||||
$options->setDatabase("tcp.test");
|
||||
$client->setAdapter(
|
||||
new GuzzleAdapter(new HttpClient(), $options)
|
||||
);
|
||||
$this->httpClient = $client;
|
||||
|
||||
$opts = new Options();
|
||||
$opts->setPort(4444);
|
||||
|
||||
$client = new Client();
|
||||
$client->setAdapter(new UdpAdapter(new Options()));
|
||||
$client->setAdapter(new UdpAdapter($opts));
|
||||
|
||||
$this->udpClient = $client;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
namespace Corley\Benchmarks\InfluxDB;
|
||||
|
||||
use Athletic\AthleticEvent;
|
||||
use InfluxDB\Adapter\UdpAdapter;
|
||||
use InfluxDB\Options;
|
||||
|
||||
class MessageToInlineProtocolEvent extends AthleticEvent
|
||||
{
|
||||
private $method;
|
||||
private $object;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$object = new UdpAdapter(new Options());
|
||||
$reflection = new \ReflectionClass(get_class($object));
|
||||
$method = $reflection->getMethod("serialize");
|
||||
$method->setAccessible(true);
|
||||
|
||||
$this->method = $method;
|
||||
$this->object = $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @iterations 10000
|
||||
*/
|
||||
public function convertMessageToInlineProtocolWithNoTags()
|
||||
{
|
||||
$this->method->invokeArgs($this->object, [
|
||||
[
|
||||
"points" => [
|
||||
[
|
||||
"measurement" => "vm-serie",
|
||||
"fields" => [
|
||||
"cpu" => 18.12,
|
||||
"free" => 712423,
|
||||
],
|
||||
],
|
||||
]
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @iterations 10000
|
||||
*/
|
||||
public function convertMessageToInlineProtocolWithGlobalTags()
|
||||
{
|
||||
$this->method->invokeArgs($this->object, [
|
||||
[
|
||||
"tags" => [
|
||||
"dc" => "eu-west-1",
|
||||
],
|
||||
"points" => [
|
||||
[
|
||||
"measurement" => "vm-serie",
|
||||
"fields" => [
|
||||
"cpu" => 18.12,
|
||||
"free" => 712423,
|
||||
],
|
||||
],
|
||||
]
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @iterations 10000
|
||||
*/
|
||||
public function convertMessageToInlineProtocolWithDifferentTagLevels()
|
||||
{
|
||||
$this->method->invokeArgs($this->object, [
|
||||
[
|
||||
"tags" => [
|
||||
"dc" => "eu-west-1",
|
||||
],
|
||||
"points" => [
|
||||
[
|
||||
"measurement" => "vm-serie",
|
||||
"tags" => [
|
||||
"server" => "tc12",
|
||||
],
|
||||
"fields" => [
|
||||
"cpu" => 18.12,
|
||||
"free" => 712423,
|
||||
],
|
||||
],
|
||||
]
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
<?php
|
||||
namespace Corley\Benchmarks\InfluxDB;
|
||||
|
||||
use Athletic\AthleticEvent;
|
||||
use InfluxDB\Client;
|
||||
use InfluxDB\Filter\ColumnsPointsFilter;
|
||||
use Prophecy\Prophet;
|
||||
use Prophecy\Argument;
|
||||
|
||||
class FilterEvent extends AthleticEvent
|
||||
{
|
||||
private $withFilter;
|
||||
private $withoutFilter;
|
||||
private $testData;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->testData = [
|
||||
(object)[
|
||||
"name" => "test",
|
||||
"columns" => [
|
||||
"time",
|
||||
"sequence_number",
|
||||
"value",
|
||||
],
|
||||
"points" => [
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
$prophet = new Prophet;
|
||||
$adapter = $prophet->prophesize('InfluxDB\Adapter\GuzzleAdapter');
|
||||
$adapter->query(Argument::any(), Argument::Any())->willReturn($this->testData);
|
||||
|
||||
$this->withFilter = new Client();
|
||||
$this->withFilter->setAdapter($adapter->reveal());
|
||||
$this->withFilter->setFilter(new ColumnsPointsFilter());
|
||||
|
||||
$this->withoutFilter = new Client();
|
||||
$this->withoutFilter->setAdapter($adapter->reveal());
|
||||
}
|
||||
|
||||
/**
|
||||
* @iterations 10000
|
||||
*/
|
||||
public function get10PointDirectData()
|
||||
{
|
||||
for ($i=0; $i<10; $i++) {
|
||||
$this->testData[0]->points[] = [1985718957, 12519287519, 12589175198];
|
||||
}
|
||||
|
||||
$this->withoutFilter->query("THE QUERY", "s");
|
||||
}
|
||||
|
||||
/**
|
||||
* @iterations 10000
|
||||
*/
|
||||
public function get10PointFilteredData()
|
||||
{
|
||||
for ($i=0; $i<10; $i++) {
|
||||
$this->testData[0]->points[] = [1985718957, 12519287519, 12589175198];
|
||||
}
|
||||
$this->withFilter->query("THE QUERY", "s");
|
||||
}
|
||||
|
||||
/**
|
||||
* @iterations 1000
|
||||
*/
|
||||
public function get100PointDirectData()
|
||||
{
|
||||
for ($i=0; $i<100; $i++) {
|
||||
$this->testData[0]->points[] = [1985718957, 12519287519, 12589175198];
|
||||
}
|
||||
|
||||
$this->withoutFilter->query("THE QUERY", "s");
|
||||
}
|
||||
|
||||
/**
|
||||
* @iterations 1000
|
||||
*/
|
||||
public function get100PointFilteredData()
|
||||
{
|
||||
for ($i=0; $i<100; $i++) {
|
||||
$this->testData[0]->points[] = [1985718957, 12519287519, 12589175198];
|
||||
}
|
||||
$this->withFilter->query("THE QUERY", "s");
|
||||
}
|
||||
|
||||
/**
|
||||
* @iterations 100
|
||||
*/
|
||||
public function get1000PointDirectData()
|
||||
{
|
||||
for ($i=0; $i<1000; $i++) {
|
||||
$this->testData[0]->points[] = [1985718957, 12519287519, 12589175198];
|
||||
}
|
||||
|
||||
$this->withoutFilter->query("THE QUERY", "s");
|
||||
}
|
||||
|
||||
/**
|
||||
* @iterations 100
|
||||
*/
|
||||
public function get1000PointFilteredData()
|
||||
{
|
||||
for ($i=0; $i<1000; $i++) {
|
||||
$this->testData[0]->points[] = [1985718957, 12519287519, 12589175198];
|
||||
}
|
||||
$this->withFilter->query("THE QUERY", "s");
|
||||
}
|
||||
}
|
||||
+7
-3
@@ -10,7 +10,6 @@
|
||||
"zendframework/zend-servicemanager": "~2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "2.*",
|
||||
"phpunit/phpunit": "4.*",
|
||||
"athletic/athletic": "~0.1",
|
||||
"ext-sockets": "*"
|
||||
@@ -32,11 +31,16 @@
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"InfluxDB\\": ["./src/", "./tests"],
|
||||
"psr-4": {
|
||||
"InfluxDB\\": ["./src/"],
|
||||
"Corley\\": ["./benchmarks/"]
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"InfluxDB\\": ["./tests/"]
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"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",
|
||||
|
||||
Generated
+76
-403
@@ -4,30 +4,30 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "f2dbbf00b528de2e350ff4550629e1b4",
|
||||
"hash": "96faa156d58fde5c5c3cf3df60d74ae1",
|
||||
"packages": [
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "5.2.0",
|
||||
"version": "5.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "475b29ccd411f2fa8a408e64576418728c032cfa"
|
||||
"reference": "f3c8c22471cb55475105c14769644a49c3262b93"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/475b29ccd411f2fa8a408e64576418728c032cfa",
|
||||
"reference": "475b29ccd411f2fa8a408e64576418728c032cfa",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/f3c8c22471cb55475105c14769644a49c3262b93",
|
||||
"reference": "f3c8c22471cb55475105c14769644a49c3262b93",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/ringphp": "~1.0",
|
||||
"guzzlehttp/ringphp": "^1.1",
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"psr/log": "~1.0"
|
||||
"phpunit/phpunit": "^4.0",
|
||||
"psr/log": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
@@ -62,20 +62,20 @@
|
||||
"rest",
|
||||
"web service"
|
||||
],
|
||||
"time": "2015-01-28 01:03:29"
|
||||
"time": "2015-05-20 03:47:55"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/ringphp",
|
||||
"version": "1.0.7",
|
||||
"version": "1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/RingPHP.git",
|
||||
"reference": "52d868f13570a9a56e5fce6614e0ec75d0f13ac2"
|
||||
"reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/RingPHP/zipball/52d868f13570a9a56e5fce6614e0ec75d0f13ac2",
|
||||
"reference": "52d868f13570a9a56e5fce6614e0ec75d0f13ac2",
|
||||
"url": "https://api.github.com/repos/guzzle/RingPHP/zipball/dbbb91d7f6c191e5e405e900e3102ac7f261bc0b",
|
||||
"reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -93,7 +93,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -113,7 +113,7 @@
|
||||
}
|
||||
],
|
||||
"description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.",
|
||||
"time": "2015-03-30 01:43:20"
|
||||
"time": "2015-05-20 03:37:09"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/streams",
|
||||
@@ -211,29 +211,31 @@
|
||||
},
|
||||
{
|
||||
"name": "zendframework/zend-filter",
|
||||
"version": "2.4.2",
|
||||
"version": "2.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zendframework/zend-filter.git",
|
||||
"reference": "a3711101850078b2aa69586c71897acaada2e9cb"
|
||||
"reference": "93e6990a198e6cdd811064083acac4693f4b29ae"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zendframework/zend-filter/zipball/a3711101850078b2aa69586c71897acaada2e9cb",
|
||||
"reference": "a3711101850078b2aa69586c71897acaada2e9cb",
|
||||
"url": "https://api.github.com/repos/zendframework/zend-filter/zipball/93e6990a198e6cdd811064083acac4693f4b29ae",
|
||||
"reference": "93e6990a198e6cdd811064083acac4693f4b29ae",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.23",
|
||||
"zendframework/zend-stdlib": "self.version"
|
||||
"zendframework/zend-stdlib": "~2.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"fabpot/php-cs-fixer": "1.7.*",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"satooshi/php-coveralls": "dev-master",
|
||||
"zendframework/zend-crypt": "self.version",
|
||||
"zendframework/zend-servicemanager": "self.version",
|
||||
"zendframework/zend-uri": "self.version"
|
||||
"zendframework/zend-config": "~2.5",
|
||||
"zendframework/zend-crypt": "~2.5",
|
||||
"zendframework/zend-i18n": "~2.5",
|
||||
"zendframework/zend-loader": "~2.5",
|
||||
"zendframework/zend-servicemanager": "~2.5",
|
||||
"zendframework/zend-uri": "~2.5"
|
||||
},
|
||||
"suggest": {
|
||||
"zendframework/zend-crypt": "Zend\\Crypt component",
|
||||
@@ -244,8 +246,8 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev",
|
||||
"dev-develop": "2.5-dev"
|
||||
"dev-master": "2.5-dev",
|
||||
"dev-develop": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -263,20 +265,20 @@
|
||||
"filter",
|
||||
"zf2"
|
||||
],
|
||||
"time": "2015-05-07 14:55:31"
|
||||
"time": "2015-06-03 15:32:01"
|
||||
},
|
||||
{
|
||||
"name": "zendframework/zend-servicemanager",
|
||||
"version": "2.4.2",
|
||||
"version": "2.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zendframework/zend-servicemanager.git",
|
||||
"reference": "855294e12771b4295c26446b6ed2df2f1785f234"
|
||||
"reference": "3b22c403e351d92526c642cba0bd810bc22e1c56"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zendframework/zend-servicemanager/zipball/855294e12771b4295c26446b6ed2df2f1785f234",
|
||||
"reference": "855294e12771b4295c26446b6ed2df2f1785f234",
|
||||
"url": "https://api.github.com/repos/zendframework/zend-servicemanager/zipball/3b22c403e351d92526c642cba0bd810bc22e1c56",
|
||||
"reference": "3b22c403e351d92526c642cba0bd810bc22e1c56",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -285,8 +287,8 @@
|
||||
"require-dev": {
|
||||
"fabpot/php-cs-fixer": "1.7.*",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"satooshi/php-coveralls": "dev-master",
|
||||
"zendframework/zend-di": "self.version"
|
||||
"zendframework/zend-di": "~2.5",
|
||||
"zendframework/zend-mvc": "~2.5"
|
||||
},
|
||||
"suggest": {
|
||||
"ocramius/proxy-manager": "ProxyManager 0.5.* to handle lazy initialization of services",
|
||||
@@ -295,8 +297,8 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev",
|
||||
"dev-develop": "2.5-dev"
|
||||
"dev-master": "2.5-dev",
|
||||
"dev-develop": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -308,25 +310,25 @@
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"homepage": "https://github.com/zendframework/zend-service-manager",
|
||||
"homepage": "https://github.com/zendframework/zend-servicemanager",
|
||||
"keywords": [
|
||||
"servicemanager",
|
||||
"zf2"
|
||||
],
|
||||
"time": "2015-05-07 14:55:31"
|
||||
"time": "2015-06-03 15:32:02"
|
||||
},
|
||||
{
|
||||
"name": "zendframework/zend-stdlib",
|
||||
"version": "2.4.2",
|
||||
"version": "2.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zendframework/zend-stdlib.git",
|
||||
"reference": "a5dd7fd2ba6e8f6c6ea5a12db0605d3aa48af1e7"
|
||||
"reference": "cc8e90a60dd5d44b9730b77d07b97550091da1ae"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/a5dd7fd2ba6e8f6c6ea5a12db0605d3aa48af1e7",
|
||||
"reference": "a5dd7fd2ba6e8f6c6ea5a12db0605d3aa48af1e7",
|
||||
"url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/cc8e90a60dd5d44b9730b77d07b97550091da1ae",
|
||||
"reference": "cc8e90a60dd5d44b9730b77d07b97550091da1ae",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -335,11 +337,12 @@
|
||||
"require-dev": {
|
||||
"fabpot/php-cs-fixer": "1.7.*",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"satooshi/php-coveralls": "dev-master",
|
||||
"zendframework/zend-eventmanager": "self.version",
|
||||
"zendframework/zend-filter": "self.version",
|
||||
"zendframework/zend-serializer": "self.version",
|
||||
"zendframework/zend-servicemanager": "self.version"
|
||||
"zendframework/zend-config": "~2.5",
|
||||
"zendframework/zend-eventmanager": "~2.5",
|
||||
"zendframework/zend-filter": "~2.5",
|
||||
"zendframework/zend-inputfilter": "~2.5",
|
||||
"zendframework/zend-serializer": "~2.5",
|
||||
"zendframework/zend-servicemanager": "~2.5"
|
||||
},
|
||||
"suggest": {
|
||||
"zendframework/zend-eventmanager": "To support aggregate hydrator usage",
|
||||
@@ -350,8 +353,8 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev",
|
||||
"dev-develop": "2.5-dev"
|
||||
"dev-master": "2.5-dev",
|
||||
"dev-develop": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -368,7 +371,7 @@
|
||||
"stdlib",
|
||||
"zf2"
|
||||
],
|
||||
"time": "2015-05-07 14:55:31"
|
||||
"time": "2015-06-03 15:32:03"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
@@ -620,118 +623,6 @@
|
||||
],
|
||||
"time": "2015-02-03 12:10:50"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/php-diff",
|
||||
"version": "v1.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/php-diff.git",
|
||||
"reference": "30e103d19519fe678ae64a60d77884ef3d71b28a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/php-diff/zipball/30e103d19519fe678ae64a60d77884ef3d71b28a",
|
||||
"reference": "30e103d19519fe678ae64a60d77884ef3d71b28a",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Diff": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Chris Boulton",
|
||||
"homepage": "http://github.com/chrisboulton",
|
||||
"role": "Original developer"
|
||||
}
|
||||
],
|
||||
"description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).",
|
||||
"time": "2013-11-01 13:02:21"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/phpspec",
|
||||
"version": "2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/phpspec.git",
|
||||
"reference": "9727d75919a00455433e867565bc022f0b985a39"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/phpspec/zipball/9727d75919a00455433e867565bc022f0b985a39",
|
||||
"reference": "9727d75919a00455433e867565bc022f0b985a39",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/instantiator": "^1.0.1",
|
||||
"php": ">=5.3.3",
|
||||
"phpspec/php-diff": "~1.0.0",
|
||||
"phpspec/prophecy": "~1.4",
|
||||
"sebastian/exporter": "~1.0",
|
||||
"symfony/console": "~2.3",
|
||||
"symfony/event-dispatcher": "~2.1",
|
||||
"symfony/finder": "~2.1",
|
||||
"symfony/process": "~2.1",
|
||||
"symfony/yaml": "~2.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"behat/behat": "^3.0.11",
|
||||
"bossa/phpspec2-expect": "~1.0",
|
||||
"phpunit/phpunit": "~4.4",
|
||||
"symfony/filesystem": "~2.1",
|
||||
"symfony/process": "~2.1"
|
||||
},
|
||||
"suggest": {
|
||||
"phpspec/nyan-formatters": "~1.0 – Adds Nyan formatters"
|
||||
},
|
||||
"bin": [
|
||||
"bin/phpspec"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"PhpSpec": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Konstantin Kudryashov",
|
||||
"email": "ever.zet@gmail.com",
|
||||
"homepage": "http://everzet.com"
|
||||
},
|
||||
{
|
||||
"name": "Marcello Duarte",
|
||||
"homepage": "http://marcelloduarte.net/"
|
||||
}
|
||||
],
|
||||
"description": "Specification-oriented BDD framework for PHP 5.3+",
|
||||
"homepage": "http://phpspec.net/",
|
||||
"keywords": [
|
||||
"BDD",
|
||||
"SpecBDD",
|
||||
"TDD",
|
||||
"spec",
|
||||
"specification",
|
||||
"testing",
|
||||
"tests"
|
||||
],
|
||||
"time": "2015-04-18 16:22:51"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "v1.4.1",
|
||||
@@ -794,16 +685,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "2.0.16",
|
||||
"version": "2.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "934fd03eb6840508231a7f73eb8940cf32c3b66c"
|
||||
"reference": "28a6b34e91d789b2608072ab3c82eaae7cdb973c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/934fd03eb6840508231a7f73eb8940cf32c3b66c",
|
||||
"reference": "934fd03eb6840508231a7f73eb8940cf32c3b66c",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/28a6b34e91d789b2608072ab3c82eaae7cdb973c",
|
||||
"reference": "28a6b34e91d789b2608072ab3c82eaae7cdb973c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -826,7 +717,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
"dev-master": "2.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -852,7 +743,7 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-04-11 04:35:00"
|
||||
"time": "2015-06-03 07:01:01"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
@@ -1040,16 +931,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "4.6.6",
|
||||
"version": "4.6.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "3afe303d873a4d64c62ef84de491b97b006fbdac"
|
||||
"reference": "7b5fe98b28302a8b25693b2298bca74463336975"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3afe303d873a4d64c62ef84de491b97b006fbdac",
|
||||
"reference": "3afe303d873a4d64c62ef84de491b97b006fbdac",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7b5fe98b28302a8b25693b2298bca74463336975",
|
||||
"reference": "7b5fe98b28302a8b25693b2298bca74463336975",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1108,20 +999,20 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-04-29 15:18:52"
|
||||
"time": "2015-06-03 05:03:30"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit-mock-objects",
|
||||
"version": "2.3.1",
|
||||
"version": "2.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
|
||||
"reference": "74ffb87f527f24616f72460e54b595f508dccb5c"
|
||||
"reference": "253c005852591fd547fc18cd5b7b43a1ec82d8f7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/74ffb87f527f24616f72460e54b595f508dccb5c",
|
||||
"reference": "74ffb87f527f24616f72460e54b595f508dccb5c",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/253c005852591fd547fc18cd5b7b43a1ec82d8f7",
|
||||
"reference": "253c005852591fd547fc18cd5b7b43a1ec82d8f7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1163,7 +1054,7 @@
|
||||
"mock",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-04-02 05:36:41"
|
||||
"time": "2015-05-29 05:19:18"
|
||||
},
|
||||
{
|
||||
"name": "pimple/pimple",
|
||||
@@ -1582,240 +1473,22 @@
|
||||
"homepage": "https://github.com/sebastianbergmann/version",
|
||||
"time": "2015-02-24 06:35:25"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v2.6.7",
|
||||
"target-dir": "Symfony/Component/Console",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Console.git",
|
||||
"reference": "ebc5679854aa24ed7d65062e9e3ab0b18a917272"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Console/zipball/ebc5679854aa24ed7d65062e9e3ab0b18a917272",
|
||||
"reference": "ebc5679854aa24ed7d65062e9e3ab0b18a917272",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/log": "~1.0",
|
||||
"symfony/event-dispatcher": "~2.1",
|
||||
"symfony/phpunit-bridge": "~2.7",
|
||||
"symfony/process": "~2.1"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/log": "For using the console logger",
|
||||
"symfony/event-dispatcher": "",
|
||||
"symfony/process": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Console\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-05-02 15:18:45"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v2.6.7",
|
||||
"target-dir": "Symfony/Component/EventDispatcher",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/EventDispatcher.git",
|
||||
"reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/672593bc4b0043a0acf91903bb75a1c82d8f2e02",
|
||||
"reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/log": "~1.0",
|
||||
"symfony/config": "~2.0,>=2.0.5",
|
||||
"symfony/dependency-injection": "~2.6",
|
||||
"symfony/expression-language": "~2.6",
|
||||
"symfony/phpunit-bridge": "~2.7",
|
||||
"symfony/stopwatch": "~2.3"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/dependency-injection": "",
|
||||
"symfony/http-kernel": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\EventDispatcher\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-05-02 15:18:45"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v2.6.7",
|
||||
"target-dir": "Symfony/Component/Finder",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Finder.git",
|
||||
"reference": "704c64c8b12c8882640d5c0330a8414b1e06dc99"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Finder/zipball/704c64c8b12c8882640d5c0330a8414b1e06dc99",
|
||||
"reference": "704c64c8b12c8882640d5c0330a8414b1e06dc99",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "~2.7"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Finder\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Finder Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-05-02 15:18:45"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v2.6.7",
|
||||
"target-dir": "Symfony/Component/Process",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Process.git",
|
||||
"reference": "9f3c4baaf840ed849e1b1f7bfd5ae246e8509562"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Process/zipball/9f3c4baaf840ed849e1b1f7bfd5ae246e8509562",
|
||||
"reference": "9f3c4baaf840ed849e1b1f7bfd5ae246e8509562",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "~2.7"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Process\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-05-02 15:18:45"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v2.6.7",
|
||||
"target-dir": "Symfony/Component/Yaml",
|
||||
"version": "v2.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Yaml.git",
|
||||
"reference": "f157ab074e453ecd4c0fa775f721f6e67a99d9e2"
|
||||
"reference": "4a29a5248aed4fb45f626a7bbbd330291492f5c3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/f157ab074e453ecd4c0fa775f721f6e67a99d9e2",
|
||||
"reference": "f157ab074e453ecd4c0fa775f721f6e67a99d9e2",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/4a29a5248aed4fb45f626a7bbbd330291492f5c3",
|
||||
"reference": "4a29a5248aed4fb45f626a7bbbd330291492f5c3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
"php": ">=5.3.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "~2.7"
|
||||
@@ -1823,11 +1496,11 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.6-dev"
|
||||
"dev-master": "2.7-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Yaml\\": ""
|
||||
}
|
||||
},
|
||||
@@ -1847,7 +1520,7 @@
|
||||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-05-02 15:18:45"
|
||||
"time": "2015-05-02 15:21:08"
|
||||
},
|
||||
{
|
||||
"name": "zeptech/annotations",
|
||||
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
<phpunit
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/3.7/phpunit.xsd"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
@@ -13,7 +12,7 @@
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<php>
|
||||
<env name="UDP_PORT" value="5551"/>
|
||||
<env name="UDP_PORT" value="4444"/>
|
||||
<env name="UDP_DB" value="udp.test"/>
|
||||
|
||||
<env name="TCP_PORT" value="8086"/>
|
||||
|
||||
+61
-174
@@ -1,187 +1,74 @@
|
||||
# Welcome to the InfluxDB configuration file.
|
||||
[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"
|
||||
|
||||
# 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"
|
||||
[data]
|
||||
dir = "/var/opt/influxdb/data"
|
||||
retention-auto-create = true
|
||||
retention-check-enabled = true
|
||||
retention-check-period = "10m0s"
|
||||
retention-create-period = "45m0s"
|
||||
|
||||
[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.
|
||||
shard-writer-timeout = "5s"
|
||||
|
||||
# Here's an example. Note that the port on the host is the same as the raft port.
|
||||
# seed-servers = ["hosta:8090","hostb:8090"]
|
||||
[retention]
|
||||
enabled = true
|
||||
check-interval = "10m0s"
|
||||
|
||||
# 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.
|
||||
[admin]
|
||||
enabled = true
|
||||
bind-address = ":8083"
|
||||
|
||||
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
|
||||
[http]
|
||||
enabled = true
|
||||
bind-address = ":8086"
|
||||
auth-enabled = false
|
||||
log-enabled = true
|
||||
write-tracing = false
|
||||
pprof-enabled = false
|
||||
|
||||
# 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
|
||||
[collectd]
|
||||
enabled = false
|
||||
bind-address = ""
|
||||
database = ""
|
||||
typesdb = ""
|
||||
|
||||
# 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
|
||||
[opentsdb]
|
||||
enabled = false
|
||||
bind-address = ""
|
||||
database = ""
|
||||
retention-policy = ""
|
||||
|
||||
# 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
|
||||
[udp]
|
||||
enabled = true
|
||||
bind-address = ":4444"
|
||||
database = "udp.test"
|
||||
batch-size = 0
|
||||
batch-timeout = "10ns"
|
||||
|
||||
[wal]
|
||||
[monitoring]
|
||||
enabled = false
|
||||
write-interval = "1m0s"
|
||||
|
||||
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
|
||||
[continuous_queries]
|
||||
enabled = true
|
||||
recompute-previous-n = 2
|
||||
recompute-no-older-than = "10m0s"
|
||||
compute-runs-per-interval = 10
|
||||
compute-no-more-than = "2m0s"
|
||||
|
||||
# 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
|
||||
[hinted-handoff]
|
||||
enabled = true
|
||||
dir = "/var/opt/influxdb/hh"
|
||||
max-size = 1073741824
|
||||
max-age = "168h0m0s"
|
||||
retry-rate-limit = 0
|
||||
retry-interval = "1s"
|
||||
|
||||
# the number of requests per one log file, if new requests came in a
|
||||
# new log file will be created
|
||||
requests-per-logfile = 10000
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace spec\InfluxDB\Adapter;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use GuzzleHttp\Client;
|
||||
use InfluxDB\Options;
|
||||
use GuzzleHttp\Message\Response;
|
||||
|
||||
class GuzzleAdapterSpec extends ObjectBehavior
|
||||
{
|
||||
function let(Client $client, Options $options)
|
||||
{
|
||||
$options->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);
|
||||
}
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace spec\InfluxDB\Adapter;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Message\Response;
|
||||
use GuzzleHttp\Stream\Stream;
|
||||
use InfluxDB\Adapter\HttpAdapter;
|
||||
use InfluxDB\Exception\InfluxAuthorizationException;
|
||||
use InfluxDB\Exception\InfluxBadResponseException;
|
||||
use InfluxDB\Exception\InfluxGeneralException;
|
||||
use InfluxDB\Exception\InfluxNoSeriesException;
|
||||
use InfluxDB\Exception\InfluxUnexpectedResponseException;
|
||||
use InfluxDB\Options;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
|
||||
class HttpAdapterSpec extends ObjectBehavior
|
||||
{
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('InfluxDB\Adapter\HttpAdapter');
|
||||
}
|
||||
|
||||
function let(Options $options, Client $client)
|
||||
{
|
||||
$options->getHttpSeriesEndpoint()->willReturn("localhost");
|
||||
$options->getHttpDatabaseEndpoint()->willReturn("localhost");
|
||||
$options->getUsername()->willReturn("one");
|
||||
$options->getPassword()->willReturn("two");
|
||||
$this->beConstructedWith($options, $client);
|
||||
}
|
||||
|
||||
function it_should_send_data_via_post(Client $client)
|
||||
{
|
||||
$responseBody = ['key'=>'value'];
|
||||
$response = new Response(200,[], Stream::factory(json_encode($responseBody)));
|
||||
$client->post("localhost", [
|
||||
'auth' => ["one", "two"],
|
||||
'exceptions' => false,
|
||||
'body' => json_encode(['pippo'])
|
||||
])->willReturn($response)
|
||||
->shouldBeCalledTimes(1);
|
||||
$this->send(["pippo"])->shouldReturn($responseBody);
|
||||
}
|
||||
|
||||
function it_should_query_data(Client $client, Options $options)
|
||||
{
|
||||
$client->get(
|
||||
"localhost",
|
||||
[
|
||||
"auth" => ["one", "two"],
|
||||
"exceptions" => false,
|
||||
"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"],
|
||||
"exceptions" => false,
|
||||
"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"],
|
||||
"exceptions" => false,
|
||||
]
|
||||
)->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"],
|
||||
"exceptions" => false,
|
||||
"body" => json_encode(["name" => "db_name"])
|
||||
]
|
||||
)->shouldBeCalledTimes(1)->willReturn(new Response(201, [], null));
|
||||
|
||||
$this->createDatabase("db_name")->shouldReturn(true);
|
||||
}
|
||||
|
||||
function it_should_return_true_with_success(Client $client) {
|
||||
foreach ([201,204,299] as $code) {
|
||||
$client->post(Argument::any(), Argument::any(), Argument::any())->willReturn(new Response($code, [], null));
|
||||
|
||||
$this->createDatabase("db_name")->shouldReturn(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function it_should_throw_no_series_exception (Client $client)
|
||||
{
|
||||
$client->get(
|
||||
"localhost",
|
||||
[
|
||||
"auth" => ["one", "two"],
|
||||
"exceptions" => false,
|
||||
"query" => [
|
||||
"q" => "select * from tcp.test",
|
||||
]
|
||||
]
|
||||
)->willReturn(new Response(HttpAdapter::STATUS_CODE_BAD_REQUEST,[], Stream::factory("Couldn't find series: tcp.test")));
|
||||
$this->shouldThrow(new InfluxNoSeriesException("Couldn't find series: tcp.test", HttpAdapter::STATUS_CODE_BAD_REQUEST))
|
||||
->during("query", ["select * from tcp.test"]);
|
||||
}
|
||||
|
||||
function it_should_throw_authorization_exception (Client $client)
|
||||
{
|
||||
$codes = [HttpAdapter::STATUS_CODE_UNAUTHORIZED, HttpAdapter::STATUS_CODE_FORBIDDEN];
|
||||
foreach ($codes as $code) {
|
||||
$client->get(
|
||||
"localhost",
|
||||
[
|
||||
"auth" => ["one", "two"],
|
||||
"exceptions" => false,
|
||||
"query" => [
|
||||
"q" => "select * from tcp.test",
|
||||
]
|
||||
]
|
||||
)->willReturn(new Response($code,[], Stream::factory("Message")));
|
||||
$this->shouldThrow(new InfluxAuthorizationException("Message", $code))
|
||||
->during("query", ["select * from tcp.test"]);
|
||||
}
|
||||
}
|
||||
|
||||
function it_should_throw_general_exception (Client $client)
|
||||
{
|
||||
$client->get(
|
||||
"localhost",
|
||||
[
|
||||
"auth" => ["one", "two"],
|
||||
"exceptions" => false,
|
||||
"query" => [
|
||||
"q" => "select * from tcp.test",
|
||||
]
|
||||
]
|
||||
)->willReturn(new Response(409,[], Stream::factory("Message")));
|
||||
$this->shouldThrow(new InfluxGeneralException("Message", 409))
|
||||
->during("query", ["select * from tcp.test"]);
|
||||
}
|
||||
|
||||
function it_should_throw_general_exception_with_default_message (Client $client)
|
||||
{
|
||||
$client->get(Argument::any(), Argument::any())->willReturn(new Response(409));
|
||||
$this->shouldThrow(new InfluxGeneralException("Conflict", 409))
|
||||
->during("query", ["select * from tcp.test"]);
|
||||
}
|
||||
|
||||
function it_should_throw_bad_response_exception(Client $client)
|
||||
{
|
||||
$response = new Response(200,[], Stream::factory('bad response'));
|
||||
$client->post("localhost", [
|
||||
'auth' => ["one", "two"],
|
||||
'exceptions' => false,
|
||||
'body' => json_encode(['pippo'])
|
||||
])->willReturn($response)
|
||||
->shouldBeCalledTimes(1);
|
||||
$this->shouldThrow(new InfluxBadResponseException("Unable to parse JSON data: JSON_ERROR_SYNTAX - Syntax error, malformed JSON; Response is 'bad response'", 0))
|
||||
->during("send", [["pippo"]]);
|
||||
}
|
||||
|
||||
function it_should_throw_unexpected_response_exception (Client $client)
|
||||
{
|
||||
foreach ([0, 300, 500] as $code) {
|
||||
$client->get(Argument::any(), Argument::any())->willReturn(new Response($code, [], Stream::factory("Message")));
|
||||
$this->shouldThrow(new InfluxUnexpectedResponseException("Message", $code))
|
||||
->during("query", ["select * from tcp.test"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace spec\InfluxDB\Adapter;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use InfluxDB\Options;
|
||||
|
||||
class UdpAdapterSpec extends ObjectBehavior
|
||||
{
|
||||
function let(Options $options)
|
||||
{
|
||||
$this->beConstructedWith($options);
|
||||
}
|
||||
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('InfluxDB\Adapter\UdpAdapter');
|
||||
}
|
||||
|
||||
function it_should_implement_adapter_interface()
|
||||
{
|
||||
$this->shouldImplement("InfluxDB\Adapter\AdapterInterface");
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
namespace spec\InfluxDB;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use InfluxDB\Adapter\GuzzleAdapter;
|
||||
use InfluxDB\Adapter\UdpAdapter;
|
||||
use InfluxDB\Adapter\AdapterInterface;
|
||||
use InfluxDb\Adapter\QueryableInterface;
|
||||
|
||||
class ClientSpec extends ObjectBehavior
|
||||
{
|
||||
function let(\InfluxDB\Adapter\AdapterInterface $adapter)
|
||||
{
|
||||
$this->setAdapter($adapter);
|
||||
}
|
||||
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('InfluxDB\Client');
|
||||
}
|
||||
|
||||
function it_should_send_data(AdapterInterface $adapter)
|
||||
{
|
||||
$adapter->send([[
|
||||
"name" => "video.search",
|
||||
"columns" => ["author", "title"],
|
||||
"points" => [
|
||||
["Guccini", "Autogrill"]
|
||||
]
|
||||
]], false)->shouldBeCalledTimes(1);
|
||||
|
||||
$this->mark("video.search", [
|
||||
"author" => "Guccini",
|
||||
"title" => "Autogrill"
|
||||
]);
|
||||
}
|
||||
|
||||
function it_should_send_data_with_time_precision(AdapterInterface $adapter)
|
||||
{
|
||||
$adapter->send([[
|
||||
"name" => "video.search",
|
||||
"columns" => ["time", "author", "title"],
|
||||
"points" => [
|
||||
["1410591552", "Guccini", "Autogrill"]
|
||||
]
|
||||
]], "s")->shouldBeCalledTimes(1);
|
||||
|
||||
$this->mark("video.search", [
|
||||
"time" => "1410591552",
|
||||
"author" => "Guccini",
|
||||
"title" => "Autogrill"
|
||||
], "s");
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace spec\InfluxDB;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
|
||||
class OptionsSpec extends ObjectBehavior
|
||||
{
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->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");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace InfluxDB\Adapter;
|
||||
|
||||
use InfluxDB\Options;
|
||||
|
||||
abstract class AdapterAbstract implements AdapterInterface
|
||||
{
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* @param Options $options
|
||||
*/
|
||||
public function __construct(Options $options)
|
||||
{
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 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);
|
||||
}
|
||||
@@ -11,5 +11,5 @@ interface AdapterInterface
|
||||
* @param mixed $message
|
||||
* @param string|boolean $timePrecision
|
||||
*/
|
||||
public function send($message, $timePrecision = false);
|
||||
public function send(array $message);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
namespace InfluxDB\Adapter;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use InfluxDB\Options;
|
||||
|
||||
/**
|
||||
* Class GuzzleAdapter
|
||||
* @package InfluxDB\Adapter
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
class GuzzleAdapter extends AdapterAbstract implements QueryableInterface
|
||||
{
|
||||
private $httpClient;
|
||||
|
||||
public function __construct(Client $httpClient, Options $options)
|
||||
{
|
||||
parent::__construct($options);
|
||||
|
||||
$this->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()],
|
||||
"body" => json_encode($message)
|
||||
];
|
||||
|
||||
$endpoint = $this->getOptions()->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->getOptions()->getHttpQueryEndpoint();
|
||||
return $this->httpClient->get($endpoint, $httpMessage)->json();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace InfluxDB\Adapter;
|
||||
|
||||
interface QueryableInterface
|
||||
{
|
||||
public function query($query);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
namespace InfluxDB\Adapter;
|
||||
|
||||
use DateTime;
|
||||
use InfluxDB\Options;
|
||||
|
||||
final class UdpAdapter extends AdapterAbstract
|
||||
{
|
||||
public function send(array $message)
|
||||
{
|
||||
$message = array_replace_recursive($this->getMessageDefaults(), $message);
|
||||
$message = $this->serialize($message);
|
||||
|
||||
$this->write($message);
|
||||
}
|
||||
|
||||
public function write($message)
|
||||
{
|
||||
$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);
|
||||
}
|
||||
|
||||
private function serialize(array $message)
|
||||
{
|
||||
$tags = $this->getOptions()->getTags();
|
||||
|
||||
if (array_key_exists("tags", $message)) {
|
||||
$tags = array_replace_recursive($tags, $message["tags"]);
|
||||
}
|
||||
|
||||
$now = new DateTime();
|
||||
$unixepoch = (int)($now->format("U") * 1e9);
|
||||
if (array_key_exists("time", $message)) {
|
||||
$dt = new DateTime($message["time"]);
|
||||
$unixepoch = (int)($dt->format("U") * 1e9);
|
||||
}
|
||||
|
||||
$lines = [];
|
||||
foreach ($message["points"] as $point) {
|
||||
if (array_key_exists("tags", $point)) {
|
||||
$tags = array_replace_recursive($tags, $point["tags"]);
|
||||
}
|
||||
|
||||
if (!$tags) {
|
||||
$lines[] = trim(
|
||||
sprintf(
|
||||
"%s %s %d",
|
||||
$point["measurement"], $this->toKeyValue($point["fields"], true), $unixepoch
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$lines[] = trim(
|
||||
sprintf(
|
||||
"%s,%s %s %d",
|
||||
$point["measurement"], $this->toKeyValue($tags), $this->toKeyValue($point["fields"], true), $unixepoch
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
private function toKeyValue(array $elems, $escape=false)
|
||||
{
|
||||
$list = [];
|
||||
foreach ($elems as $key => $value) {
|
||||
if ($escape && is_string($value)) {
|
||||
$value = "\"{$value}\"";
|
||||
}
|
||||
$list[] = sprintf("%s=%s", $key, $value);
|
||||
}
|
||||
|
||||
return implode(",", $list);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB;
|
||||
|
||||
use InfluxDb\Adapter\QueryableInterface;
|
||||
use InfluxDB\Filter\FilterInterface;
|
||||
|
||||
/**
|
||||
* Client to manage request at InfluxDB
|
||||
*/
|
||||
class Client
|
||||
{
|
||||
private $adapter;
|
||||
|
||||
public function __construct(Adapter\AdapterInterface $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
public function mark($name, array $values = [])
|
||||
{
|
||||
$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()
|
||||
{
|
||||
if (!($this->getAdapter() instanceOf QueryableInterface)) {
|
||||
throw new \BadMethodCallException("You can query the database only if the adapter supports it!");
|
||||
}
|
||||
return $this->getAdapter()->query("show databases");
|
||||
}
|
||||
|
||||
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()->query("create database \"{$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()->query("drop database \"{$name}\"");
|
||||
}
|
||||
|
||||
private function clearTimePrecision($timePrecision)
|
||||
{
|
||||
switch ($timePrecision) {
|
||||
case 's':
|
||||
case 'u':
|
||||
case 'ms':
|
||||
break;
|
||||
default:
|
||||
$timePrecision = false;
|
||||
}
|
||||
|
||||
return $timePrecision;
|
||||
}
|
||||
}
|
||||
@@ -44,15 +44,11 @@ abstract class ClientFactory
|
||||
case 'InfluxDB\\Adapter\\GuzzleAdapter':
|
||||
$adapter = new $adapterName(new GuzzleClient($options["adapter"]["options"]), $adapterOptions);
|
||||
break;
|
||||
case 'InfluxDB\\Adapter\\HttpAdapter':
|
||||
$adapter = new $adapterName($adapterOptions, new GuzzleClient($options["adapter"]["options"]));
|
||||
break;
|
||||
default:
|
||||
throw new \InvalidArgumentException("Missing adapter {$adapter}");
|
||||
}
|
||||
|
||||
$client = new Client();
|
||||
$client->setAdapter($adapter);
|
||||
$client = new Client($adapter);
|
||||
|
||||
return $client;
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
<?php
|
||||
namespace InfluxDB\Adapter;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use InfluxDB\Options;
|
||||
|
||||
/**
|
||||
* Class GuzzleAdapter
|
||||
* @package InfluxDB\Adapter
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
class GuzzleAdapter implements AdapterInterface, QueryableInterface
|
||||
{
|
||||
/**
|
||||
* @var GuzzleHttp\Client
|
||||
*/
|
||||
private $httpClient;
|
||||
|
||||
/**
|
||||
* @var \InfluxDB\Options
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* @param Client $httpClient
|
||||
* @param Options $options
|
||||
*/
|
||||
public function __construct(Client $httpClient, Options $options)
|
||||
{
|
||||
$this->httpClient = $httpClient;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Options
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function send($message, $timePrecision = false)
|
||||
{
|
||||
$httpMessage = [
|
||||
"auth" => [$this->options->getUsername(), $this->options->getPassword()],
|
||||
"body" => json_encode($message)
|
||||
];
|
||||
|
||||
if ($timePrecision) {
|
||||
$httpMessage["query"]["time_precision"] = $timePrecision;
|
||||
}
|
||||
|
||||
$endpoint = $this->options->getHttpSeriesEndpoint();
|
||||
return $this->httpClient->post($endpoint, $httpMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getDatabases()
|
||||
{
|
||||
$options = [
|
||||
"auth" => [$this->options->getUsername(), $this->options->getPassword()],
|
||||
];
|
||||
|
||||
$endpoint = $this->options->getHttpDatabaseEndpoint();
|
||||
|
||||
return $this->httpClient->get($endpoint, $options)->json();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function deleteDatabase($name)
|
||||
{
|
||||
$httpMessage = [
|
||||
"auth" => [$this->options->getUsername(), $this->options->getPassword()],
|
||||
];
|
||||
|
||||
$endpoint = $this->options->getHttpDatabaseEndpoint($name);
|
||||
return $this->httpClient->delete($endpoint, $httpMessage)->json();
|
||||
}
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB\Adapter;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\ParseException;
|
||||
use GuzzleHttp\Message\ResponseInterface;
|
||||
use InfluxDB\Exception\InfluxAuthorizationException;
|
||||
use InfluxDB\Exception\InfluxBadResponseException;
|
||||
use InfluxDB\Exception\InfluxGeneralException;
|
||||
use InfluxDB\Exception\InfluxNoSeriesException;
|
||||
use InfluxDB\Exception\InfluxUnexpectedResponseException;
|
||||
use InfluxDB\Options;
|
||||
|
||||
class HttpAdapter implements AdapterInterface, QueryableInterface
|
||||
{
|
||||
const STATUS_CODE_OK = 200;
|
||||
const STATUS_CODE_UNAUTHORIZED = 401;
|
||||
const STATUS_CODE_FORBIDDEN = 403;
|
||||
const STATUS_CODE_BAD_REQUEST = 400;
|
||||
|
||||
/**
|
||||
* @var \InfluxDB\Options
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
private $client;
|
||||
|
||||
/**
|
||||
* @param Options $options
|
||||
*/
|
||||
public function __construct(Options $options, Client $client = null)
|
||||
{
|
||||
$this->options = $options;
|
||||
$this->client = $client ?: new Client();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Options
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $body
|
||||
* @param array $query
|
||||
* @param bool $timePrecision
|
||||
* @return array
|
||||
*/
|
||||
protected function getRequest(array $body = [], array $query = [], $timePrecision = false)
|
||||
{
|
||||
$request = [
|
||||
"auth" => [$this->options->getUsername(), $this->options->getPassword()],
|
||||
"exceptions" => false
|
||||
];
|
||||
if (count($body)) {
|
||||
$request['body'] = json_encode($body);
|
||||
}
|
||||
if (count($query)) {
|
||||
$request['query'] = $query;
|
||||
}
|
||||
if ($timePrecision) {
|
||||
$request["query"]["time_precision"] = $timePrecision;
|
||||
}
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ResponseInterface $response
|
||||
* @return mixed
|
||||
* @throws \InfluxDB\Exception\InfluxGeneralException
|
||||
* @throws \InfluxDB\Exception\InfluxAuthorizationException
|
||||
* @throws \InfluxDB\Exception\InfluxNoSeriesException
|
||||
*/
|
||||
protected function parseResponse(ResponseInterface $response)
|
||||
{
|
||||
$statusCode = $response->getStatusCode();
|
||||
if ($statusCode >= 400 && $statusCode < 500) {
|
||||
$message = (string)$response->getBody();
|
||||
if (!$message) {
|
||||
$message = $response->getReasonPhrase();
|
||||
}
|
||||
switch ($statusCode) {
|
||||
case self::STATUS_CODE_UNAUTHORIZED:
|
||||
case self::STATUS_CODE_FORBIDDEN:
|
||||
throw new InfluxAuthorizationException($message, $statusCode);
|
||||
case self::STATUS_CODE_BAD_REQUEST:
|
||||
if (strpos($message, "Couldn't find series:") !== false) {
|
||||
throw new InfluxNoSeriesException($message, $statusCode);
|
||||
}
|
||||
}
|
||||
throw new InfluxGeneralException($message, $statusCode);
|
||||
} else if ($statusCode == self::STATUS_CODE_OK) {
|
||||
try {
|
||||
return $response->json();
|
||||
} catch (ParseException $ex) {
|
||||
throw new InfluxBadResponseException(
|
||||
sprintf("%s; Response is '%s'", $ex->getMessage(), (string)$response->getBody()),
|
||||
$ex->getCode(), $ex
|
||||
);
|
||||
}
|
||||
} else if ($statusCode > 200 && $statusCode < 300) {
|
||||
return true;
|
||||
}
|
||||
throw new InfluxUnexpectedResponseException((string)$response->getBody(), $statusCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $message
|
||||
* @param bool $timePrecision
|
||||
* @return \GuzzleHttp\Message\ResponseInterface
|
||||
*/
|
||||
public function send($message, $timePrecision = false)
|
||||
{
|
||||
try {
|
||||
$response = $this->client->post(
|
||||
$this->options->getHttpSeriesEndpoint(),
|
||||
$this->getRequest($message, [], $timePrecision)
|
||||
);
|
||||
} catch (\Exception $ex) {
|
||||
throw new InfluxGeneralException($ex->getMessage(), $ex->getCode(), $ex);
|
||||
}
|
||||
return $this->parseResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $query
|
||||
* @param bool $timePrecision
|
||||
* @return mixed
|
||||
*/
|
||||
public function query($query, $timePrecision = false)
|
||||
{
|
||||
try {
|
||||
$response = $this->client->get(
|
||||
$this->options->getHttpSeriesEndpoint(),
|
||||
$this->getRequest([], ["q" => $query], $timePrecision)
|
||||
);
|
||||
} catch (\Exception $ex) {
|
||||
throw new InfluxGeneralException($ex->getMessage(), $ex->getCode(), $ex);
|
||||
}
|
||||
return $this->parseResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDatabases()
|
||||
{
|
||||
try {
|
||||
$response = $this->client->get(
|
||||
$this->options->getHttpDatabaseEndpoint(),
|
||||
$this->getRequest()
|
||||
);
|
||||
} catch (\Exception $ex) {
|
||||
throw new InfluxGeneralException($ex->getMessage(), $ex->getCode(), $ex);
|
||||
}
|
||||
return $this->parseResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function createDatabase($name)
|
||||
{
|
||||
try {
|
||||
$response = $this->client->post(
|
||||
$this->options->getHttpDatabaseEndpoint(),
|
||||
$this->getRequest(["name" => $name])
|
||||
);
|
||||
} catch (\Exception $ex) {
|
||||
throw new InfluxGeneralException($ex->getMessage(), $ex->getCode(), $ex);
|
||||
}
|
||||
return $this->parseResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function deleteDatabase($name)
|
||||
{
|
||||
try {
|
||||
$response = $this->client->delete(
|
||||
$this->options->getHttpDatabaseEndpoint($name),
|
||||
$this->getRequest()
|
||||
);
|
||||
} catch (\Exception $ex) {
|
||||
throw new InfluxGeneralException($ex->getMessage(), $ex->getCode(), $ex);
|
||||
}
|
||||
return $this->parseResponse($response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
namespace InfluxDB\Adapter;
|
||||
|
||||
/**
|
||||
* The Adapter implement this interface if it supports database query
|
||||
*/
|
||||
interface QueryableInterface
|
||||
{
|
||||
/**
|
||||
* Make query into database
|
||||
* @param string $query
|
||||
* @param string|bool $timePrecision
|
||||
*/
|
||||
public function query($query, $timePrecision = false);
|
||||
|
||||
/**
|
||||
* Return database
|
||||
*/
|
||||
public function getDatabases();
|
||||
|
||||
/**
|
||||
* Create database
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public function createDatabase($name);
|
||||
|
||||
/**
|
||||
* Delete database by database
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public function deleteDatabase($name);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
namespace InfluxDB\Adapter;
|
||||
|
||||
use InfluxDB\Options;
|
||||
|
||||
/**
|
||||
* Clent adapter to call InfluxDb by UDP protocol
|
||||
* @link http://influxdb.com/docs/v0.6/api/reading_and_writing_data.html#writing-data-through-json-+-udp
|
||||
*/
|
||||
class UdpAdapter implements AdapterInterface
|
||||
{
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* @param Options $options
|
||||
*/
|
||||
public function __construct(Options $options)
|
||||
{
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Options
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function send($message, $timePrecision = false)
|
||||
{
|
||||
$message = json_encode($message);
|
||||
$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);
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB;
|
||||
|
||||
use InfluxDb\Adapter\QueryableInterface;
|
||||
use InfluxDB\Filter\FilterInterface;
|
||||
|
||||
/**
|
||||
* Client to manage request at InfluxDB
|
||||
*/
|
||||
class Client
|
||||
{
|
||||
/**
|
||||
* @var \InfluxDB\Adapter\AdapterInterface
|
||||
*/
|
||||
private $adapter;
|
||||
|
||||
/**
|
||||
* Set InfluxDB adapter
|
||||
* @param Adapter\AdapterInterface
|
||||
* @return Client
|
||||
*/
|
||||
public function setAdapter(Adapter\AdapterInterface $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get adapter
|
||||
* @return Adapter\AdapterInterface
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert point into series
|
||||
* @param string $name
|
||||
* @param array $value
|
||||
* @param bool|string $timePrecision
|
||||
* @return mixed
|
||||
*/
|
||||
public function mark($name, array $values, $timePrecision = false)
|
||||
{
|
||||
$data =[];
|
||||
|
||||
$timePrecision = $this->clearTimePrecision($timePrecision);
|
||||
|
||||
$data['name'] = $name;
|
||||
$data['columns'] = array_keys($values);
|
||||
$data['points'][] = array_values($values);
|
||||
|
||||
return $this->getAdapter()->send([$data], $timePrecision);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a query into database
|
||||
* @param string $query
|
||||
* @param bool|string $timePrecision
|
||||
* @return array
|
||||
*/
|
||||
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);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of databases
|
||||
* @return array
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create database by name
|
||||
* @param string $name
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete database by name
|
||||
* @param string $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);
|
||||
}
|
||||
|
||||
/**
|
||||
* List of time precision choose
|
||||
* @param string $timePrecision
|
||||
* @return bool|string
|
||||
*/
|
||||
private function clearTimePrecision($timePrecision)
|
||||
{
|
||||
switch ($timePrecision) {
|
||||
case 's':
|
||||
case 'u':
|
||||
case 'ms':
|
||||
break;
|
||||
default:
|
||||
$timePrecision = false;
|
||||
}
|
||||
|
||||
return $timePrecision;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB\Exception;
|
||||
|
||||
class InfluxAuthorizationException extends InfluxGeneralException
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB\Exception;
|
||||
|
||||
class InfluxBadResponseException extends InfluxGeneralException
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB\Exception;
|
||||
|
||||
class InfluxGeneralException extends \RuntimeException
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB\Exception;
|
||||
|
||||
class InfluxNoSeriesException extends InfluxGeneralException
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB\Exception;
|
||||
|
||||
class InfluxUnexpectedResponseException extends InfluxGeneralException
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -7,46 +7,54 @@ namespace InfluxDB;
|
||||
*/
|
||||
class Options
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $host;
|
||||
|
||||
/**
|
||||
* @var string|int
|
||||
*/
|
||||
private $port;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $username;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $password;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $protocol;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Set default options
|
||||
*/
|
||||
private $retentionPolicy;
|
||||
|
||||
private $tags;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->host = "localhost";
|
||||
$this->port = 8086;
|
||||
$this->username = "root";
|
||||
$this->password = "root";
|
||||
$this->setHost("localhost");
|
||||
$this->setPort(8086);
|
||||
$this->setUsername("root");
|
||||
$this->setPassword("root");
|
||||
$this->setProtocol("http");
|
||||
|
||||
$this->setRetentionPolicy("default");
|
||||
$this->setTags([]);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,19 +65,12 @@ class Options
|
||||
return $this->protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $protocol
|
||||
* @return Options
|
||||
*/
|
||||
public function setProtocol($protocol)
|
||||
{
|
||||
$this->protocol = $protocol;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHost()
|
||||
{
|
||||
return $this->host;
|
||||
@@ -81,111 +82,69 @@ class Options
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|int
|
||||
*/
|
||||
public function getPort()
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|int $port
|
||||
* @return Options
|
||||
*/
|
||||
public function setPort($port)
|
||||
{
|
||||
$this->port = $port;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $usarname
|
||||
* @return Options
|
||||
*/
|
||||
public function setUsername($username)
|
||||
{
|
||||
$this->username = $username;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $password
|
||||
* @return Options
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
$this->password = $password;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDatabase()
|
||||
{
|
||||
return $this->database;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $database
|
||||
* @return Options
|
||||
*/
|
||||
public function setDatabase($database)
|
||||
{
|
||||
$this->database = $database;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build http series edpoint
|
||||
* @return string
|
||||
*/
|
||||
public function getHttpSeriesEndpoint()
|
||||
{
|
||||
return sprintf(
|
||||
"%s://%s:%d/db/%s/series",
|
||||
"%s://%s:%d/write",
|
||||
$this->getProtocol(),
|
||||
$this->getHost(),
|
||||
$this->getPort(),
|
||||
$this->getDatabase()
|
||||
$this->getPort()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build http database endpoint by name
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function getHttpDatabaseEndpoint($name = false)
|
||||
public function getHttpQueryEndpoint($name = false)
|
||||
{
|
||||
$url = sprintf(
|
||||
"%s://%s:%d/db",
|
||||
"%s://%s:%d/query",
|
||||
$this->getProtocol(),
|
||||
$this->getHost(),
|
||||
$this->getPort()
|
||||
);
|
||||
|
||||
if ($name !== false) {
|
||||
$url .= "/{$name}";
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
namespace InfluxDB\Adapter;
|
||||
|
||||
use InfluxDB\Options;
|
||||
|
||||
class UdpAdapterTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider getMessages
|
||||
*/
|
||||
public function testRewriteMessages($input, $response)
|
||||
{
|
||||
$object = new UdpAdapter(new Options());
|
||||
$reflection = new \ReflectionClass(get_class($object));
|
||||
$method = $reflection->getMethod("serialize");
|
||||
$method->setAccessible(true);
|
||||
|
||||
$message = $method->invokeArgs($object, [$input]);
|
||||
|
||||
$this->assertEquals($response, $message);
|
||||
}
|
||||
|
||||
public function getMessages()
|
||||
{
|
||||
return [
|
||||
[
|
||||
[
|
||||
"time" => "2009-11-10T23:00:00Z",
|
||||
"points" => [
|
||||
[
|
||||
"measurement" => "cpu",
|
||||
"fields" => [
|
||||
"value" => 1,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
"cpu value=1 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,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
<<<EOF
|
||||
cpu,region=us-west,host=serverA,env=prod,target=servers,zone=1c cpu=18.12 1257894000000000000
|
||||
mem,region=us-west,host=serverA,env=prod,target=servers,zone=1c free=712432 1257894000000000000
|
||||
EOF
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class ClientFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
/**
|
||||
* @group factory
|
||||
* @group tcp
|
||||
* @dataProvider getTcpAdapters
|
||||
* @dataProvider getHttpAdapters
|
||||
*/
|
||||
public function testCreateTcpClient($adapter)
|
||||
{
|
||||
@@ -75,19 +75,11 @@ class ClientFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals("pass", $client->getAdapter()->getOptions()->getPassword());
|
||||
}
|
||||
|
||||
public function getTcpAdapters()
|
||||
{
|
||||
return [
|
||||
["InfluxDB\\Adapter\\GuzzleAdapter"],
|
||||
["InfluxDB\\Adapter\\HttpAdapter"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @group factory
|
||||
* @dataProvider getTcpAdapters
|
||||
* @dataProvider getHttpAdapters
|
||||
*/
|
||||
public function testCreateTcpClientWithFilter($adapter)
|
||||
public function testCreateTcpClientWithAllOptions($adapter)
|
||||
{
|
||||
$options = [
|
||||
"adapter" => [
|
||||
@@ -97,6 +89,11 @@ class ClientFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
"host" => "127.0.0.1",
|
||||
"username" => "user",
|
||||
"password" => "pass",
|
||||
"retention_policy" => "too_many_data",
|
||||
"tags" => [
|
||||
"region" => "eu",
|
||||
"env" => "prod",
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -107,5 +104,14 @@ class ClientFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
$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"],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,399 @@
|
||||
<?php
|
||||
namespace InfluxDB;
|
||||
|
||||
use DateTime;
|
||||
use InfluxDB\Adapter\GuzzleAdapter as InfluxHttpAdapter;
|
||||
use InfluxDB\Options;
|
||||
use InfluxDB\Adapter\UdpAdapter;
|
||||
use GuzzleHttp\Client as GuzzleHttpClient;
|
||||
|
||||
class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $rawOptions;
|
||||
private $object;
|
||||
private $options;
|
||||
|
||||
private $anotherClient;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$options = include __DIR__ . '/bootstrap.php';
|
||||
$this->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($adapter);
|
||||
$this->object = $influx;
|
||||
|
||||
$databases = $this->object->getDatabases();
|
||||
if (array_key_exists("values", $databases["results"][0]["series"][0])) {
|
||||
foreach ($databases["results"][0]["series"][0]["values"] as $database) {
|
||||
$this->object->deleteDatabase($database[0]);
|
||||
}
|
||||
}
|
||||
|
||||
$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"]);
|
||||
|
||||
sleep(1);
|
||||
|
||||
$body = $this->object->query("select * from \"tcp.test\"");
|
||||
$this->assertCount(1, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("mark", $body["results"][0]["series"][0]["columns"][1]);
|
||||
$this->assertEquals("element", $body["results"][0]["series"][0]["values"][0][1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group tcp
|
||||
*/
|
||||
public function testGuzzleHttpQueryApiWorksCorrectly()
|
||||
{
|
||||
$this->object->mark("tcp.test", ["mark" => "element"]);
|
||||
|
||||
sleep(1);
|
||||
|
||||
$body = $this->object->query("select * from \"tcp.test\"");
|
||||
|
||||
$this->assertCount(1, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("mark", $body["results"][0]["series"][0]["columns"][1]);
|
||||
$this->assertEquals("element", $body["results"][0]["series"][0]["values"][0][1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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"]);
|
||||
|
||||
sleep(1);
|
||||
|
||||
$body = $this->object->query("select mark from \"tcp.test\"", "s");
|
||||
|
||||
$this->assertCount(3, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("mark", $body["results"][0]["series"][0]["columns"][1]);
|
||||
$this->assertEquals("element", $body["results"][0]["series"][0]["values"][0][1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group tcp
|
||||
*/
|
||||
public function testWriteDirectMessages()
|
||||
{
|
||||
$this->object->mark([
|
||||
"tags" => [
|
||||
"dc" => "eu-west-1",
|
||||
],
|
||||
"points" => [
|
||||
[
|
||||
"measurement" => "vm-serie",
|
||||
"fields" => [
|
||||
"cpu" => 18.12,
|
||||
"free" => 712423,
|
||||
],
|
||||
],
|
||||
]
|
||||
]);
|
||||
|
||||
sleep(1);
|
||||
|
||||
$body = $this->object->query("select * from \"vm-serie\"");
|
||||
|
||||
$this->assertCount(1, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("cpu", $body["results"][0]["series"][0]["columns"][1]);
|
||||
$this->assertEquals(18.12, $body["results"][0]["series"][0]["values"][0][1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group tcp
|
||||
*/
|
||||
public function testOverrideDatabaseNameViaMessage()
|
||||
{
|
||||
$this->options->setDatabase("a-wrong-database");
|
||||
|
||||
$this->object->mark([
|
||||
"database" => "tcp.test",
|
||||
"points" => [
|
||||
[
|
||||
"measurement" => "vm-serie",
|
||||
"fields" => [
|
||||
"cpu" => 18.12,
|
||||
"free" => 712423,
|
||||
],
|
||||
],
|
||||
]
|
||||
]);
|
||||
|
||||
sleep(1);
|
||||
|
||||
$this->options->setDatabase("tcp.test");
|
||||
$body = $this->object->query("select * from \"vm-serie\"");
|
||||
|
||||
$this->assertCount(1, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("cpu", $body["results"][0]["series"][0]["columns"][1]);
|
||||
$this->assertEquals(18.12, $body["results"][0]["series"][0]["values"][0][1]);
|
||||
$this->assertEquals(712423, $body["results"][0]["series"][0]["values"][0][2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group udp
|
||||
*/
|
||||
public function testUdpIpWriteData()
|
||||
{
|
||||
$object = $this->createClientWithUdpAdapter();
|
||||
|
||||
$object->mark("udp.test", ["mark" => "element"]);
|
||||
sleep(1);
|
||||
$object->mark("udp.test", ["mark" => "element1"]);
|
||||
sleep(1);
|
||||
$object->mark("udp.test", ["mark" => "element2"]);
|
||||
sleep(1);
|
||||
$object->mark("udp.test", ["mark" => "element3"]);
|
||||
|
||||
// Wait UDP/IP message arrives
|
||||
sleep(2);
|
||||
|
||||
$this->options->setDatabase("udp.test");
|
||||
$body = $this->object->query("select * from \"udp.test\"");
|
||||
|
||||
$this->assertCount(4, $body["results"][0]["series"][0]["values"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group udp
|
||||
*/
|
||||
public function testSendMultipleMeasurementWithUdpIp()
|
||||
{
|
||||
$object = $this->createClientWithUdpAdapter();
|
||||
|
||||
$object->mark([
|
||||
"points" => [
|
||||
[
|
||||
"measurement" => "mem",
|
||||
"fields" => [
|
||||
"free" => 712423,
|
||||
],
|
||||
],
|
||||
[
|
||||
"measurement" => "cpu",
|
||||
"fields" => [
|
||||
"cpu" => 18.12,
|
||||
],
|
||||
],
|
||||
]
|
||||
]);
|
||||
|
||||
sleep(2);
|
||||
|
||||
$this->options->setDatabase("udp.test");
|
||||
$body = $this->object->query("select * from \"cpu\"");
|
||||
|
||||
$this->assertCount(1, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("cpu", $body["results"][0]["series"][0]["columns"][1]);
|
||||
$this->assertEquals(18.12, $body["results"][0]["series"][0]["values"][0][1]);
|
||||
|
||||
$body = $this->object->query("select * from \"mem\"");
|
||||
|
||||
$this->assertCount(1, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("free", $body["results"][0]["series"][0]["columns"][1]);
|
||||
$this->assertEquals(712423, $body["results"][0]["series"][0]["values"][0][1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group udp
|
||||
*/
|
||||
public function testWriteDirectMessageWithUdpIp()
|
||||
{
|
||||
$object = $this->createClientWithUdpAdapter();
|
||||
|
||||
$object->mark([
|
||||
"points" => [
|
||||
[
|
||||
"measurement" => "vm-serie",
|
||||
"fields" => [
|
||||
"cpu" => 18.12,
|
||||
"free" => 712423,
|
||||
],
|
||||
],
|
||||
]
|
||||
]);
|
||||
|
||||
sleep(2);
|
||||
|
||||
$this->options->setDatabase("udp.test");
|
||||
$body = $this->object->query("select * from \"vm-serie\"");
|
||||
|
||||
$this->assertCount(1, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("cpu", $body["results"][0]["series"][0]["columns"][1]);
|
||||
$this->assertEquals(18.12, $body["results"][0]["series"][0]["values"][0][1]);
|
||||
$this->assertEquals(712423, $body["results"][0]["series"][0]["values"][0][2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group udp
|
||||
* @group date
|
||||
*/
|
||||
public function testWriteDirectMessageWillPreserveActualTime()
|
||||
{
|
||||
$object = $this->createClientWithUdpAdapter();
|
||||
|
||||
$object->mark([
|
||||
"points" => [
|
||||
[
|
||||
"measurement" => "vm-serie",
|
||||
"fields" => [
|
||||
"cpu" => 18.12,
|
||||
"free" => 712423,
|
||||
],
|
||||
],
|
||||
]
|
||||
]);
|
||||
|
||||
sleep(2);
|
||||
|
||||
$this->options->setDatabase("udp.test");
|
||||
$body = $this->object->query("select * from \"vm-serie\"");
|
||||
|
||||
$this->assertCount(1, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("time", $body["results"][0]["series"][0]["columns"][0]);
|
||||
$saved = new DateTime($body["results"][0]["series"][0]["values"][0][0]);
|
||||
$this->assertEquals(date("Y-m-d"), $saved->format("Y-m-d"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group udp
|
||||
* @group date
|
||||
*/
|
||||
public function testWriteDirectMessageWillPreserveDatetime()
|
||||
{
|
||||
$object = $this->createClientWithUdpAdapter();
|
||||
|
||||
$object->mark([
|
||||
"time" => "2009-11-10T23:00:00Z",
|
||||
"points" => [
|
||||
[
|
||||
"measurement" => "vm-serie",
|
||||
"fields" => [
|
||||
"cpu" => 18.12,
|
||||
"free" => 712423,
|
||||
],
|
||||
],
|
||||
]
|
||||
]);
|
||||
|
||||
sleep(2);
|
||||
|
||||
$this->options->setDatabase("udp.test");
|
||||
$body = $this->object->query("select * from \"vm-serie\"");
|
||||
|
||||
$this->assertCount(1, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("time", $body["results"][0]["series"][0]["columns"][0]);
|
||||
$this->assertEquals("2009-11-10T23:00:00Z", $body["results"][0]["series"][0]["values"][0][0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group udp
|
||||
* @group tags
|
||||
*/
|
||||
public function testTagsAreWrittenCorrectly()
|
||||
{
|
||||
$object = $this->createClientWithUdpAdapter();
|
||||
|
||||
$object->mark([
|
||||
"tags" => [
|
||||
"region" => "eu",
|
||||
],
|
||||
"points" => [
|
||||
[
|
||||
"measurement" => "vm-serie",
|
||||
"tags" => [
|
||||
"dc" => "eu-west-1",
|
||||
"one" => "two",
|
||||
],
|
||||
"fields" => [
|
||||
"cpu" => 18.12,
|
||||
"free" => 712423,
|
||||
],
|
||||
],
|
||||
[
|
||||
"measurement" => "vm-serie",
|
||||
"tags" => [
|
||||
"dc" => "us-east-1",
|
||||
],
|
||||
"fields" => [
|
||||
"cpu" => 28.12,
|
||||
"free" => 412923,
|
||||
],
|
||||
],
|
||||
]
|
||||
]);
|
||||
|
||||
sleep(2);
|
||||
|
||||
$this->options->setDatabase("udp.test");
|
||||
$body = $this->object->query("select * from \"vm-serie\" where dc='eu-west-1'");
|
||||
|
||||
$this->assertCount(1, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("cpu", $body["results"][0]["series"][0]["columns"][1]);
|
||||
$this->assertEquals(18.12, $body["results"][0]["series"][0]["values"][0][1]);
|
||||
$this->assertEquals(712423, $body["results"][0]["series"][0]["values"][0][2]);
|
||||
}
|
||||
|
||||
public function testListActiveDatabses()
|
||||
{
|
||||
$databases = $this->object->getDatabases();
|
||||
|
||||
$this->assertCount(2, $databases["results"][0]["series"][0]["values"]);
|
||||
}
|
||||
|
||||
public function testCreateANewDatabase()
|
||||
{
|
||||
$this->object->createDatabase("walter");
|
||||
|
||||
sleep(1);
|
||||
|
||||
$databases = $this->object->getDatabases();
|
||||
|
||||
$this->assertCount(3, $databases["results"][0]["series"][0]["values"]);
|
||||
|
||||
$this->object->deleteDatabase("walter");
|
||||
}
|
||||
|
||||
private function createClientWithUdpAdapter()
|
||||
{
|
||||
$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"]);
|
||||
$options->setDatabase($rawOptions["udp"]["database"]);
|
||||
|
||||
$adapter = new UdpAdapter($options);
|
||||
$object = new Client($adapter);
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
<?php
|
||||
namespace InfluxDB;
|
||||
|
||||
use InfluxDB\Adapter\GuzzleAdapter as InfluxHttpAdapter;
|
||||
use InfluxDB\Options;
|
||||
use InfluxDB\Adapter\UdpAdapter;
|
||||
use GuzzleHttp\Client as GuzzleHttpClient;
|
||||
|
||||
class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $rawOptions;
|
||||
private $object;
|
||||
private $options;
|
||||
|
||||
private $anotherClient;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$options = include __DIR__ . '/../bootstrap.php';
|
||||
$this->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 tcp
|
||||
*/
|
||||
public function testGuzzleHttpWriteApiWithTimePrecision()
|
||||
{
|
||||
$this->object->mark("tcp.test", ["time" => 1410591552, "mark" => "element"], "s");
|
||||
|
||||
$body = $this->object->query("select mark from tcp.test", "ms");
|
||||
|
||||
$this->assertCount(1, $body[0]["points"]);
|
||||
$this->assertEquals("tcp.test", $body[0]["name"]);
|
||||
|
||||
$this->assertEquals("1410591552000", $body[0]["points"][0][0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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");
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
<?php
|
||||
namespace InfluxDB;
|
||||
|
||||
use InfluxDB\Adapter\HttpAdapter;
|
||||
use InfluxDB\Adapter\UdpAdapter;
|
||||
use InfluxDB\Filter\ColumnsPointsFilter;
|
||||
|
||||
class HttpAdapterTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $rawOptions;
|
||||
private $object;
|
||||
private $options;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$options = include __DIR__ . '/../bootstrap.php';
|
||||
$this->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;
|
||||
|
||||
$adapter = new HttpAdapter($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["tcp"]["database"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group tcp
|
||||
*/
|
||||
public function testApiWorksCorrectly()
|
||||
{
|
||||
$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 testQueryApiWorksCorrectly()
|
||||
{
|
||||
$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 testQueryApiWithMultipleData()
|
||||
{
|
||||
$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 testQueryApiWithTimePrecision()
|
||||
{
|
||||
$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 tcp
|
||||
*/
|
||||
public function testWriteApiWithTimePrecision()
|
||||
{
|
||||
$this->object->mark("tcp.test", ["time" => 1410591552, "mark" => "element"], "s");
|
||||
|
||||
$body = $this->object->query("select mark from tcp.test", "ms");
|
||||
|
||||
$this->assertCount(1, $body[0]["points"]);
|
||||
$this->assertEquals("tcp.test", $body[0]["name"]);
|
||||
|
||||
$this->assertEquals("1410591552000", $body[0]["points"][0][0]);
|
||||
}
|
||||
|
||||
public function testListActiveDatabses()
|
||||
{
|
||||
$databases = $this->object->getDatabases();
|
||||
|
||||
$this->assertCount(1, $databases);
|
||||
}
|
||||
|
||||
public function testCreateANewDatabase()
|
||||
{
|
||||
$this->object->createDatabase("walter");
|
||||
$databases = $this->object->getDatabases();
|
||||
|
||||
$this->assertCount(2, $databases);
|
||||
|
||||
$this->object->deleteDatabase("walter");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user