blob: a877a4a861edac80fa4f16aff33067de280d92f1 [file]
/*
* 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;
import org.apache.iotdb.isession.ITableSession;
import org.apache.iotdb.rpc.subscription.config.TopicConstant;
import org.apache.iotdb.session.TableSessionBuilder;
import org.apache.iotdb.session.subscription.ISubscriptionTableSession;
import org.apache.iotdb.session.subscription.SubscriptionTableSessionBuilder;
import org.apache.iotdb.session.subscription.consumer.ISubscriptionTablePullConsumer;
import org.apache.iotdb.session.subscription.consumer.table.SubscriptionTablePullConsumerBuilder;
import org.apache.iotdb.session.subscription.payload.SubscriptionMessage;
import org.apache.iotdb.session.subscription.payload.SubscriptionRecordHandler;
import org.apache.tsfile.read.query.dataset.ResultSet;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
public class ConsensusTableModelSubscriptionSessionExample {
private static final String HOST = "127.0.0.1";
private static final int PORT = 6667;
private static final String USER = "root";
private static final String PASSWORD = "root";
private static final long POLL_TIMEOUT_MS = 1_000L;
private static final int MAX_POLL_ROUNDS = 20;
private static final int EXPECTED_ROWS = 5;
public static void main(final String[] args) throws Exception {
final long runId = System.currentTimeMillis();
final String database = "db_consensus_example_" + runId;
final String table = "events";
final String topic = "topic_consensus_table_example_" + runId;
final String consumerGroup = "cg_consensus_table_example_" + runId;
final String consumerId = "consumer_consensus_table_example_" + runId;
System.out.println("=== Consensus Subscription Table Example ===");
System.out.println("database = " + database);
System.out.println("table = " + table);
System.out.println("topic = " + topic);
System.out.println("consumerGroup = " + consumerGroup);
prepareBootstrapData(database, table);
createConsensusTopic(topic, database, table);
try (final ISubscriptionTablePullConsumer consumer =
new SubscriptionTablePullConsumerBuilder()
.host(HOST)
.port(PORT)
.username(USER)
.password(PASSWORD)
.consumerId(consumerId)
.consumerGroupId(consumerGroup)
.autoCommit(false)
.build()) {
consumer.open();
consumer.subscribe(topic);
writeRealtimeDataAfterSubscribe(database, table);
pollAndCommit(consumer, EXPECTED_ROWS);
consumer.unsubscribe(topic);
} finally {
dropTopic(topic);
}
}
private static void prepareBootstrapData(final String database, final String table)
throws Exception {
try (final ITableSession session = openTableSession()) {
session.executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS " + database);
session.executeNonQueryStatement("USE " + database);
session.executeNonQueryStatement(
"CREATE TABLE " + table + "(tag1 STRING TAG, s1 INT64 FIELD)");
session.executeNonQueryStatement(
"insert into " + table + "(tag1, s1, time) values ('bootstrap', 0, 0)");
session.executeNonQueryStatement("flush");
}
}
private static void createConsensusTopic(
final String topicName, final String database, final String table) throws Exception {
try (final ISubscriptionTableSession session =
new SubscriptionTableSessionBuilder()
.host(HOST)
.port(PORT)
.username(USER)
.password(PASSWORD)
.build()) {
final Properties config = new Properties();
config.put(TopicConstant.MODE_KEY, TopicConstant.MODE_CONSENSUS_VALUE);
config.put(TopicConstant.FORMAT_KEY, TopicConstant.FORMAT_RECORD_HANDLER_VALUE);
config.put(TopicConstant.DATABASE_KEY, database);
config.put(TopicConstant.TABLE_KEY, table);
config.put(TopicConstant.ORDER_MODE_KEY, TopicConstant.ORDER_MODE_PER_WRITER_VALUE);
session.createTopicIfNotExists(topicName, config);
}
}
private static void writeRealtimeDataAfterSubscribe(final String database, final String table)
throws Exception {
try (final ITableSession session = openTableSession()) {
session.executeNonQueryStatement("USE " + database);
for (int i = 1; i <= EXPECTED_ROWS; i++) {
session.executeNonQueryStatement(
String.format(
"insert into %s(tag1, s1, time) values ('device_%d', %d, %d)",
table, i, i * 10L, i));
}
session.executeNonQueryStatement("flush");
}
}
private static void pollAndCommit(
final ISubscriptionTablePullConsumer consumer, final int expectedRows) throws Exception {
int totalRows = 0;
int consecutiveEmptyPolls = 0;
for (int round = 1; round <= MAX_POLL_ROUNDS; round++) {
final List<SubscriptionMessage> messages = consumer.poll(POLL_TIMEOUT_MS);
if (messages.isEmpty()) {
consecutiveEmptyPolls++;
if (totalRows >= expectedRows && consecutiveEmptyPolls >= 3) {
break;
}
continue;
}
consecutiveEmptyPolls = 0;
for (final SubscriptionMessage message : messages) {
for (final ResultSet resultSet : message.getResultSets()) {
final SubscriptionRecordHandler.SubscriptionResultSet subscriptionResultSet =
(SubscriptionRecordHandler.SubscriptionResultSet) resultSet;
System.out.println(
"database = "
+ subscriptionResultSet.getDatabaseName()
+ ", table = "
+ subscriptionResultSet.getTableName());
System.out.println("Columns = " + subscriptionResultSet.getColumnNames());
System.out.println("Types = " + subscriptionResultSet.getColumnTypes());
while (subscriptionResultSet.hasNext()) {
System.out.println(subscriptionResultSet.nextRecord());
totalRows++;
}
}
}
consumer.commitSync(messages);
System.out.println("poll round " + round + ", totalRows = " + totalRows);
}
if (totalRows != expectedRows) {
throw new IllegalStateException(
"Expected "
+ expectedRows
+ " realtime rows, but consumed "
+ totalRows
+ ". Please check whether consensus subscription is enabled on the server.");
}
}
private static void dropTopic(final String topicName) throws Exception {
try (final ISubscriptionTableSession session =
new SubscriptionTableSessionBuilder()
.host(HOST)
.port(PORT)
.username(USER)
.password(PASSWORD)
.build()) {
session.dropTopicIfExists(topicName);
}
}
private static ITableSession openTableSession() throws Exception {
return new TableSessionBuilder()
.nodeUrls(Collections.singletonList(HOST + ":" + PORT))
.username(USER)
.password(PASSWORD)
.build();
}
}