提交 8c9ea1e1 编写于 作者: G gccgdb1234

Merge branch 'develop' into docs/TD-15485

......@@ -18,13 +18,13 @@ import InstallOnLinux from "../../14-reference/03-connector/_windows_install.mdx
import VerifyLinux from "../../14-reference/03-connector/_verify_linux.mdx";
import VerifyWindows from "../../14-reference/03-connector/_verify_windows.mdx";
TDengine 提供 REST API,容许在任何平台的任何应用程序通过它访问 TDengine 运行实例,详细介绍请看 [REST API](/reference/rest-api/)。除 REST API 之外,TDengine 还提供多种编程语言的连接器方便用户开发应用程序,其中包括 C/C++、Java、Python、Go、Node.js、C# 等。 本节介绍如何使用连接器建立与 TDengine 的连接,给出连接器安装、连接的简单说明。关于各连接器的详细功能说明,请查看[连接器](https://docs.taosdata.com/reference/connector/)
TDengine 提供了丰富的应用程序开发接口,为了便于用户快速开发自己的应用,TDengine 支持了多种编程语言的连接器,其中官方连接器包括支持 C/C++、Java、Python、Go、Node.js、C# 和 Rust 的连接器。这些连接器支持使用原生接口(taosc)和 REST 接口(部分语言暂不支持)连接 TDengine 集群。社区开发者也贡献了多个非官方连接器,例如 ADO.NET 连接器、Lua 连接器和 PHP 连接器。
## 连接器建立连接的方式
连接器建立连接的方式,TDengine 提供两种:
1. 通过 taosAdapter 组件提供的 REST API 建立与 taosd 的连接,这种连接方式下文中简称"REST 连接“
1. 通过 taosAdapter 组件提供的 REST API 建立与 taosd 的连接,这种连接方式下文中简称“REST 连接”
2. 通过客户端驱动程序 taosc 直接与服务端程序 taosd 建立连接,这种连接方式下文中简称“原生连接”。
无论使用何种方式建立连接,连接器都提供了相同或相似的 API 操作数据库,都可以执行 SQL 语句,只是初始化连接的方式稍有不同,用户在使用上不会感到什么差别。
......
......@@ -5,6 +5,12 @@ title: Grafana
TDengine 能够与开源数据可视化系统 [Grafana](https://www.grafana.com/) 快速集成搭建数据监测报警系统,整个过程无需任何代码开发,TDengine 中数据表的内容可以在仪表盘(DashBoard)上进行可视化展现。关于 TDengine 插件的使用您可以在[GitHub](https://github.com/taosdata/grafanaplugin/blob/master/README.md)中了解更多。
## 前置条件
要让 Grafana 能正常添加 TDengine 数据源,需要以下几方面的准备工作。
- TDengine 集群已经部署并正常运行
- taosAdapter 已经安装并正常运行。具体细节请参考 [taosAdapter 的使用手册](/reference/taosadapter)
## 安装 Grafana
目前 TDengine 支持 Grafana 7.0 以上的版本。用户可以根据当前的操作系统,到 Grafana 官网下载安装包,并执行安装。下载地址如下:<https://grafana.com/grafana/download>。
......
---
sidebar_label: Introduction
docs/dingbo/en-titles
title: Introduction
toc_max_heading_level: 2
---
......
label: TDengine 介绍
label: Introduction
......@@ -66,6 +66,11 @@ public class TSDBDriver extends AbstractDriver {
* Just for Cloud Service
*/
public static final String PROPERTY_KEY_TOKEN = "token";
/**
* Use SSL (true/false) to communicate with the server. The default value is false.
* Just for Cloud Service
*/
public static final String PROPERTY_KEY_USE_SSL = "useSSL";
/**
* Key for the configuration file directory of TSDB client in properties instance
*/
......
......@@ -17,17 +17,21 @@ public class RestfulConnection extends AbstractConnection {
private final int port;
private final String url;
private final String database;
private final String auth;
private final boolean useSsl;
private final String token;
private boolean isClosed;
private final DatabaseMetaData metadata;
public RestfulConnection(String host, String port, Properties props, String database, String url, String token) {
public RestfulConnection(String host, String port, Properties props, String database, String url, String auth, boolean useSsl, String token) {
super(props);
this.host = host;
this.port = Integer.parseInt(port);
this.database = database;
this.url = url;
this.auth = "Basic " + auth;
this.useSsl = useSsl;
this.token = token;
this.metadata = new RestfulDatabaseMetaData(url, props.getProperty(TSDBDriver.PROPERTY_KEY_USER), this);
}
......@@ -88,4 +92,12 @@ public class RestfulConnection extends AbstractConnection {
public String getToken() {
return token;
}
public String getAuth() {
return auth;
}
public boolean isUseSsl() {
return useSsl;
}
}
\ No newline at end of file
package com.taosdata.jdbc.rs;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.taosdata.jdbc.*;
import com.taosdata.jdbc.AbstractDriver;
import com.taosdata.jdbc.TSDBDriver;
import com.taosdata.jdbc.TSDBError;
import com.taosdata.jdbc.TSDBErrorNumbers;
import com.taosdata.jdbc.enums.TimestampFormat;
import com.taosdata.jdbc.utils.HttpClientPoolUtil;
import com.taosdata.jdbc.ws.InFlightRequest;
......@@ -16,6 +17,7 @@ import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.sql.*;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
......@@ -52,7 +54,6 @@ public class RestfulDriver extends AbstractDriver {
String user;
String password;
String cloudToken = null;
try {
if (!props.containsKey(TSDBDriver.PROPERTY_KEY_USER))
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_USER_IS_REQUIRED);
......@@ -64,15 +65,25 @@ public class RestfulDriver extends AbstractDriver {
} catch (UnsupportedEncodingException e) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE, "unsupported UTF-8 concoding, user: " + props.getProperty(TSDBDriver.PROPERTY_KEY_USER) + ", password: " + props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD));
}
String cloudToken = null;
if (props.containsKey(TSDBDriver.PROPERTY_KEY_TOKEN)) {
cloudToken = props.getProperty(TSDBDriver.PROPERTY_KEY_TOKEN);
}
boolean useSsl = Boolean.parseBoolean(props.getProperty(TSDBDriver.PROPERTY_KEY_USE_SSL, "false"));
String loginUrl;
String batchLoad = info.getProperty(TSDBDriver.PROPERTY_KEY_BATCH_LOAD);
if (Boolean.parseBoolean(batchLoad)) {
loginUrl = "ws://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST)
String protocol = "ws";
if (useSsl) {
protocol = "wss";
}
loginUrl = protocol + "://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST)
+ ":" + props.getProperty(TSDBDriver.PROPERTY_KEY_PORT) + "/rest/ws";
if (null != cloudToken) {
loginUrl = loginUrl + "?token=" + cloudToken;
}
WSClient client;
Transport transport;
try {
......@@ -106,24 +117,13 @@ public class RestfulDriver extends AbstractDriver {
props.setProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, String.valueOf(TimestampFormat.TIMESTAMP));
return new WSConnection(url, props, transport, database);
}
loginUrl = "http://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST) + ":" + props.getProperty(TSDBDriver.PROPERTY_KEY_PORT) + "/rest/login/" + user + "/" + password + "";
if (null != cloudToken) {
loginUrl += "?token=" + cloudToken;
}
int poolSize = Integer.parseInt(props.getProperty("httpPoolSize", HttpClientPoolUtil.DEFAULT_MAX_PER_ROUTE));
boolean keepAlive = Boolean.parseBoolean(props.getProperty("httpKeepAlive", HttpClientPoolUtil.DEFAULT_HTTP_KEEP_ALIVE));
HttpClientPoolUtil.init(poolSize, keepAlive);
String result = HttpClientPoolUtil.execute(loginUrl);
JSONObject jsonResult = JSON.parseObject(result);
String status = jsonResult.getString("status");
String token = jsonResult.getString("desc");
if (!status.equals("succ")) {
throw new SQLException(jsonResult.getString("desc"));
}
RestfulConnection conn = new RestfulConnection(host, port, props, database, url, token);
String auth = Base64.getEncoder().encodeToString(
(user + ":" + password).getBytes(StandardCharsets.UTF_8));
RestfulConnection conn = new RestfulConnection(host, port, props, database, url, auth, useSsl, cloudToken);
if (database != null && !database.trim().replaceAll("\\s", "").isEmpty()) {
try (Statement stmt = conn.createStatement()) {
stmt.execute("use " + database);
......
......@@ -63,7 +63,7 @@ public class RestfulStatement extends AbstractStatement {
//如果执行了use操作应该将当前Statement的catalog设置为新的database
boolean result = true;
String response = HttpClientPoolUtil.execute(getUrl(), sql, this.conn.getToken());
String response = HttpClientPoolUtil.execute(getUrl(), sql, this.conn.getAuth());
JSONObject jsonObject = JSON.parseObject(response);
if (null == jsonObject) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "sql: " + sql);
......@@ -95,6 +95,10 @@ public class RestfulStatement extends AbstractStatement {
private String getUrl() throws SQLException {
String dbname = conn.getClientInfo(TSDBDriver.PROPERTY_KEY_DBNAME);
String protocol = "http";
// if (conn.isUseSsl()) {
// protocol = "https";
// }
if (dbname == null || dbname.trim().isEmpty()) {
dbname = "";
} else {
......@@ -105,13 +109,16 @@ public class RestfulStatement extends AbstractStatement {
switch (timestampFormat) {
case TIMESTAMP:
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlt" + dbname;
url = protocol + "://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlt" + dbname;
break;
case UTC:
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlutc" + dbname;
url = protocol + "://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlutc" + dbname;
break;
default:
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql" + dbname;
url = protocol + "://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql" + dbname;
}
if (this.conn.getToken() != null && !"".equals(this.conn.getToken().trim())) {
url = url + "?token=" + this.conn.getToken();
}
return url;
}
......
......@@ -5,7 +5,6 @@ import com.taosdata.jdbc.TSDBErrorNumbers;
import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HttpEntity;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
......@@ -97,12 +96,12 @@ public class HttpClientPoolUtil {
}
/*** execute POST request ***/
public static String execute(String uri, String data, String token) throws SQLException {
public static String execute(String uri, String data, String auth) throws SQLException {
HttpEntityEnclosingRequestBase method = (HttpEntityEnclosingRequestBase) getRequest(uri, HttpPost.METHOD_NAME);
method.setHeader(HTTP.CONTENT_TYPE, "text/plain");
method.setHeader(HTTP.CONN_DIRECTIVE, isKeepAlive);
method.setHeader("Authorization", "Taosd " + token);
method.setHeader("Authorization", auth);
method.setEntity(new StringEntity(data, StandardCharsets.UTF_8));
HttpContext context = HttpClientContext.create();
......
......@@ -84,7 +84,7 @@ public class HttpClientPoolUtilTest {
if (!status.equals("succ")) {
throw new SQLException(jsonResult.getString("desc"));
}
return token;
return "Basic " + token;
}
private boolean executeOneSql(String sql, String token) throws SQLException {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册