This is an automated email from the ASF dual-hosted git repository.
rong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 726f259 [IOTDB-1797][IOTDB-1799] Compatibility of Apache IoTDB with
InfluxDB - Intergration Framework (#4081)
726f259 is described below
commit 726f25969e971bad773604bb1deb6957f8e48810
Author: Xieqijun <[email protected]>
AuthorDate: Fri Oct 8 15:56:17 2021 +0800
[IOTDB-1797][IOTDB-1799] Compatibility of Apache IoTDB with InfluxDB -
Intergration Framework (#4081)
Co-authored-by: Steve Yurong Su <[email protected]>
---
.github/workflows/influxdb-protocol.yml | 64 ++++
.github/workflows/main-unix.yml | 3 +-
.github/workflows/main-win.yml | 31 +-
.github/workflows/sonar-coveralls.yml | 2 +-
docs/zh/UserGuide/API/InfluxDB-Protocol.md | 35 ++
influxdb-protocol/pom.xml | 135 +++++++
.../org/apache/iotdb/influxdb/IoTDBInfluxDB.java | 387 +++++++++++++++++++++
.../iotdb/influxdb/IoTDBInfluxDBFactory.java | 69 ++++
.../apache/iotdb/influxdb/IoTDBInfluxDBUtils.java | 36 ++
.../iotdb/influxdb/example/InfluxDBExample.java | 102 ++++++
.../influxdb/integration/IoTDBInfluxDBIT.java | 102 ++++++
site/src/main/.vuepress/config.js | 3 +-
12 files changed, 951 insertions(+), 18 deletions(-)
diff --git a/.github/workflows/influxdb-protocol.yml
b/.github/workflows/influxdb-protocol.yml
new file mode 100644
index 0000000..37e6ce9
--- /dev/null
+++ b/.github/workflows/influxdb-protocol.yml
@@ -0,0 +1,64 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: InfluxDB Protocol Test
+
+on:
+ push:
+ branches:
+ - master
+ - 'rel/*'
+ paths-ignore:
+ - 'docs/**'
+ pull_request:
+ branches:
+ - master
+ - 'rel/*'
+ paths-ignore:
+ - 'docs/**'
+ # allow manually run the action:
+ workflow_dispatch:
+
+env:
+ MAVEN_OPTS: -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false
-Dmaven.wagon.http.retryHandler.class=standard
-Dmaven.wagon.http.retryHandler.count=3
+
+jobs:
+ ubuntu:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Set up JDK 11
+ uses: actions/setup-java@v1
+ with:
+ java-version: 11
+
+ - name: Cache Maven packages
+ uses: actions/cache@v2
+ with:
+ path: ~/.m2
+ key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
+ restore-keys: ${{ runner.os }}-m2-
+
+ - name: Build Distribution Zip
+ run: ./mvnw.sh -B -DskipTests clean install
+
+ - name: Build Docker Image
+ run: |
+ docker build . -f docker/src/main/Dockerfile-single -t
"iotdb:$GITHUB_SHA"
+ docker images
+
+ - name: IT Test
+ shell: bash
+ run: |
+ cd influxdb-protocol && mvn -B clean compile post-integration-test
-Dtest.port.closed=true
diff --git a/.github/workflows/main-unix.yml b/.github/workflows/main-unix.yml
index ed8ef02..0bd7690 100644
--- a/.github/workflows/main-unix.yml
+++ b/.github/workflows/main-unix.yml
@@ -52,4 +52,5 @@ jobs:
- name: IT/UT Test
shell: bash
# we do not compile client-cpp for saving time, it is tested in
client.yml
- run: mvn -B clean post-integration-test -Dtest.port.closed=true -P
'!testcontainer'
+ # we can skip influxdb-protocol because it has been tested separately
in influxdb-protocol.yml
+ run: mvn -B clean post-integration-test -Dtest.port.closed=true -P
'!testcontainer,!influxdb-protocol'
diff --git a/.github/workflows/main-win.yml b/.github/workflows/main-win.yml
index 68cedab..7cc897a 100644
--- a/.github/workflows/main-win.yml
+++ b/.github/workflows/main-win.yml
@@ -29,18 +29,18 @@ jobs:
fail-fast: false
max-parallel: 20
matrix:
- java: [8, 11, 17]
- # to reduce the CI time cost; we split the whole CI to 3 parts:
- # modules except the server and the cluster:
- # -Diotdb.skip.test=true -Dcluster.skip.test=true
- # the server module:
- # -pl server -am -DskipTests=true -Diotdb.test.only=true
- # the cluster module:
- # -pl cluster -am -DskipTests=true -Dcluster.test.only=true
- # but we just add labels here to make the action name more graceful
- it_task: ['others',
- 'server',
- 'cluster'
+ java: [ 8, 11, 17 ]
+ # to reduce the CI time cost; we split the whole CI to 3 parts:
+ # modules except the server and the cluster:
+ # -Diotdb.skip.test=true -Dcluster.skip.test=true
+ # the server module:
+ # -pl server -am -DskipTests=true -Diotdb.test.only=true
+ # the cluster module:
+ # -pl cluster -am -DskipTests=true -Dcluster.test.only=true
+ # but we just add labels here to make the action name more graceful
+ it_task: [ 'others',
+ 'server',
+ 'cluster'
]
runs-on: windows-latest
@@ -100,13 +100,14 @@ jobs:
- name: Test Server Module with Maven
shell: bash
if: ${{ matrix.it_task == 'server'}}
- run: source ~/.bash_profile && mvn -B clean integration-test
-Dtest.port.closed=true -pl server -am -DskipTests=true -Diotdb.test.only=true
+ run: source ~/.bash_profile && mvn -B clean integration-test
-Dtest.port.closed=true -pl server -am -DskipTests=true -Diotdb.test.only=true
- name: Test Cluster Module with Maven
shell: bash
if: ${{ matrix.it_task == 'cluster'}}
- run: source ~/.bash_profile && mvn -B clean integration-test
-Dtest.port.closed=true -pl cluster -am -DskipTests=true
-Dcluster.test.only=true
+ run: source ~/.bash_profile && mvn -B clean integration-test
-Dtest.port.closed=true -pl cluster -am -DskipTests=true
-Dcluster.test.only=true
- name: Test Other Modules with Maven
shell: bash
if: ${{ matrix.it_task == 'others'}}
- run: source ~/.bash_profile && mvn -B clean integration-test
-Dtest.port.closed=true -Diotdb.test.skip=true -Dcluster.test.skip=true
+ # we can skip influxdb-protocol because it has been tested separately
in influxdb-protocol.yml
+ run: source ~/.bash_profile && mvn -B clean integration-test
-Dtest.port.closed=true -Diotdb.test.skip=true -Dcluster.test.skip=true -P
'!influxdb-protocol'
diff --git a/.github/workflows/sonar-coveralls.yml
b/.github/workflows/sonar-coveralls.yml
index 30ec9aa..33cc7ea 100644
--- a/.github/workflows/sonar-coveralls.yml
+++ b/.github/workflows/sonar-coveralls.yml
@@ -49,7 +49,7 @@ jobs:
restore-keys: ${{ runner.os }}-m2-
- name: IT/UT Test
# we do not compile client-cpp for saving time, it is tested in
client.yml
- run: mvn -B clean compile post-integration-test
-Dtest.port.closed=true -Pcode-coverage -P '!testcontainer'
+ run: mvn -B clean compile post-integration-test
-Dtest.port.closed=true -Pcode-coverage -P '!testcontainer,!influxdb-protocol'
- name: Code Coverage (Coveralls)
if: ${{ success() && (github.event_name == 'pull_request_target' ||
github.event_name == 'push')}}
run: |
diff --git a/docs/zh/UserGuide/API/InfluxDB-Protocol.md
b/docs/zh/UserGuide/API/InfluxDB-Protocol.md
new file mode 100644
index 0000000..e5ab023
--- /dev/null
+++ b/docs/zh/UserGuide/API/InfluxDB-Protocol.md
@@ -0,0 +1,35 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+# 切换方案
+
+假如您原先接入 InfluxDB 的业务代码如下:
+
+```java
+InfluxDB influxDB = InfluxDBFactory.connect(openurl, username, password);
+```
+
+您只需要将 InfluxDBFactory 替换为 **IoTDBInfluxDBFactory** 即可实现业务向 IoTDB 的切换:
+
+```java
+InfluxDB influxDB = IoTDBInfluxDBFactory.connect(openurl, username, password);
+```
+
diff --git a/influxdb-protocol/pom.xml b/influxdb-protocol/pom.xml
new file mode 100644
index 0000000..1d74bf1
--- /dev/null
+++ b/influxdb-protocol/pom.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.iotdb</groupId>
+ <artifactId>iotdb-parent</artifactId>
+ <version>0.13.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>influxdb-protocol</artifactId>
+ <name>InfluxDB Protocol</name>
+ <description>compatible with the protocol of influxdb.</description>
+ <properties>
+ <influxdb.test.skip>false</influxdb.test.skip>
+ <influxdb.it.skip>${influxdb.test.skip}</influxdb.it.skip>
+ <influxdb.ut.skip>${influxdb.test.skip}</influxdb.ut.skip>
+ <maven.compiler.source>8</maven.compiler.source>
+ <maven.compiler.target>8</maven.compiler.target>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.iotdb</groupId>
+ <artifactId>iotdb-session</artifactId>
+ <version>0.13.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.iotdb</groupId>
+ <artifactId>iotdb-thrift</artifactId>
+ <version>0.13.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.influxdb</groupId>
+ <artifactId>influxdb-java</artifactId>
+ <version>2.21</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr4-runtime</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <skipTests>${influxdb.ut.skip}</skipTests>
+ <systemProperties>
+ <IOTDB_CONF>src/test/resources</IOTDB_CONF>
+ </systemProperties>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>run-integration-tests</id>
+ <phase>integration-test</phase>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <skipTests>${influxdb.test.skip}</skipTests>
+ <skipITs>${influxdb.it.skip}</skipITs>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr4-maven-plugin</artifactId>
+ <version>${antlr4.version}</version>
+ <executions>
+ <execution>
+ <configuration>
+ <listener>false</listener>
+ <visitor>true</visitor>
+ </configuration>
+ <goals>
+ <goal>antlr4</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>3.2.0</version>
+ <executions>
+ <execution>
+ <id>add-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+
<source>${project.build.directory}/generated-sources/antlr4</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git
a/influxdb-protocol/src/main/java/org/apache/iotdb/influxdb/IoTDBInfluxDB.java
b/influxdb-protocol/src/main/java/org/apache/iotdb/influxdb/IoTDBInfluxDB.java
new file mode 100644
index 0000000..a7f030e
--- /dev/null
+++
b/influxdb-protocol/src/main/java/org/apache/iotdb/influxdb/IoTDBInfluxDB.java
@@ -0,0 +1,387 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.influxdb;
+
+import org.apache.iotdb.rpc.IoTDBConnectionException;
+import org.apache.iotdb.session.Session;
+
+import org.influxdb.BatchOptions;
+import org.influxdb.InfluxDB;
+import org.influxdb.InfluxDBException;
+import org.influxdb.dto.BatchPoints;
+import org.influxdb.dto.Point;
+import org.influxdb.dto.Pong;
+import org.influxdb.dto.Query;
+import org.influxdb.dto.QueryResult;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+public class IoTDBInfluxDB implements InfluxDB {
+
+ private static final String METHOD_NOT_SUPPORTED = "Method not supported.";
+
+ private final Session session;
+
+ public IoTDBInfluxDB(String url, String userName, String password) {
+ URI uri;
+ try {
+ uri = new URI(url);
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException("Unable to parse url: " + url, e);
+ }
+ session = new Session(uri.getHost(), uri.getPort(), userName, password);
+ openSession();
+ }
+
+ public IoTDBInfluxDB(String host, int rpcPort, String userName, String
password) {
+ session = new Session(host, rpcPort, userName, password);
+ openSession();
+ }
+
+ public IoTDBInfluxDB(Session session) {
+ this.session = session;
+ openSession();
+ }
+
+ public IoTDBInfluxDB(Session.Builder builder) {
+ session = builder.build();
+ openSession();
+ }
+
+ private void openSession() {
+ try {
+ session.open(false);
+ } catch (IoTDBConnectionException e) {
+ throw new InfluxDBException(e.getMessage());
+ }
+ }
+
+ @Override
+ public void write(final Point point) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public QueryResult query(final Query query) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void createDatabase(final String name) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void deleteDatabase(final String name) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public InfluxDB setDatabase(final String database) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void write(final String records) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void write(final List<String> records) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void write(final String database, final String retentionPolicy, final
Point point) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void write(final int udpPort, final Point point) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void write(final BatchPoints batchPoints) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void writeWithRetry(final BatchPoints batchPoints) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void write(
+ final String database,
+ final String retentionPolicy,
+ final ConsistencyLevel consistency,
+ final String records) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void write(
+ final String database,
+ final String retentionPolicy,
+ final ConsistencyLevel consistency,
+ final TimeUnit precision,
+ final String records) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void write(
+ final String database,
+ final String retentionPolicy,
+ final ConsistencyLevel consistency,
+ final List<String> records) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void write(
+ final String database,
+ final String retentionPolicy,
+ final ConsistencyLevel consistency,
+ final TimeUnit precision,
+ final List<String> records) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void write(final int udpPort, final String records) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void write(final int udpPort, final List<String> records) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void query(
+ final Query query,
+ final Consumer<QueryResult> onSuccess,
+ final Consumer<Throwable> onFailure) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void query(Query query, int chunkSize, Consumer<QueryResult> onNext) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void query(Query query, int chunkSize, BiConsumer<Cancellable,
QueryResult> onNext) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void query(Query query, int chunkSize, Consumer<QueryResult> onNext,
Runnable onComplete) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void query(
+ Query query,
+ int chunkSize,
+ BiConsumer<Cancellable, QueryResult> onNext,
+ Runnable onComplete) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void query(
+ Query query,
+ int chunkSize,
+ BiConsumer<Cancellable, QueryResult> onNext,
+ Runnable onComplete,
+ Consumer<Throwable> onFailure) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public QueryResult query(Query query, TimeUnit timeUnit) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public List<String> describeDatabases() {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public boolean databaseExists(final String name) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void flush() {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void close() {
+ try {
+ session.close();
+ } catch (IoTDBConnectionException e) {
+ throw new InfluxDBException(e.getMessage());
+ }
+ }
+
+ @Override
+ public InfluxDB setConsistency(final ConsistencyLevel consistencyLevel) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public InfluxDB setRetentionPolicy(final String retentionPolicy) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void createRetentionPolicy(
+ final String rpName,
+ final String database,
+ final String duration,
+ final String shardDuration,
+ final int replicationFactor,
+ final boolean isDefault) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void createRetentionPolicy(
+ final String rpName,
+ final String database,
+ final String duration,
+ final int replicationFactor,
+ final boolean isDefault) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void createRetentionPolicy(
+ final String rpName,
+ final String database,
+ final String duration,
+ final String shardDuration,
+ final int replicationFactor) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void dropRetentionPolicy(final String rpName, final String database) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public InfluxDB setLogLevel(LogLevel logLevel) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public InfluxDB enableGzip() {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public InfluxDB disableGzip() {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public boolean isGzipEnabled() {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public InfluxDB enableBatch() {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public InfluxDB enableBatch(BatchOptions batchOptions) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public InfluxDB enableBatch(
+ final int actions, final int flushDuration, final TimeUnit
flushDurationTimeUnit) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public InfluxDB enableBatch(
+ final int actions,
+ final int flushDuration,
+ final TimeUnit flushDurationTimeUnit,
+ final ThreadFactory threadFactory) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public InfluxDB enableBatch(
+ int actions,
+ int flushDuration,
+ TimeUnit flushDurationTimeUnit,
+ ThreadFactory threadFactory,
+ BiConsumer<Iterable<Point>, Throwable> exceptionHandler,
+ ConsistencyLevel consistency) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public InfluxDB enableBatch(
+ final int actions,
+ final int flushDuration,
+ final TimeUnit flushDurationTimeUnit,
+ final ThreadFactory threadFactory,
+ final BiConsumer<Iterable<Point>, Throwable> exceptionHandler) {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public void disableBatch() {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public boolean isBatchEnabled() {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public Pong ping() {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+
+ @Override
+ public String version() {
+ throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
+ }
+}
diff --git
a/influxdb-protocol/src/main/java/org/apache/iotdb/influxdb/IoTDBInfluxDBFactory.java
b/influxdb-protocol/src/main/java/org/apache/iotdb/influxdb/IoTDBInfluxDBFactory.java
new file mode 100644
index 0000000..b8b14cd
--- /dev/null
+++
b/influxdb-protocol/src/main/java/org/apache/iotdb/influxdb/IoTDBInfluxDBFactory.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.influxdb;
+
+import org.apache.iotdb.session.Session;
+
+import okhttp3.OkHttpClient;
+import org.influxdb.InfluxDB;
+
+public enum IoTDBInfluxDBFactory {
+ INSTANCE;
+
+ private IoTDBInfluxDBFactory() {}
+
+ public static InfluxDB connect(String url, String username, String password)
{
+ IoTDBInfluxDBUtils.checkNonEmptyString(url, "url");
+ IoTDBInfluxDBUtils.checkNonEmptyString(username, "username");
+ return new IoTDBInfluxDB(url, username, password);
+ }
+
+ public static InfluxDB connect(String host, int rpcPort, String userName,
String password) {
+ IoTDBInfluxDBUtils.checkNonEmptyString(host, "host");
+ IoTDBInfluxDBUtils.checkNonEmptyString(userName, "username");
+ return new IoTDBInfluxDB(host, rpcPort, userName, password);
+ }
+
+ public static InfluxDB connect(
+ String url, String username, String password, OkHttpClient.Builder
client) {
+ IoTDBInfluxDBUtils.checkNonEmptyString(url, "url");
+ IoTDBInfluxDBUtils.checkNonEmptyString(username, "username");
+ return connect(url, username, password);
+ }
+
+ public static InfluxDB connect(
+ String url,
+ String username,
+ String password,
+ OkHttpClient.Builder client,
+ InfluxDB.ResponseFormat responseFormat) {
+ IoTDBInfluxDBUtils.checkNonEmptyString(url, "url");
+ IoTDBInfluxDBUtils.checkNonEmptyString(username, "username");
+ return connect(url, username, password);
+ }
+
+ public static InfluxDB connect(Session.Builder builder) {
+ return new IoTDBInfluxDB(builder);
+ }
+
+ public static InfluxDB connect(Session session) {
+ return new IoTDBInfluxDB(session);
+ }
+}
diff --git
a/influxdb-protocol/src/main/java/org/apache/iotdb/influxdb/IoTDBInfluxDBUtils.java
b/influxdb-protocol/src/main/java/org/apache/iotdb/influxdb/IoTDBInfluxDBUtils.java
new file mode 100644
index 0000000..b4c5230
--- /dev/null
+++
b/influxdb-protocol/src/main/java/org/apache/iotdb/influxdb/IoTDBInfluxDBUtils.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.influxdb;
+
+public final class IoTDBInfluxDBUtils {
+
+ /**
+ * check whether the field is empty. If it is empty, an error will be thrown
+ *
+ * @param string string to check
+ * @param name prompt information in error throwing
+ */
+ public static void checkNonEmptyString(String string, String name)
+ throws IllegalArgumentException {
+ if (string == null || string.isEmpty()) {
+ throw new IllegalArgumentException("Expecting a non-empty string for " +
name);
+ }
+ }
+}
diff --git
a/influxdb-protocol/src/main/java/org/apache/iotdb/influxdb/example/InfluxDBExample.java
b/influxdb-protocol/src/main/java/org/apache/iotdb/influxdb/example/InfluxDBExample.java
new file mode 100644
index 0000000..4b8904d
--- /dev/null
+++
b/influxdb-protocol/src/main/java/org/apache/iotdb/influxdb/example/InfluxDBExample.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.influxdb.example;
+
+import org.apache.iotdb.influxdb.IoTDBInfluxDBFactory;
+
+import org.influxdb.InfluxDB;
+import org.influxdb.dto.Point;
+import org.influxdb.dto.Query;
+import org.influxdb.dto.QueryResult;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class InfluxDBExample {
+
+ private static InfluxDB influxDB;
+
+ public static void main(String[] args) throws Exception {
+ influxDB = IoTDBInfluxDBFactory.connect("http://127.0.0.1:6667", "root",
"root");
+ influxDB.createDatabase("database");
+ influxDB.setDatabase("database");
+ insertData();
+ queryData();
+ }
+
+ private static void insertData() {
+ Point.Builder builder = Point.measurement("student");
+ Map<String, String> tags = new HashMap<>();
+ Map<String, Object> fields = new HashMap<>();
+ tags.put("name", "xie");
+ tags.put("sex", "m");
+ fields.put("score", 87);
+ fields.put("tel", "110");
+ fields.put("country", "china");
+ builder.tag(tags);
+ builder.fields(fields);
+ builder.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS);
+ Point point = builder.build();
+ influxDB.write(point);
+
+ builder = Point.measurement("student");
+ tags = new HashMap<>();
+ fields = new HashMap<>();
+ tags.put("name", "xie");
+ tags.put("sex", "m");
+ tags.put("province", "anhui");
+ fields.put("score", 99);
+ fields.put("country", "china");
+ builder.tag(tags);
+ builder.fields(fields);
+ builder.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS);
+ point = builder.build();
+ influxDB.write(point);
+ }
+
+ private static void queryData() {
+ Query query;
+ QueryResult result;
+
+ // the selector query is parallel to the field value
+ query =
+ new Query(
+ "select * from student where (name=\"xie\" and sex=\"m\")or
time<now()-7d", "database");
+ result = influxDB.query(query);
+ System.out.println("query1 result:" +
result.getResults().get(0).getSeries().get(0).toString());
+
+ // use iotdb built-in func
+ query =
+ new Query(
+ "select
max(score),min(score),sum(score),count(score),spread(score),mean(score),first(score),last(score)
from student ",
+ "database");
+ result = influxDB.query(query);
+ System.out.println("query2 result:" +
result.getResults().get(0).getSeries().get(0).toString());
+
+ // aggregate query and selector query are parallel
+ query =
+ new Query(
+ "select
count(score),first(score),last(country),max(score),mean(score),median(score),min(score),mode(score),spread(score),stddev(score),sum(score)
from student where (name=\"xie\" and sex=\"m\")or score<99",
+ "database");
+ result = influxDB.query(query);
+ System.out.println("query3 result:" +
result.getResults().get(0).getSeries().get(0).toString());
+ }
+}
diff --git
a/influxdb-protocol/src/test/java/org/apache/iotdb/influxdb/integration/IoTDBInfluxDBIT.java
b/influxdb-protocol/src/test/java/org/apache/iotdb/influxdb/integration/IoTDBInfluxDBIT.java
new file mode 100644
index 0000000..f49cbd8
--- /dev/null
+++
b/influxdb-protocol/src/test/java/org/apache/iotdb/influxdb/integration/IoTDBInfluxDBIT.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.influxdb.integration;
+
+import org.apache.iotdb.influxdb.IoTDBInfluxDBFactory;
+import org.apache.iotdb.session.Session;
+
+import org.influxdb.InfluxDB;
+import org.influxdb.InfluxDBException;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.testcontainers.containers.GenericContainer;
+
+public class IoTDBInfluxDBIT {
+
+ private String host;
+ private Integer port;
+ private String username;
+ private String password;
+
+ @Rule
+ public GenericContainer IotDB =
+ new GenericContainer("apache/iotdb:latest").withExposedPorts(6667);
+
+ @Before
+ public void setUp() {
+ host = IotDB.getContainerIpAddress();
+ port = IotDB.getMappedPort(6667);
+ username = "root";
+ password = "root";
+ }
+
+ @Test
+ public void testConnect1() {
+ IoTDBInfluxDBFactory.connect("https://" + host + ":" + port, username,
password).close();
+ }
+
+ @Test
+ public void testConnect2() {
+ IoTDBInfluxDBFactory.connect(host, port, username, password).close();
+ }
+
+ @Test
+ public void testConnect3() {
+ IoTDBInfluxDBFactory.connect(
+ "https://" + host + ":" + port, username, password, new
okhttp3.OkHttpClient.Builder())
+ .close();
+ }
+
+ @Test
+ public void testConnect4() {
+ IoTDBInfluxDBFactory.connect(
+ "https://" + host + ":" + port,
+ username,
+ password,
+ new okhttp3.OkHttpClient.Builder(),
+ InfluxDB.ResponseFormat.JSON)
+ .close();
+ }
+
+ @Test
+ public void testConnect5() {
+ Session.Builder builder =
+ new
Session.Builder().host(host).port(port).username(username).password(password);
+ IoTDBInfluxDBFactory.connect(builder).close();
+ }
+
+ @Test
+ public void testConnect6() {
+ Session session =
+ new
Session.Builder().host(host).port(port).username(username).password(password).build();
+ session.setFetchSize(10000);
+ IoTDBInfluxDBFactory.connect(session).close();
+ }
+
+ @Test(expected = InfluxDBException.class)
+ public void testConnectRefusedFailed() {
+ InfluxDB influxDB = IoTDBInfluxDBFactory.connect(host, 80, username,
password);
+ }
+
+ @Test(expected = InfluxDBException.class)
+ public void testConnectAuthFailed() {
+ InfluxDB influxDB = IoTDBInfluxDBFactory.connect(host, port, "1", "1");
+ }
+}
diff --git a/site/src/main/.vuepress/config.js
b/site/src/main/.vuepress/config.js
index 6a9d52b..cf955b0 100644
--- a/site/src/main/.vuepress/config.js
+++ b/site/src/main/.vuepress/config.js
@@ -1501,7 +1501,8 @@ var config = {
['API/Programming-Cpp-Native-API','C++ 原生接口'],
['API/Programming-Go-Native-API','Go 原生接口'],
['API/Programming-TsFile-API','TsFile API'],
- ['API/Time-zone','时区']
+ ['API/Time-zone','时区'],
+
['API/InfluxDB-Protocol','InfluxDB 协议适配器']
]
},
{