diff --git a/configuration/conf/config.properties b/configuration/conf/config.properties
index 71523f9e3..b86bcda18 100644
--- a/configuration/conf/config.properties
+++ b/configuration/conf/config.properties
@@ -26,6 +26,9 @@
# REST 接口的授权头,默认是"root:root" 的 Base64 编码结果
# REST_AUTHORIZATION=Basic cm9vdDpyb290
+# REST 接口端口,默认 18080
+# REST_PORT=18080
+
# 所有被测数据库的用户名,如果为多个数据库,则要求保持一致
# USERNAME=root
diff --git a/core/src/main/java/cn/edu/tsinghua/iot/benchmark/conf/Config.java b/core/src/main/java/cn/edu/tsinghua/iot/benchmark/conf/Config.java
index bd52fe895..21d975482 100644
--- a/core/src/main/java/cn/edu/tsinghua/iot/benchmark/conf/Config.java
+++ b/core/src/main/java/cn/edu/tsinghua/iot/benchmark/conf/Config.java
@@ -101,6 +101,9 @@ public class Config {
/** Authorization header for REST interface */
private String REST_AUTHORIZATION = "Basic cm9vdDpyb290";
+ /** Port for REST interface */
+ private int REST_PORT = 18080;
+
// 初始化:双写模式
/** whether to operate another database */
private boolean IS_DOUBLE_WRITE = false;
@@ -717,6 +720,14 @@ public void setREST_AUTHORIZATION(String REST_AUTHORIZATION) {
this.REST_AUTHORIZATION = REST_AUTHORIZATION;
}
+ public int getREST_PORT() {
+ return REST_PORT;
+ }
+
+ public void setREST_PORT(int REST_PORT) {
+ this.REST_PORT = REST_PORT;
+ }
+
public long IncrementAndGetCURRENT_RECORD_LINE() {
return CURRENT_RECORD_LINE.incrementAndGet();
}
diff --git a/core/src/main/java/cn/edu/tsinghua/iot/benchmark/conf/ConfigDescriptor.java b/core/src/main/java/cn/edu/tsinghua/iot/benchmark/conf/ConfigDescriptor.java
index f069e6329..1a9955def 100644
--- a/core/src/main/java/cn/edu/tsinghua/iot/benchmark/conf/ConfigDescriptor.java
+++ b/core/src/main/java/cn/edu/tsinghua/iot/benchmark/conf/ConfigDescriptor.java
@@ -40,6 +40,7 @@
import java.util.Properties;
import java.util.stream.Collectors;
+import static cn.edu.tsinghua.iot.benchmark.tsdb.enums.DBInsertMode.INSERT_USE_REST;
import static cn.edu.tsinghua.iot.benchmark.tsdb.enums.DBInsertMode.INSERT_USE_SESSION_RECORDS;
import static cn.edu.tsinghua.iot.benchmark.tsdb.enums.DBInsertMode.INSERT_USE_SESSION_TABLET;
@@ -105,6 +106,12 @@ private void loadProps() {
"BENCHMARK_WORK_MODE", config.getBENCHMARK_WORK_MODE() + "")));
config.setREST_AUTHORIZATION(
properties.getProperty("REST_AUTHORIZATION", config.getREST_AUTHORIZATION()));
+ String restAuthorization = System.getenv("BENCHMARK_REST_AUTHORIZATION");
+ if (restAuthorization != null && !restAuthorization.isEmpty()) {
+ config.setREST_AUTHORIZATION(restAuthorization);
+ }
+ config.setREST_PORT(
+ Integer.parseInt(properties.getProperty("REST_PORT", config.getREST_PORT() + "")));
config.setTEST_MAX_TIME(
Long.parseLong(
properties.getProperty("TEST_MAX_TIME", config.getTEST_MAX_TIME() + "")));
@@ -731,9 +738,10 @@ boolean checkConfig() {
}
if (config.getIoTDB_DIALECT_MODE() == SQLDialect.TABLE
&& config.getDbConfig().getDB_SWITCH().getType() == DBType.IoTDB
- && config.getDbConfig().getDB_SWITCH().getInsertMode() != INSERT_USE_SESSION_TABLET) {
+ && config.getDbConfig().getDB_SWITCH().getInsertMode() != INSERT_USE_SESSION_TABLET
+ && config.getDbConfig().getDB_SWITCH().getInsertMode() != INSERT_USE_REST) {
LOGGER.error(
- "The iotdb table model only supports INSERT_USE_SESSION_TABLET! Please modify DB_SWITCH in the configuration file.");
+ "The iotdb table model only supports INSERT_USE_SESSION_TABLET and INSERT_USE_REST! Please modify DB_SWITCH in the configuration file.");
result = false;
}
// TODO Not supported TIME_DURATION、MAX_BY、MIN_BY. iotdb will report errors for these three
diff --git a/iotdb-2.0/pom.xml b/iotdb-2.0/pom.xml
index 0bcd1bb15..49eaba286 100644
--- a/iotdb-2.0/pom.xml
+++ b/iotdb-2.0/pom.xml
@@ -89,6 +89,12 @@
gson
${gson.version}
+
+ com.squareup.okhttp3
+ mockwebserver
+ ${okhttp3.version}
+ test
+
iot-benchmark-iotdb-2.0
diff --git a/iotdb-2.0/src/main/java/cn/edu/tsinghua/iot/benchmark/iotdb200/IoTDB.java b/iotdb-2.0/src/main/java/cn/edu/tsinghua/iot/benchmark/iotdb200/IoTDB.java
index e0fd39358..51e871df6 100644
--- a/iotdb-2.0/src/main/java/cn/edu/tsinghua/iot/benchmark/iotdb200/IoTDB.java
+++ b/iotdb-2.0/src/main/java/cn/edu/tsinghua/iot/benchmark/iotdb200/IoTDB.java
@@ -98,6 +98,11 @@ public class IoTDB implements IDatabase {
private static final Config config = ConfigDescriptor.getInstance().getConfig();
public IoTDB(DBConfig dbConfig) throws IoTDBConnectionException {
+ this(dbConfig, true);
+ }
+
+ protected IoTDB(DBConfig dbConfig, boolean initializeDmlStrategy)
+ throws IoTDBConnectionException {
this.dbConfig = dbConfig;
ROOT_SERIES_NAME = "root." + dbConfig.getDB_NAME();
DELETE_SERIES_SQL = "delete storage group root." + dbConfig.getDB_NAME() + ".*";
@@ -106,6 +111,10 @@ public IoTDB(DBConfig dbConfig) throws IoTDBConnectionException {
config.getIoTDB_DIALECT_MODE() == SQLDialect.TABLE
? new TableStrategy(dbConfig)
: new TreeStrategy(dbConfig);
+ if (!initializeDmlStrategy) {
+ dmlStrategy = null;
+ return;
+ }
switch (dbConfig.getDB_SWITCH()) {
case DB_IOT_200_REST:
case DB_IOT_200_SESSION_BY_TABLET:
diff --git a/iotdb-2.0/src/main/java/cn/edu/tsinghua/iot/benchmark/iotdb200/IoTDBRestAPI.java b/iotdb-2.0/src/main/java/cn/edu/tsinghua/iot/benchmark/iotdb200/IoTDBRestAPI.java
index 90d229523..e4373afc0 100644
--- a/iotdb-2.0/src/main/java/cn/edu/tsinghua/iot/benchmark/iotdb200/IoTDBRestAPI.java
+++ b/iotdb-2.0/src/main/java/cn/edu/tsinghua/iot/benchmark/iotdb200/IoTDBRestAPI.java
@@ -8,6 +8,7 @@
import cn.edu.tsinghua.iot.benchmark.entity.Batch.IBatch;
import cn.edu.tsinghua.iot.benchmark.entity.Record;
import cn.edu.tsinghua.iot.benchmark.entity.Sensor;
+import cn.edu.tsinghua.iot.benchmark.entity.enums.SQLDialect;
import cn.edu.tsinghua.iot.benchmark.exception.DBConnectException;
import cn.edu.tsinghua.iot.benchmark.measurement.Status;
import cn.edu.tsinghua.iot.benchmark.schema.schemaImpl.DeviceSchema;
@@ -19,25 +20,41 @@
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
+import okhttp3.ResponseBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.TimeUnit;
public class IoTDBRestAPI extends IoTDB {
private static final Logger LOGGER = LoggerFactory.getLogger(IoTDBRestAPI.class);
- private final OkHttpClient client = new OkHttpClient();
+ private static final Gson GSON = new Gson();
+ private final OkHttpClient client;
private final String baseURL;
+ private final DBConfig dbConfig;
protected final String ROOT_SERIES_NAME;
protected static final Config config = ConfigDescriptor.getInstance().getConfig();
public IoTDBRestAPI(DBConfig dbConfig) throws IoTDBConnectionException {
- super(dbConfig);
+ this(dbConfig, false);
+ }
+
+ IoTDBRestAPI(DBConfig dbConfig, boolean skipDmlStrategy) throws IoTDBConnectionException {
+ super(dbConfig, !skipDmlStrategy);
+ this.dbConfig = dbConfig;
+ long timeout = config.getWRITE_OPERATION_TIMEOUT_MS();
+ client =
+ new OkHttpClient.Builder()
+ .connectTimeout(timeout, TimeUnit.MILLISECONDS)
+ .readTimeout(timeout, TimeUnit.MILLISECONDS)
+ .writeTimeout(timeout, TimeUnit.MILLISECONDS)
+ .build();
String host = dbConfig.getHOST().get(0);
- baseURL = String.format("http://%s:18080", host);
- ROOT_SERIES_NAME = "root";
+ baseURL = String.format("http://%s:%d", host, config.getREST_PORT());
+ ROOT_SERIES_NAME = String.format("root.%s", dbConfig.getDB_NAME());
}
private Request constructRequest(String api, String json) {
@@ -54,15 +71,16 @@ public void init() throws TsdbException {}
@Override
public void cleanup() {
- String json = "{\"sql\":\"delete database root.**\"}";
- Request request = constructRequest("/rest/v2/nonQuery", json);
- try {
- Response response = client.newCall(request).execute();
- response.close();
- LOGGER.info("Finish clean data!");
- } catch (Exception e) {
- LOGGER.warn("No Data to Clean!");
+ if (isTableMode()) {
+ for (int group = 0; group < config.getGROUP_NUMBER(); group++) {
+ String database =
+ String.format("%s_%s%d", dbConfig.getDB_NAME(), config.getGROUP_NAME_PREFIX(), group);
+ executeNonQuery("drop database if exists " + database);
+ }
+ } else {
+ executeNonQuery("delete database root." + dbConfig.getDB_NAME() + ".**");
}
+ LOGGER.info("Finish clean data!");
}
@Override
@@ -71,21 +89,30 @@ public void close() throws TsdbException {}
@Override
public Status insertOneBatch(IBatch batch) throws DBConnectException {
String json = generatePayload(batch);
- Request request = constructRequest("/rest/v2/insertTablet", json);
- try {
- Response response = client.newCall(request).execute();
- response.close();
- return new Status(true);
+ String api = isTableMode() ? "/rest/table/v1/insertTablet" : "/rest/v2/insertTablet";
+ Request request = constructRequest(api, json);
+ try (Response response = client.newCall(request).execute()) {
+ ResponseBody responseBody = response.body();
+ String body = responseBody == null ? "" : responseBody.string();
+ boolean success = isSuccessful(response, body);
+ if (!success) {
+ LOGGER.warn("Insert failed: HTTP {}, body {}", response.code(), body);
+ }
+ return new Status(success);
} catch (IOException e) {
- LOGGER.warn("Insert failed!");
- return new Status(false);
+ LOGGER.warn("Insert failed: {}", e.toString());
+ return new Status(false, e, "REST insert failed");
}
}
private String generatePayload(IBatch batch) {
+ return isTableMode() ? generateTablePayload(batch) : generateTreePayload(batch);
+ }
+
+ private String generateTreePayload(IBatch batch) {
DeviceSchema schema = batch.getDeviceSchema();
IoTDBRestPayload payload = new IoTDBRestPayload();
- payload.device = String.format("root.%s", schema.getDevicePath());
+ payload.device = String.format("%s.%s", ROOT_SERIES_NAME, schema.getDevicePath());
payload.is_aligned = config.isIS_SENSOR_TS_ALIGNMENT();
List measurements = new ArrayList<>();
@@ -112,7 +139,39 @@ private String generatePayload(IBatch batch) {
payload.timestamps = timestamps;
payload.values = values;
- return new Gson().toJson(payload);
+ return GSON.toJson(payload);
+ }
+
+ private String generateTablePayload(IBatch batch) {
+ DeviceSchema schema = batch.getDeviceSchema();
+ IoTDBTableRestPayload payload = new IoTDBTableRestPayload();
+ payload.database = dbConfig.getDB_NAME() + "_" + schema.getGroup();
+ payload.table = schema.getTable();
+
+ for (Sensor sensor : schema.getSensors()) {
+ payload.column_names.add(sensor.getName());
+ payload.column_categories.add("FIELD");
+ payload.data_types.add(sensor.getSensorType().name);
+ }
+ payload.column_names.add("device_id");
+ payload.column_categories.add("TAG");
+ payload.data_types.add("STRING");
+ for (String key : schema.getTags().keySet()) {
+ payload.column_names.add(key);
+ payload.column_categories.add("TAG");
+ payload.data_types.add("STRING");
+ }
+
+ for (Record record : batch.getRecords()) {
+ payload.timestamps.add(record.getTimestamp());
+ List