diff --git a/CHANGELOG.md b/CHANGELOG.md index b16637d..9d32f71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ # Changelog +## unreleased +### Fixes +- [210](https://github.com/tobiasschuerg/InfluxDB-Client-for-Arduino/pull/210) - Allow setting of options without previously set connection params + ## 3.13.0 [2022-10-14] ### Features - [202](https://github.com/tobiasschuerg/InfluxDB-Client-for-Arduino/pull/202) - Added option to specify timestamp precision and do not send timestamp. Set using `WriteOption::useServerTimestamptrue)`. diff --git a/src/HTTPService.cpp b/src/HTTPService.cpp index dc7669b..ffaf9fc 100644 --- a/src/HTTPService.cpp +++ b/src/HTTPService.cpp @@ -51,7 +51,7 @@ HTTPService::HTTPService(ConnectionInfo *pConnInfo):_pConnInfo(pConnInfo) { if(!_httpClient) { _httpClient = new HTTPClient; } - _httpClient->setReuse(_httpOptions._connectionReuse); + _httpClient->setReuse(_pConnInfo->httpOptions._connectionReuse); _httpClient->setUserAgent(FPSTR(UserAgent)); }; @@ -74,15 +74,14 @@ HTTPService::~HTTPService() { } -void HTTPService::setHTTPOptions(const HTTPOptions & httpOptions) { - _httpOptions = httpOptions; - if(!_httpClient) { - _httpClient = new HTTPClient; - } - _httpClient->setReuse(_httpOptions._connectionReuse); - _httpClient->setTimeout(_httpOptions._httpReadTimeout); +void HTTPService::setHTTPOptions() { + if(!_httpClient) { + _httpClient = new HTTPClient; + } + _httpClient->setReuse(_pConnInfo->httpOptions._connectionReuse); + _httpClient->setTimeout(_pConnInfo->httpOptions._httpReadTimeout); #if defined(ESP32) - _httpClient->setConnectTimeout(_httpOptions._httpReadTimeout); + _httpClient->setConnectTimeout(_pConnInfo->httpOptions._httpReadTimeout); #endif } diff --git a/src/HTTPService.h b/src/HTTPService.h index 31f4158..25026c9 100644 --- a/src/HTTPService.h +++ b/src/HTTPService.h @@ -62,6 +62,8 @@ struct ConnectionInfo { bool insecure; // Error message of last failed operation String lastError; + // HTTP options + HTTPOptions httpOptions; }; /** @@ -89,8 +91,7 @@ friend class Test; #endif // Store retry timeout suggested by server after last request int _lastRetryAfter = 0; - // HTTP options - HTTPOptions _httpOptions; + protected: // Sets request params bool beforeRequest(const char *url); @@ -104,13 +105,10 @@ friend class Test; HTTPService(ConnectionInfo *pConnInfo); // Clean instance on deletion ~HTTPService(); - // Sets custom HTTP options. See HTTPOptions doc for more info. - // Must be called before calling any method initiating a connection to server. - // Example: - // service.setHTTPOptions(HTTPOptions().httpReadTimeout(20000)). - void setHTTPOptions(const HTTPOptions &httpOptions); + // Propagates http options to http client. + void setHTTPOptions(); // Returns current HTTPOption - HTTPOptions &getHTTPOptions() { return _httpOptions; } + HTTPOptions &getHTTPOptions() { return _pConnInfo->httpOptions; } // Performs HTTP POST by sending data. On success calls response call back bool doPOST(const char *url, const char *data, const char *contentType, int expectedCode, httpResponseCallback cb); // Performs HTTP POST by sending stream. On success calls response call back diff --git a/src/InfluxDbClient.cpp b/src/InfluxDbClient.cpp index 975d221..29052d2 100644 --- a/src/InfluxDbClient.cpp +++ b/src/InfluxDbClient.cpp @@ -144,7 +144,7 @@ void InfluxDBClient::clean() { } bool InfluxDBClient::setUrls() { - if(!_service && !init()) { + if(!_service) { return false; } INFLUXDB_CLIENT_DEBUG("[D] setUrls\n"); @@ -186,13 +186,10 @@ bool InfluxDBClient::setUrls() { } bool InfluxDBClient::setWriteOptions(WritePrecision precision, uint16_t batchSize, uint16_t bufferSize, uint16_t flushInterval, bool preserveConnection) { - if(!_service && !init()) { - return false; - } if(!setWriteOptions(WriteOptions().writePrecision(precision).batchSize(batchSize).bufferSize(bufferSize).flushInterval(flushInterval))) { return false; } - if(!setHTTPOptions(_service->getHTTPOptions().connectionReuse(preserveConnection))) { + if(!setHTTPOptions(_connInfo.httpOptions.connectionReuse(preserveConnection))) { return false; } return true; @@ -201,7 +198,7 @@ bool InfluxDBClient::setWriteOptions(WritePrecision precision, uint16_t batchSiz bool InfluxDBClient::setWriteOptions(const WriteOptions & writeOptions) { if(_writeOptions._writePrecision != writeOptions._writePrecision) { _writeOptions._writePrecision = writeOptions._writePrecision; - if(!setUrls()) { + if(_service && !setUrls()) { return false; } } @@ -212,7 +209,8 @@ bool InfluxDBClient::setWriteOptions(const WriteOptions & writeOptions) { } if(writeOptions._bufferSize > 0 && _writeOptions._bufferSize != writeOptions._bufferSize) { _writeOptions._bufferSize = writeOptions._bufferSize; - if(_writeOptions._bufferSize < 2*_writeOptions._batchSize) { + // If retrying, we need space for at least two batches + if(writeOptions._retryInterval && _writeOptions._bufferSize < 2*_writeOptions._batchSize) { _writeOptions._bufferSize = 2*_writeOptions._batchSize; INFLUXDB_CLIENT_DEBUG("[D] Changing buffer size to %d\n", _writeOptions._bufferSize); } @@ -231,10 +229,10 @@ bool InfluxDBClient::setWriteOptions(const WriteOptions & writeOptions) { } bool InfluxDBClient::setHTTPOptions(const HTTPOptions & httpOptions) { - if(!_service && !init()) { - return false; + _connInfo.httpOptions = httpOptions; + if(_service) { + _service->setHTTPOptions(); } - _service->setHTTPOptions(httpOptions); return true; } diff --git a/src/Options.cpp b/src/Options.cpp index ad33884..149aab8 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -41,3 +41,16 @@ WriteOptions& WriteOptions::addDefaultTag(const String &name, const String &valu delete [] s; return *this; } + +void WriteOptions::printTo(Print &dest) const { + dest.println("WriteOptions:"); + dest.print("\t_precision: "); dest.println((uint8_t)_writePrecision); + dest.print("\t_batchSize: "); dest.println(_batchSize); + dest.print("\t_bufferSize: "); dest.println(_bufferSize); + dest.print("\t_flushInterval: "); dest.println(_flushInterval); + dest.print("\t_retryInterval: "); dest.println(_retryInterval); + dest.print("\t_maxRetryInterval: "); dest.println(_maxRetryInterval); + dest.print("\t_maxRetryAttempts: "); dest.println(_maxRetryAttempts); + dest.print("\t_defaultTags: "); dest.println(_defaultTags); + dest.print("\t_useServerTimestamp: "); dest.println(_useServerTimestamp); +} diff --git a/src/Options.h b/src/Options.h index bde55b5..68a99a6 100644 --- a/src/Options.h +++ b/src/Options.h @@ -101,6 +101,8 @@ class WriteOptions { WriteOptions& clearDefaultTags() { _defaultTags = (char *)nullptr; return *this; } // If timestamp precision is set and useServerTimestamp is true, timestamp from point is not sent, or assigned. WriteOptions& useServerTimestamp(bool useServerTimestamp) { _useServerTimestamp = useServerTimestamp; return *this; } + // prints options values to a Print device. E.g. opts.printTo(Serial); + void printTo(Print &dest) const; }; /** diff --git a/test/Test.cpp b/test/Test.cpp index e10eebd..0fe2e99 100644 --- a/test/Test.cpp +++ b/test/Test.cpp @@ -44,7 +44,7 @@ void Test::run() { testOldAPI(); testBatch(); testLineProtocol(); - testEcaping(); + testEscaping(); testUrlEncode(); testIsValidID(); testFluxTypes(); @@ -56,7 +56,7 @@ void Test::run() { testFluxParserNilValue(); testFluxParserMultiTables(false); testFluxParserMultiTables(true); - testFluxParserErrorDiffentColumnsNum(); + testFluxParserErrorDifferentColumnsNum(); testFluxParserFluxError(); testFluxParserInvalidDatatype(); testFluxParserMissingDatatype(); @@ -140,6 +140,8 @@ void Test::testOptions() { TEST_ASSERT(c._writeOptions._retryInterval == 5); TEST_ASSERT(c._writeOptions._maxRetryAttempts == 3); TEST_ASSERT(c._writeOptions._maxRetryInterval == 300); + TEST_ASSERT(c._writeOptions._defaultTags == ""); + TEST_ASSERT(!c._writeOptions._useServerTimestamp); ConnectionInfo connInfo = { serverUrl: "http://localhost:8086", bucket: "", @@ -147,11 +149,8 @@ void Test::testOptions() { authToken: "my-token" }; HTTPService s(&connInfo); - TEST_ASSERT(!s._httpOptions._connectionReuse); - TEST_ASSERT(s._httpOptions._httpReadTimeout == 5000); - // Client has no params - TEST_ASSERT(!c.setWriteOptions(defWO)); - TEST_ASSERT(c.getLastErrorMessage() == "Invalid parameters"); + TEST_ASSERT(!s.getHTTPOptions()._connectionReuse); + TEST_ASSERT(s.getHTTPOptions()._httpReadTimeout == 5000); c.setConnectionParams("http://localhost:8086","my-org","my-bucket", "my-token"); TEST_ASSERT(c.setWriteOptions(defWO)); @@ -162,19 +161,21 @@ void Test::testOptions() { TEST_ASSERT(c._writeOptions._retryInterval == 1); TEST_ASSERT(c._writeOptions._maxRetryAttempts == 5); TEST_ASSERT(c._writeOptions._maxRetryInterval == 20); - + TEST_ASSERT(c._writeOptions._defaultTags == "tag1=val1,tag2=val2"); + TEST_ASSERT(c._writeOptions._useServerTimestamp); TEST_ASSERT(c.setHTTPOptions(defHO)); - TEST_ASSERT(c._service->_httpOptions._connectionReuse); - TEST_ASSERT(c._service->_httpOptions._httpReadTimeout == 20000); + TEST_ASSERT(c._service == nullptr); + TEST_ASSERT(c._connInfo.httpOptions._connectionReuse); + TEST_ASSERT(c._connInfo.httpOptions._httpReadTimeout == 20000); c.setWriteOptions(WritePrecision::MS, 15, 14, 70, false); TEST_ASSERT(c._writeOptions._writePrecision == WritePrecision::MS); TEST_ASSERT(c._writeOptions._batchSize == 15); TEST_ASSERTM(c._writeOptions._bufferSize == 30, String(c._writeOptions._bufferSize)); TEST_ASSERT(c._writeOptions._flushInterval == 70); - TEST_ASSERT(!c._service->_httpOptions._connectionReuse); - TEST_ASSERT(c._service->_httpOptions._httpReadTimeout == 20000); + TEST_ASSERT(!c._connInfo.httpOptions._connectionReuse); + TEST_ASSERT(c._connInfo.httpOptions._httpReadTimeout == 20000); defWO = WriteOptions().batchSize(100).bufferSize(7000); c.setWriteOptions(defWO); @@ -188,8 +189,8 @@ void Test::testOptions() { } -void Test::testEcaping() { - TEST_INIT("testEcaping"); +void Test::testEscaping() { + TEST_INIT("testEscaping"); Point p("t\re=s\nt\t_t e\"s,t"); p.addTag("ta=g","val=ue"); @@ -623,19 +624,22 @@ bool checkLinesParts(InfluxDBClient &client, size_t lineCount, int partCount) { void Test::testUseServerTimestamp() { TEST_INIT("testUseServerTimestamp"); - InfluxDBClient client(Test::apiUrl, Test::orgName, Test::bucketName, Test::token); + InfluxDBClient client; TEST_ASSERT(waitServer(Test::managementUrl, true)); // test no precision, no timestamp Point *p = createPoint("test1"); - TEST_ASSERT(client.writePoint(*p)); + + // Test no precision, custom timestamp + auto opts = WriteOptions().batchSize(1).bufferSize(10); + TEST_ASSERT(client.setWriteOptions(opts)); + client.setConnectionParams(Test::apiUrl, Test::orgName, Test::bucketName, Test::token); + TEST_ASSERT(client.writePoint(*p)); TEST_ASSERT(checkLinesParts(client, 1, 9)); - // Test no precision, custom timestamp - auto opts = WriteOptions().batchSize(2); - client.setWriteOptions(opts); + TEST_ASSERT(client.setWriteOptions(opts.batchSize(2))); Point *dir = new Point("dir"); dir->addTag("direction", "check-precision"); @@ -649,7 +653,7 @@ void Test::testUseServerTimestamp() { TEST_ASSERT(checkLinesParts(client, 1, 10)); // Test writerecitions + ts - client.setWriteOptions(opts.writePrecision(WritePrecision::S)); + TEST_ASSERT(client.setWriteOptions(opts.writePrecision(WritePrecision::S))); dir = new Point("dir"); dir->addTag("direction", "check-precision"); @@ -660,7 +664,7 @@ void Test::testUseServerTimestamp() { TEST_ASSERT(checkLinesParts(client, 1, 10)); //test sending only precision - client.setWriteOptions(opts.useServerTimestamp(true)); + TEST_ASSERT(client.setWriteOptions(opts.useServerTimestamp(true))); TEST_ASSERT(client.writePoint(*dir)); TEST_ASSERT(client.writePoint(*p)); @@ -2123,8 +2127,8 @@ void Test::testFluxParserMultiTables(bool chunked) { TEST_END(); } -void Test::testFluxParserErrorDiffentColumnsNum() { - TEST_INIT("testFluxParserErrorDiffentColumnsNum"); +void Test::testFluxParserErrorDifferentColumnsNum() { + TEST_INIT("testFluxParserErrorDifferentColumnsNum"); InfluxDBClient client(Test::apiUrl, Test::orgName, Test::bucketName, Test::token); TEST_ASSERT(waitServer(Test::managementUrl, true)); FluxQueryResult flux = client.query("testquery-diffNum-data"); diff --git a/test/Test.h b/test/Test.h index aea0ce4..a5af7d7 100644 --- a/test/Test.h +++ b/test/Test.h @@ -39,7 +39,7 @@ class Test : public TestBase { private: // tests static void testUtils(); static void testOptions(); - static void testEcaping(); + static void testEscaping(); static void testPoint(); static void testOldAPI(); static void testBatch(); @@ -51,7 +51,7 @@ class Test : public TestBase { static void testFluxParserSingleTable(); static void testFluxParserNilValue(); static void testFluxParserMultiTables(bool chunked); - static void testFluxParserErrorDiffentColumnsNum(); + static void testFluxParserErrorDifferentColumnsNum(); static void testFluxParserFluxError(); static void testFluxParserInvalidDatatype(); static void testFluxParserMissingDatatype(); diff --git a/test/test.ino b/test/test.ino index 73710bc..eed0180 100644 --- a/test/test.ino +++ b/test/test.ino @@ -81,6 +81,10 @@ void initInet() { while(!wifiOk && j<3) { Serial.print("Connecting to wifi " INFLUXDB_CLIENT_TESTING_SSID); WiFi.begin(INFLUXDB_CLIENT_TESTING_SSID, INFLUXDB_CLIENT_TESTING_PASS); +#ifdef ARDUINO_LOLIN_C3_MINI + // Necessary for Lolin C3 mini v1.0 + WiFi.setTxPower(WIFI_POWER_8_5dBm); +#endif while ((WiFi.status() != WL_CONNECTED) && (i < 30)) { Serial.print("."); delay(300);