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 协议适配器']
                                                ]
                                        },
                                        {

Reply via email to