diff --git a/.gitignore b/.gitignore index 0a53632..f6f86ec 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,6 @@ target .classpath .project .settings + +# IDEA files +*.iml \ No newline at end of file diff --git a/README.md b/README.md index 0583a34..be243e6 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ SqlResult result = client.management().executeSql("CREATE TABLE MY_FIRST_TABL(" ## Data ingestion example ```java // CeresDBx options -final CeresDBxOptions opts = CeresDBxOptions.newBuilder("127.0.0.1", 8081) // +final CeresDBxOptions opts = CeresDBxOptions.newBuilder("127.0.0.1", 8831) // .tenant("test", "sub_test", "test_token") // tenant info // maximum retry times when write fails // (only some error codes will be retried, such as the routing table failure) @@ -149,9 +149,9 @@ final long t1 = t0 + 1000; final long t2 = t1 + 1000; final Rows data = Series.newBuilder("machine_metric") .tag("city", "Singapore") - .tag("ip", "127.0.01") + .tag("ip", "127.0.0.1") .toRowsBuilder() - // codes below organizes 3 lines data (3 timestamps) for the `cpu` and `mem` column, this will just transport once through network. CeresDB encourage practices like this, because the SDK could use efficient compression algorithm to reduce network overhead and also be friedly to the sever side. + // codes below organizes 3 lines data (3 timestamps) for the `cpu` and `mem` column, this will just transport once through network. CeresDB encourage practices like this, because the SDK could use efficient compression algorithm to reduce network traffic and also be friendly to the sever side. .field(t0, "cpu", FieldValue.withDouble(0.23)) // first row, first column .field(t0, "mem", FieldValue.withDouble(0.55)) // first row, second column .field(t1, "cpu", FieldValue.withDouble(0.25)) // second row, first column @@ -167,9 +167,9 @@ final Result wr = wf.get(); Assert.assertTrue(wr.isOk()); Assert.assertEquals(3, wr.getOk().getSuccess()); // `Result` class referenced the Rust language practice, provides rich functions (such as mapXXX, andThen) transforming the result value to improve programming efficiency. You can refer to the API docs for detail usage. -Assert.assertEquals(3, wr.mapOr(0, WriteOk::getSuccess())); +Assert.assertEquals(3, wr.mapOr(0, WriteOk::getSuccess).intValue()); Assert.assertEquals(0, wr.getOk().getFailed()); -Assert.assertEquals(0, wr.mapOr(-1, WriteOk::getFailed)); +Assert.assertEquals(0, wr.mapOr(-1, WriteOk::getFailed).intValue()); final QueryRequest queryRequest = QueryRequest.newBuilder() .forMetrics("machine_metric") // table name is optional. If not provided, SQL parser will parse the `ql` to get the table name and do the routing automaticly diff --git a/README_CN.md b/README_CN.md index 9513411..9579474 100644 --- a/README_CN.md +++ b/README_CN.md @@ -126,7 +126,7 @@ SqlResult result = client.management().executeSql("CREATE TABLE MY_FIRST_TABL(" ## 写入 Example ```java // CeresDBx options -final CeresDBxOptions opts = CeresDBxOptions.newBuilder("127.0.0.1", 8081) // +final CeresDBxOptions opts = CeresDBxOptions.newBuilder("127.0.0.1", 8831) // .tenant("test", "sub_test", "test_token") // 租户信息 .writeMaxRetries(1) // 写入失败重试次数上限(只有部分错误 code 才会重试,比如路由表失效) .readMaxRetries(1) // 查询失败重试次数上限(只有部分错误 code 才会重试,比如路由表失效) @@ -142,7 +142,7 @@ final long t1 = t0 + 1000; final long t2 = t1 + 1000; final Rows data = Series.newBuilder("machine_metric") .tag("city", "Singapore") - .tag("ip", "127.0.01") + .tag("ip", "127.0.0.1") .toRowsBuilder() // 下面针对 cpu、mem 两列,一次写入了三行数据(3 个时间戳),CeresDB 鼓励这种实践,SDK 可以通过高效的压缩来减少网络传输,并且对 server 端写入非常友好 .field(t0, "cpu", FieldValue.withDouble(0.23)) // 第 1 行第 1 列 @@ -160,9 +160,9 @@ final Result wr = wf.get(); Assert.assertTrue(wr.isOk()); Assert.assertEquals(3, wr.getOk().getSuccess()); // `Result` 类参考了 Rust 语言,提供了丰富的 mapXXX、andThen 类 function 方便对结果值进行转换,提高编程效率,欢迎参考 API 文档使用 -Assert.assertEquals(3, wr.mapOr(0, WriteOk::getSuccess())); +Assert.assertEquals(3, wr.mapOr(0, WriteOk::getSuccess).intValue()); Assert.assertEquals(0, wr.getOk().getFailed()); -Assert.assertEquals(0, wr.mapOr(-1, WriteOk::getFailed)); +Assert.assertEquals(0, wr.mapOr(-1, WriteOk::getFailed).intValue()); final QueryRequest queryRequest = QueryRequest.newBuilder() .forMetrics("machine_metric") // 表名可选填,不填的话 SQL Parser 会自动解析 ql 涉及到的表名并完成自动路由 diff --git a/ceresdb-example/src/test/java/com/ceresdb/ReadmeTest.java b/ceresdb-example/src/test/java/com/ceresdb/ReadmeTest.java new file mode 100644 index 0000000..9ee8e73 --- /dev/null +++ b/ceresdb-example/src/test/java/com/ceresdb/ReadmeTest.java @@ -0,0 +1,91 @@ +/* + * 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 com.ceresdb; + +import com.ceresdb.models.*; +import com.ceresdb.options.CeresDBxOptions; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; + +/** + * @author kesheng + */ +public class ReadmeTest { + + @Ignore + @Test + public void readmeTest() throws ExecutionException, InterruptedException { + final CeresDBxOptions opts = CeresDBxOptions.newBuilder("127.0.0.1", 8831) // ceresdb default grpc port 8831 + .tenant("test", "sub_test", "test_token") // tenant info + // maximum retry times when write fails + // (only some error codes will be retried, such as the routing table failure) + .writeMaxRetries(1) + // maximum retry times when read fails + // (only some error codes will be retried, such as the routing table failure) + .readMaxRetries(1).build(); + + final CeresDBxClient client = new CeresDBxClient(); + if (!client.init(opts)) { + throw new IllegalStateException("Fail to start CeresDBxClient"); + } + + final long t0 = System.currentTimeMillis(); + final long t1 = t0 + 1000; + final long t2 = t1 + 1000; + final Rows data = Series.newBuilder("machine_metric").tag("city", "Singapore").tag("ip", "127.0.0.1") + .toRowsBuilder() + // codes below organizes 3 lines data (3 timestamps) for the `cpu` and `mem` column, this will just transport once through network. CeresDB encourage practices like this, because the SDK could use efficient compression algorithm to reduce network traffic and also be friendly to the sever side. + .field(t0, "cpu", FieldValue.withDouble(0.23)) // first row, first column + .field(t0, "mem", FieldValue.withDouble(0.55)) // first row, second column + .field(t1, "cpu", FieldValue.withDouble(0.25)) // second row, first column + .field(t1, "mem", FieldValue.withDouble(0.56)) // second row, second column + .field(t2, "cpu", FieldValue.withDouble(0.21)) // third row, first column + .field(t2, "mem", FieldValue.withDouble(0.52)) // third row, second column + .build(); + + final CompletableFuture> wf = client.write(data); + // here the `future.get` is just for demonstration, a better async programming practice would be using the CompletableFuture API + final Result wr = wf.get(); + + Assert.assertTrue(wr.isOk()); + Assert.assertEquals(3, wr.getOk().getSuccess()); + // `Result` class referenced the Rust language practice, provides rich functions (such as mapXXX, andThen) transforming the result value to improve programming efficiency. You can refer to the API docs for detail usage. + Assert.assertEquals(3, wr.mapOr(0, WriteOk::getSuccess).intValue()); + Assert.assertEquals(0, wr.getOk().getFailed()); + Assert.assertEquals(0, wr.mapOr(-1, WriteOk::getFailed).intValue()); + + final QueryRequest queryRequest = QueryRequest.newBuilder().forMetrics("machine_metric") // table name is optional. If not provided, SQL parser will parse the `ql` to get the table name and do the routing automaticly + .ql("select timestamp, cpu, mem from machine_metric") // + .build(); + final CompletableFuture> qf = client.query(queryRequest); + // here the `future.get` is just for demonstration, a better async programming practice would be using the CompletableFuture API + final Result qr = qf.get(); + + Assert.assertTrue(qr.isOk()); + + final QueryOk queryOk = qr.getOk(); + + final List records = queryOk.mapToRecord().collect(Collectors.toList()); + } + +}