You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by hx...@apache.org on 2020/04/04 12:52:41 UTC

[incubator-iotdb] branch master updated: Make JDBC OSGi usable and added a feature file (#952)

This is an automated email from the ASF dual-hosted git repository.

hxd pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 8b3fcb2  Make JDBC OSGi usable and added a feature file (#952)
8b3fcb2 is described below

commit 8b3fcb239cf6613fe590eca541581ed520fd9b42
Author: etiennerobinet <61...@users.noreply.github.com>
AuthorDate: Sat Apr 4 14:52:32 2020 +0200

    Make JDBC OSGi usable and added a feature file (#952)
    
    * Make JDBC OSGi usable and added a feature file
    
    * Added OSGi JDBC Adapter for DataSource
---
 hadoop/pom.xml                                     |  55 ++++++++
 jdbc/README.md                                     |  23 ++++
 jdbc/osgi.bnd                                      |  31 +++++
 jdbc/pom.xml                                       |  97 ++++++++++++++
 jdbc/src/main/feature/feature.xml                  |  35 +++++
 .../main/java/org/apache/iotdb/jdbc/Activator.java |  40 ++++++
 .../org/apache/iotdb/jdbc/IoTDBDataSource.java     | 146 +++++++++++++++++++++
 .../apache/iotdb/jdbc/IoTDBDatabaseMetadata.java   |  11 +-
 .../java/org/apache/iotdb/jdbc/IoTDBDriver.java    |   4 +-
 .../apache/iotdb/jdbc/IoTDBPreparedStatement.java  |  92 +++++++++++--
 .../apache/iotdb/jdbc/IoTDbDataSourceFactory.java  |  79 +++++++++++
 .../resources/services/META-INF/java.sql.Driver    |  19 +++
 service-rpc/pom.xml                                |  55 ++++++++
 tsfile/pom.xml                                     |  55 ++++++++
 14 files changed, 727 insertions(+), 15 deletions(-)

diff --git a/hadoop/pom.xml b/hadoop/pom.xml
index cc54b34..3e01236 100644
--- a/hadoop/pom.xml
+++ b/hadoop/pom.xml
@@ -49,6 +49,61 @@
     </dependencies>
     <build>
         <plugins>
+            <!--
+        Generate an OSGI compatible MANIFEST file.
+      -->
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>bundle-manifest</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>manifest</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <exportScr>true</exportScr>
+                    <instructions>
+                        <_include>-bnd.bnd</_include>
+                        <_removeheaders>Bnd-LastModified,Built-By</_removeheaders>
+                        <Embed-Dependency>dependencies</Embed-Dependency>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <!--
+              Use the MANIFEST file generated by the maven-bundle-plugin.
+            -->
+            <plugin>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>3.1.0</version>
+                <configuration>
+                    <descriptorRefs>
+                        <descriptorRef>jar-with-dependencies</descriptorRef>
+                    </descriptorRefs>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>make-assembly</id>
+                        <!-- this is used for inheritance merges -->
+                        <phase>package</phase>
+                        <!-- bind to the packaging phase -->
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
             <!--using `mvn test` to run UT, `mvn verify` to run ITs
             Reference: https://antoniogoncalves.org/2012/12/13/lets-turn-integration-tests-with-maven-to-a-first-class-citizen/-->
             <plugin>
diff --git a/jdbc/README.md b/jdbc/README.md
index b2328cd..aac66bf 100644
--- a/jdbc/README.md
+++ b/jdbc/README.md
@@ -247,3 +247,26 @@ Here is a list of Status Code and related message:
 |601|NOT_LOGIN_ERROR|Has not logged in|
 |602|NO_PERMISSION_ERROR|No permissions for this operation|
 |603|UNINITIALIZED_AUTH_ERROR|Uninitialized authorizer|
+
+##How to try IoTDB JDBC using Karaf
+Suppose you have started Karaf 4.2.8.
+
+Put the iotdb-jdbc jars into your maven repository:
+`mvn install -DskipTests -pl iotdb-jdbc -am`
+
+In your Karaf client shell:
+feature:repo-add mvn:org.apache.iotdb/iotdb-jdbc/0.10.0-SNPASHOT/xml/features
+
+NOTE: that you must install JDBC first and then iotdb-feature
+
+```ini
+feature:install jdbc 
+feature:install iotdb-feature
+```
+Start a data source instance (supposed you have started IoTDB):
+
+```
+jdbc:ds-create -dc org.apache.iotdb.jdbc.IoTDBDriver -u root -p root -url "jdbc:iotdb://127.0.0.1:6667/" IoTDB
+```
+Try query:
+`jdbc:query IoTDB "select * from root"`
\ No newline at end of file
diff --git a/jdbc/osgi.bnd b/jdbc/osgi.bnd
new file mode 100644
index 0000000..1dea967
--- /dev/null
+++ b/jdbc/osgi.bnd
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+Bundle-SymbolicName: \
+  org.apache.iotdb.jdbc
+
+Bundle-Activator: \
+  org.apache.iotdb.jdbc.Activator
+
+Provide-Capability: \
+  osgi.service;objectClass=org.osgi.service.jdbc.DataSourceFactory;osgi.jdbc.driver.class=org.apache.iotdb.jdbc.IoTDBDriver;osgi.jdbc.driver.name=iotdb
+
+Private-Package: \
+  org.apache.iotdb.jdbc
+
+Import-Package: \
+  *
diff --git a/jdbc/pom.xml b/jdbc/pom.xml
index ca97a3b..c4f0526 100644
--- a/jdbc/pom.xml
+++ b/jdbc/pom.xml
@@ -46,10 +46,107 @@
             <artifactId>service-rpc</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.cmpn</artifactId>
+            <version>6.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.jdbc</groupId>
+            <artifactId>pax-jdbc-common</artifactId>
+            <version>1.4.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>6.0.0</version>
+        </dependency>
     </dependencies>
     <build>
+        <resources>
+            <resource>
+                <directory>src/main/feature</directory>
+                <filtering>true</filtering>
+                <targetPath>${project.build.directory}/feature</targetPath>
+            </resource>
+        </resources>
         <plugins>
             <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>resources</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <!--
+                  The feature plugin doesn't correctly attach the generated feature file so it
+                  wouldn't be signed and hashed during a release build. By manually-attaching it
+                  we make sure it's processed correctly.
+                -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>3.0.0</version>
+                <executions>
+                    <execution>
+                        <id>attach-features</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>attach-artifact</goal>
+                        </goals>
+                        <configuration>
+                            <artifacts>
+                                <artifact>
+                                    <file>target/feature/feature.xml</file>
+                                    <classifier>features</classifier>
+                                    <type>xml</type>
+                                </artifact>
+                            </artifacts>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <!--
+        Generate an OSGI compatible MANIFEST file.
+      -->
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>4.2.1</version>
+                <executions>
+                    <execution>
+                        <id>bundle-manifest</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>manifest</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <exportScr>true</exportScr>
+                    <instructions>
+                        <_include>osgi.bnd</_include>
+                        <_removeheaders>Bnd-LastModified,Built-By</_removeheaders>
+                        <Embed-Dependency>dependencies</Embed-Dependency>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <!--
+              Use the MANIFEST file generated by the maven-bundle-plugin.
+            -->
+            <plugin>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
                 <artifactId>maven-assembly-plugin</artifactId>
                 <version>3.1.0</version>
                 <configuration>
diff --git a/jdbc/src/main/feature/feature.xml b/jdbc/src/main/feature/feature.xml
new file mode 100644
index 0000000..eda59ec
--- /dev/null
+++ b/jdbc/src/main/feature/feature.xml
@@ -0,0 +1,35 @@
+<?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.
+
+-->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.5.0" name="driver-s7-feature">
+    <feature name="iotdb-feature" description="iotdb-feature" version="0.10.0.SNAPSHOT">
+        <details>Feature to install required Bundle to use IoTDB inside Karaf container</details>
+        <feature prerequisite="true">wrap</feature>
+        <feature>scr</feature>
+        <bundle>mvn:org.apache.iotdb/iotdb-jdbc/${project.version}</bundle>
+        <bundle>mvn:org.apache.iotdb/tsfile/${project.version}</bundle>
+        <bundle>mvn:org.apache.iotdb/service-rpc/${project.version}</bundle>
+        <bundle>mvn:org.apache.iotdb/hadoop-tsfile/${project.version}</bundle>
+        <bundle>mvn:org.apache.thrift/libthrift/0.13.0</bundle>
+        <bundle>mvn:org.xerial.snappy/snappy-java/1.1.7.2</bundle>
+        <bundle>mvn:commons-io/commons-io/2.5</bundle>
+        <bundle>wrap:mvn:org.apache.hadoop/hadoop-core/1.2.1</bundle>
+        <bundle>wrap:mvn:org.ops4j.pax.jdbc/pax-jdbc-common/1.4.5</bundle>
+    </feature>
+</features>
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/Activator.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/Activator.java
new file mode 100644
index 0000000..5c09771
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/Activator.java
@@ -0,0 +1,40 @@
+/*
+ * 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.jdbc;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.jdbc.DataSourceFactory;
+import org.apache.iotdb.jdbc.IoTDBDriver;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+public class Activator implements BundleActivator {
+
+    public void start(BundleContext context) {
+        IoTDbDataSourceFactory dsf = new IoTDbDataSourceFactory();
+        Dictionary<String, String> props = new Hashtable<String, String>();
+        props.put(DataSourceFactory.OSGI_JDBC_DRIVER_CLASS, IoTDBDriver.class.getName());
+        props.put(DataSourceFactory.OSGI_JDBC_DRIVER_NAME, "iotdb");
+        context.registerService(DataSourceFactory.class.getName(), dsf, props);
+    }
+
+    public void stop(BundleContext context) {
+        // EMPTY
+    }
+
+}
\ No newline at end of file
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDataSource.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDataSource.java
new file mode 100644
index 0000000..2d92a33
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDataSource.java
@@ -0,0 +1,146 @@
+/*
+ * 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.jdbc;
+
+import javax.sql.DataSource;
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.Properties;
+import org.apache.thrift.transport.TTransportException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IoTDBDataSource implements DataSource {
+
+    private final Logger logger = LoggerFactory.getLogger(IoTDBDataSource.class);
+
+    private String url;
+    private String user;
+    private String password;
+    private Properties properties;
+    private Integer port = 6667;
+
+    public IoTDBDataSource() {
+        properties = new Properties();
+    }
+
+    public IoTDBDataSource(String url, String user, String password, Integer port) {
+        this.url = url;
+        this.properties = new Properties();
+        properties.setProperty("user",user);
+        properties.setProperty("password",password);
+        if(port!=0) {
+            this.port = port;
+        }
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+        properties.setProperty("user",user);
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+        properties.setProperty("password",password);
+    }
+
+    public Integer getPort() {
+        return port;
+    }
+
+    public void setPort(Integer port) {
+        this.port = port;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    @Override
+    public Connection getConnection() throws SQLException {
+        try {
+            return new IoTDBConnection(url, properties);
+        } catch (TTransportException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @Override
+    public Connection getConnection(String username, String password) throws SQLException {
+       try {
+           Properties newProp = new Properties();
+           newProp.setProperty("user",username);
+           newProp.setProperty("password",password);
+           return new IoTDBConnection(url, newProp);
+       }
+       catch (Exception e){
+           e.printStackTrace();
+       }
+       return null;
+    }
+
+
+    @Override
+    public PrintWriter getLogWriter() throws SQLException {
+        return null;
+    }
+
+    @Override
+    public void setLogWriter(PrintWriter printWriter) throws SQLException {
+
+    }
+
+    @Override
+    public void setLoginTimeout(int i) throws SQLException {
+
+    }
+
+    @Override
+    public int getLoginTimeout() throws SQLException {
+        return 0;
+    }
+
+    @Override
+    public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
+        return null;
+    }
+
+    @Override
+    public <T> T unwrap(Class<T> aClass) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public boolean isWrapperFor(Class<?> aClass) throws SQLException {
+        return false;
+    }
+}
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
index 33ec2bb..e6438a5 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
@@ -35,6 +35,7 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
   private static final Logger logger = LoggerFactory
           .getLogger(IoTDBDatabaseMetadata.class);
   private static final String METHOD_NOT_SUPPORTED_STRING = "Method not supported";
+  private static final String DATABASE_VERSION = "0.10.0-SNAPSHOT";
   private long sessionId;
 
   IoTDBDatabaseMetadata(IoTDBConnection connection, TSIService.Iface client, long sessionId) {
@@ -171,7 +172,7 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
 
   @Override
   public String getDatabaseProductVersion() throws SQLException {
-    throw new SQLException(METHOD_NOT_SUPPORTED_STRING);
+   return DATABASE_VERSION;
   }
 
   @Override
@@ -181,7 +182,7 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
 
   @Override
   public int getDriverMajorVersion() {
-    return 0;
+    return 1;
   }
 
   @Override
@@ -191,12 +192,12 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
 
   @Override
   public String getDriverName() throws SQLException {
-    throw new SQLException(METHOD_NOT_SUPPORTED_STRING);
+    return org.apache.iotdb.jdbc.IoTDBDriver.class.getName();
   }
 
   @Override
   public String getDriverVersion() throws SQLException {
-    throw new SQLException(METHOD_NOT_SUPPORTED_STRING);
+    return DATABASE_VERSION;
   }
 
   @Override
@@ -489,7 +490,7 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
 
   @Override
   public String getUserName() throws SQLException {
-    throw new SQLException(METHOD_NOT_SUPPORTED_STRING);
+    return client.toString();
   }
 
   @Override
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDriver.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDriver.java
index 1b3f1db..7adfc96 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDriver.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDriver.java
@@ -28,9 +28,9 @@ import java.util.Properties;
 import java.util.logging.Logger;
 import java.util.regex.Pattern;
 import org.apache.thrift.transport.TTransportException;
+import org.osgi.service.component.annotations.Component;
 
-public class IoTDBDriver implements Driver {
-
+@Component(service = java.sql.Driver.class, immediate = true)public class IoTDBDriver implements Driver {
   private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory
       .getLogger(IoTDBDriver.class);
   /**
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBPreparedStatement.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBPreparedStatement.java
index 8853788..4ffe143 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBPreparedStatement.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBPreparedStatement.java
@@ -41,12 +41,10 @@ import java.time.Instant;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+
 import org.apache.iotdb.service.rpc.thrift.TSIService.Iface;
+import org.slf4j.LoggerFactory;
 
 public class IoTDBPreparedStatement extends IoTDBStatement implements PreparedStatement {
 
@@ -56,7 +54,7 @@ public class IoTDBPreparedStatement extends IoTDBStatement implements PreparedSt
   /**
    * save the SQL parameters as (paramLoc,paramValue) pairs.
    */
-  private final Map<Integer, String> parameters = new HashMap<>();
+  private final Map<Integer, String> parameters = new LinkedHashMap<>();
 
   IoTDBPreparedStatement(IoTDBConnection connection, Iface client,
       Long sessionId, String sql,
@@ -97,7 +95,83 @@ public class IoTDBPreparedStatement extends IoTDBStatement implements PreparedSt
 
   @Override
   public ParameterMetaData getParameterMetaData() throws SQLException {
-    throw new SQLException(METHOD_NOT_SUPPORTED_STRING);
+    return  new ParameterMetaData() {
+      @Override
+      public int getParameterCount() throws SQLException {
+        return parameters.size();
+      }
+      @Override
+      public int isNullable(int param) throws SQLException {
+        return ParameterMetaData.parameterNullableUnknown ;
+      }
+      @Override
+      public boolean isSigned(int param) throws SQLException {
+        try{
+          return Integer.parseInt(parameters.get(param))<0;
+        }
+        catch (Exception e){
+          return false;
+        }
+      }
+
+      @Override
+      public int getPrecision(int param) throws SQLException {
+        return parameters.get(param).length();
+      }
+
+      @Override
+      public int getScale(int param) throws SQLException {
+        try{
+          double d= Double.parseDouble(parameters.get(param));
+          if (d >= 1) { //we only need the fraction digits
+            d = d - (long) d;
+          }
+          if (d == 0) { //nothing to count
+            return 0;
+          }
+          d *= 10; //shifts 1 digit to left
+          int count = 1;
+          while (d - (long) d != 0) { //keeps shifting until there are no more fractions
+            d *= 10;
+            count++;
+          }
+          return count;
+        }
+        catch (Exception e){
+          return 0;
+        }
+      }
+
+      @Override
+      public int getParameterType(int param) throws SQLException {
+        return 0;
+      }
+
+      @Override
+      public String getParameterTypeName(int param) throws SQLException {
+        return null;
+      }
+
+      @Override
+      public String getParameterClassName(int param) throws SQLException {
+        return null;
+      }
+
+      @Override
+      public int getParameterMode(int param) throws SQLException {
+        return 0;
+      }
+
+      @Override
+      public <T> T unwrap(Class<T> iface) throws SQLException {
+        return null;
+      }
+
+      @Override
+      public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return false;
+      }
+    };
   }
 
   @Override
@@ -374,10 +448,12 @@ public class IoTDBPreparedStatement extends IoTDBStatement implements PreparedSt
 
     StringBuilder newSql = new StringBuilder(parts.get(0));
     for (int i = 1; i < parts.size(); i++) {
+      LoggerFactory.getLogger(IoTDBPreparedStatement.class).info("SQL {}",sql);
+      LoggerFactory.getLogger(IoTDBPreparedStatement.class).info("parameters {}",parameters.size());
       if (!parameters.containsKey(i)) {
         throw new SQLException("Parameter #" + i + " is unset");
       }
-      newSql.append(parameters.get(i));
+      newSql.append(parameters.get(i).toString());
       newSql.append(parts.get(i));
     }
     return newSql.toString();
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDbDataSourceFactory.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDbDataSourceFactory.java
new file mode 100644
index 0000000..f03c309
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDbDataSourceFactory.java
@@ -0,0 +1,79 @@
+/*
+ * 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.jdbc;
+
+import org.ops4j.pax.jdbc.common.BeanConfig;
+import org.osgi.service.jdbc.DataSourceFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.sql.ConnectionPoolDataSource;
+import javax.sql.DataSource;
+import javax.sql.XADataSource;
+import java.sql.Driver;
+import java.sql.SQLException;
+import java.util.Properties;
+
+public class IoTDbDataSourceFactory implements DataSourceFactory {
+    private final Logger logger = LoggerFactory.getLogger(IoTDbDataSourceFactory.class);
+    @Override
+    public DataSource createDataSource(Properties properties) throws SQLException {
+       IoTDBDataSource ds = new IoTDBDataSource();
+       setProperties(ds, properties);
+       return  ds;
+    }
+    public void setProperties(IoTDBDataSource ds, Properties prop){
+        Properties properties = (Properties)prop.clone();
+        String url = (String)properties.remove(DataSourceFactory.JDBC_URL);
+        if(url!=null){
+            ds.setUrl(url);
+            logger.info("URL set {}",url);
+        }
+
+        String user = (String) properties.remove(DataSourceFactory.JDBC_USER);
+        ds.setUser(user);
+        logger.info("User set {}",user);
+
+
+        String password = (String) properties.remove(DataSourceFactory.JDBC_PASSWORD);
+        ds.setPassword(password);
+        logger.info("Password set {}",password);
+
+
+        logger.info("Remaining properties {}", properties.size());
+
+        if (!properties.isEmpty()) {
+            BeanConfig.configure(ds, properties);
+        }
+    }
+
+    @Override
+    public ConnectionPoolDataSource createConnectionPoolDataSource(Properties properties) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public XADataSource createXADataSource(Properties properties) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Driver createDriver(Properties properties) throws SQLException {
+        IoTDBDriver driver = new IoTDBDriver();
+        return driver;
+    }
+}
diff --git a/jdbc/src/main/resources/services/META-INF/java.sql.Driver b/jdbc/src/main/resources/services/META-INF/java.sql.Driver
new file mode 100644
index 0000000..2758365
--- /dev/null
+++ b/jdbc/src/main/resources/services/META-INF/java.sql.Driver
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+org.apache.iotdb.jdbc.IoTDBDriver
\ No newline at end of file
diff --git a/service-rpc/pom.xml b/service-rpc/pom.xml
index ae04090..e257b46 100644
--- a/service-rpc/pom.xml
+++ b/service-rpc/pom.xml
@@ -43,6 +43,61 @@
     </dependencies>
     <build>
         <plugins>
+            <!--
+        Generate an OSGI compatible MANIFEST file.
+      -->
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>bundle-manifest</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>manifest</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <exportScr>true</exportScr>
+                    <instructions>
+                        <_include>-bnd.bnd</_include>
+                        <_removeheaders>Bnd-LastModified,Built-By</_removeheaders>
+                        <Embed-Dependency>dependencies</Embed-Dependency>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <!--
+              Use the MANIFEST file generated by the maven-bundle-plugin.
+            -->
+            <plugin>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>3.1.0</version>
+                <configuration>
+                    <descriptorRefs>
+                        <descriptorRef>jar-with-dependencies</descriptorRef>
+                    </descriptorRefs>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>make-assembly</id>
+                        <!-- this is used for inheritance merges -->
+                        <phase>package</phase>
+                        <!-- bind to the packaging phase -->
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
             <!--using `mvn test` to run UT, `mvn verify` to run ITs
             Reference: https://antoniogoncalves.org/2012/12/13/lets-turn-integration-tests-with-maven-to-a-first-class-citizen/-->
             <plugin>
diff --git a/tsfile/pom.xml b/tsfile/pom.xml
index a67630f..26ed68f 100644
--- a/tsfile/pom.xml
+++ b/tsfile/pom.xml
@@ -56,6 +56,61 @@
     </dependencies>
     <build>
         <plugins>
+            <!--
+        Generate an OSGI compatible MANIFEST file.
+      -->
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>bundle-manifest</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>manifest</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <exportScr>true</exportScr>
+                    <instructions>
+                        <_include>-bnd.bnd</_include>
+                        <_removeheaders>Bnd-LastModified,Built-By</_removeheaders>
+                        <Embed-Dependency>dependencies</Embed-Dependency>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <!--
+              Use the MANIFEST file generated by the maven-bundle-plugin.
+            -->
+            <plugin>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>3.1.0</version>
+                <configuration>
+                    <descriptorRefs>
+                        <descriptorRef>jar-with-dependencies</descriptorRef>
+                    </descriptorRefs>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>make-assembly</id>
+                        <!-- this is used for inheritance merges -->
+                        <phase>package</phase>
+                        <!-- bind to the packaging phase -->
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
             <!--using `mvn test` to run UT, `mvn verify` to run ITs
             Reference: https://antoniogoncalves.org/2012/12/13/lets-turn-integration-tests-with-maven-to-a-first-class-citizen/-->
             <plugin>