From e9e5d8047dfcd3a40d6efc3706ff23423100ac12 Mon Sep 17 00:00:00 2001 From: "suzhi.yt" Date: Wed, 28 Aug 2024 14:22:47 +0800 Subject: [PATCH 1/2] direct load refactor --- .../rpc/bolt/transport/ObPacketFactory.java | 3 + .../rpc/direct_load/ObDirectLoadBucket.java | 183 ++++++ .../direct_load/ObDirectLoadConnection.java | 472 +++++++++++++++ .../ObDirectLoadConnectionFactory.java | 52 ++ .../rpc/direct_load/ObDirectLoadLogger.java | 158 +++++ .../rpc/direct_load/ObDirectLoadManager.java | 42 ++ .../direct_load/ObDirectLoadRuntimeInfo.java | 52 ++ .../direct_load/ObDirectLoadStatement.java | 355 ++++++++++++ .../rpc/direct_load/ObDirectLoadTraceId.java | 92 +++ .../exception/ObDirectLoadException.java | 42 ++ .../exception/ObDirectLoadExceptionUtil.java | 89 +++ .../ObDirectLoadIllegalArgumentException.java | 37 ++ .../ObDirectLoadIllegalStateException.java | 37 ++ .../ObDirectLoadInterruptedException.java | 37 ++ .../ObDirectLoadNotSupportedException.java | 29 + .../ObDirectLoadNullPointerException.java | 33 ++ ...ObDirectLoadRpcChecksumErrorException.java | 26 + .../exception/ObDirectLoadRpcException.java | 42 ++ .../ObDirectLoadRpcResponseNullException.java | 26 + .../ObDirectLoadRpcSendFailedException.java | 26 + .../ObDirectLoadRpcTimeoutException.java | 26 + .../ObDirectLoadRuntimeException.java | 42 ++ .../ObDirectLoadServerException.java | 43 ++ .../ObDirectLoadServerStatusException.java | 48 ++ .../ObDirectLoadTimeoutException.java | 33 ++ .../ObDirectLoadUnexpectedException.java | 29 + .../ObDirectLoadStatementAbortTask.java | 111 ++++ .../ObDirectLoadStatementBeginTask.java | 271 +++++++++ .../ObDirectLoadStatementCommitTask.java | 183 ++++++ .../ObDirectLoadStatementExecutor.java | 545 ++++++++++++++++++ .../ObDirectLoadStatementHeartBeatTask.java | 188 ++++++ .../ObDirectLoadStatementWriteTask.java | 122 ++++ ...ObDirectLoadStatementAsyncPromiseTask.java | 68 +++ .../ObDirectLoadStatementCompleteFuture.java | 64 ++ .../ObDirectLoadStatementDefaultPromise.java | 119 ++++ .../ObDirectLoadStatementFailedFuture.java | 43 ++ .../future/ObDirectLoadStatementFuture.java | 103 ++++ .../future/ObDirectLoadStatementPromise.java | 34 ++ .../ObDirectLoadStatementPromiseTask.java | 30 + .../ObDirectLoadStatementSucceedFuture.java | 39 ++ .../protocol/ObDirectLoadProtocol.java | 43 ++ .../protocol/ObDirectLoadProtocolFactory.java | 83 +++ .../direct_load/protocol/ObDirectLoadRpc.java | 39 ++ .../payload/ObDirectLoadAbortRpc.java | 32 + .../payload/ObDirectLoadBeginRpc.java | 56 ++ .../payload/ObDirectLoadCommitRpc.java | 32 + .../payload/ObDirectLoadGetStatusRpc.java | 36 ++ .../payload/ObDirectLoadHeartBeatRpc.java | 37 ++ .../payload/ObDirectLoadInsertRpc.java | 38 ++ .../payload}/ObTableLoadClientStatus.java | 5 +- .../protocol/v0/ObDirectLoadProtocolV0.java | 72 +++ .../v0/payload/ObDirectLoadAbortRpcV0.java | 68 +++ .../v0/payload/ObDirectLoadBeginRpcV0.java | 134 +++++ .../v0/payload/ObDirectLoadCommitRpcV0.java | 68 +++ .../v0/payload/ObDirectLoadDefaultRpcV0.java | 99 ++++ .../payload/ObDirectLoadGetStatusRpcV0.java | 81 +++ .../payload/ObDirectLoadHeartBeatRpcV0.java | 82 +++ .../v0/payload/ObDirectLoadInsertRpcV0.java | 80 +++ .../impl}/ObTableDirectLoadAbortArg.java | 6 +- .../impl}/ObTableDirectLoadBeginArg.java | 69 ++- .../impl}/ObTableDirectLoadBeginRes.java | 26 +- .../impl}/ObTableDirectLoadCommitArg.java | 6 +- .../impl}/ObTableDirectLoadGetStatusArg.java | 6 +- .../impl}/ObTableDirectLoadGetStatusRes.java | 7 +- .../impl}/ObTableDirectLoadHeartBeatArg.java | 6 +- .../impl}/ObTableDirectLoadHeartBeatRes.java | 7 +- .../impl}/ObTableDirectLoadInsertArg.java | 37 +- .../util/ObDirectLoadIntervalUtil.java | 40 ++ .../direct_load/util/ObDirectLoadUtil.java | 269 +++++++++ .../protocol/packet/ObRpcPacketHeader.java | 15 + .../rpc/protocol/payload/AbstractPayload.java | 16 + .../rpc/protocol/payload/ObPayload.java | 5 + .../rpc/protocol/payload/ResultCodes.java | 1 + .../ObLoadDupActionType.java | 2 +- .../direct_load/ObTableDirectLoadRequest.java | 15 + .../rpc/table/ObDirectLoadBucket.java | 109 ---- .../rpc/table/ObDirectLoadObjRow.java | 124 ---- .../rpc/table/ObDirectLoadParameter.java | 93 --- .../rpc/table/ObTableDirectLoad.java | 368 ------------ .../alipay/oceanbase/rpc/util/ObByteBuf.java | 25 + .../oceanbase/rpc/util/Serialization.java | 77 +++ .../rpc/util/TableClientLoggerFactory.java | 11 + .../log/log4j/log-conf.xml | 16 + .../log/log4j2/log-conf.xml | 17 + .../log/logback/log-conf.xml | 31 + 85 files changed, 5737 insertions(+), 726 deletions(-) create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadBucket.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadConnection.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadConnectionFactory.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadLogger.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadManager.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadRuntimeInfo.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadStatement.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadTraceId.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadExceptionUtil.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadIllegalArgumentException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadIllegalStateException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadInterruptedException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadNotSupportedException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadNullPointerException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcChecksumErrorException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcResponseNullException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcSendFailedException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcTimeoutException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRuntimeException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadServerException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadServerStatusException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadTimeoutException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadUnexpectedException.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementAbortTask.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementBeginTask.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementCommitTask.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementExecutor.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementHeartBeatTask.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementWriteTask.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementAsyncPromiseTask.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementCompleteFuture.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementDefaultPromise.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementFailedFuture.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementFuture.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementPromise.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementPromiseTask.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementSucceedFuture.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocol.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocolFactory.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadRpc.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadAbortRpc.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadBeginRpc.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadCommitRpc.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadGetStatusRpc.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadHeartBeatRpc.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadInsertRpc.java rename src/main/java/com/alipay/oceanbase/rpc/{protocol/payload/impl/direct_load => direct_load/protocol/payload}/ObTableLoadClientStatus.java (83%) create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/ObDirectLoadProtocolV0.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadAbortRpcV0.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadBeginRpcV0.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadCommitRpcV0.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadDefaultRpcV0.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadGetStatusRpcV0.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadHeartBeatRpcV0.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadInsertRpcV0.java rename src/main/java/com/alipay/oceanbase/rpc/{protocol/payload/impl/direct_load => direct_load/protocol/v0/payload/impl}/ObTableDirectLoadAbortArg.java (92%) rename src/main/java/com/alipay/oceanbase/rpc/{protocol/payload/impl/direct_load => direct_load/protocol/v0/payload/impl}/ObTableDirectLoadBeginArg.java (64%) rename src/main/java/com/alipay/oceanbase/rpc/{protocol/payload/impl/direct_load => direct_load/protocol/v0/payload/impl}/ObTableDirectLoadBeginRes.java (84%) rename src/main/java/com/alipay/oceanbase/rpc/{protocol/payload/impl/direct_load => direct_load/protocol/v0/payload/impl}/ObTableDirectLoadCommitArg.java (92%) rename src/main/java/com/alipay/oceanbase/rpc/{protocol/payload/impl/direct_load => direct_load/protocol/v0/payload/impl}/ObTableDirectLoadGetStatusArg.java (92%) rename src/main/java/com/alipay/oceanbase/rpc/{protocol/payload/impl/direct_load => direct_load/protocol/v0/payload/impl}/ObTableDirectLoadGetStatusRes.java (90%) rename src/main/java/com/alipay/oceanbase/rpc/{protocol/payload/impl/direct_load => direct_load/protocol/v0/payload/impl}/ObTableDirectLoadHeartBeatArg.java (92%) rename src/main/java/com/alipay/oceanbase/rpc/{protocol/payload/impl/direct_load => direct_load/protocol/v0/payload/impl}/ObTableDirectLoadHeartBeatRes.java (90%) rename src/main/java/com/alipay/oceanbase/rpc/{protocol/payload/impl/direct_load => direct_load/protocol/v0/payload/impl}/ObTableDirectLoadInsertArg.java (64%) create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/util/ObDirectLoadIntervalUtil.java create mode 100644 src/main/java/com/alipay/oceanbase/rpc/direct_load/util/ObDirectLoadUtil.java rename src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/{direct_load => }/ObLoadDupActionType.java (95%) delete mode 100644 src/main/java/com/alipay/oceanbase/rpc/table/ObDirectLoadBucket.java delete mode 100644 src/main/java/com/alipay/oceanbase/rpc/table/ObDirectLoadObjRow.java delete mode 100644 src/main/java/com/alipay/oceanbase/rpc/table/ObDirectLoadParameter.java delete mode 100644 src/main/java/com/alipay/oceanbase/rpc/table/ObTableDirectLoad.java diff --git a/src/main/java/com/alipay/oceanbase/rpc/bolt/transport/ObPacketFactory.java b/src/main/java/com/alipay/oceanbase/rpc/bolt/transport/ObPacketFactory.java index 6e92a414..2cf180cc 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/bolt/transport/ObPacketFactory.java +++ b/src/main/java/com/alipay/oceanbase/rpc/bolt/transport/ObPacketFactory.java @@ -89,6 +89,9 @@ private byte[] encodePayload(ObPayload payload) { // compute checksum rpcHeaderPacket.setChecksum(ObPureCrc32C.calculate(payloadContent)); + // group id + rpcHeaderPacket.setGroupId(payload.getGroupId()); + // 3. assemble and encode rpc packet ObRpcPacket rpcPacket = new ObRpcPacket(); rpcPacket.setRpcPacketHeader(rpcHeaderPacket); diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadBucket.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadBucket.java new file mode 100644 index 00000000..c32c839b --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadBucket.java @@ -0,0 +1,183 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2023 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load; + +import java.util.ArrayList; +import java.util.List; + +import com.alipay.oceanbase.rpc.direct_load.exception.*; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObObj; +import com.alipay.oceanbase.rpc.util.ObByteBuf; +import com.alipay.oceanbase.rpc.util.Serialization; + +public class ObDirectLoadBucket { + + /** + * buffer的格式如下 + * +----------------+-----------+------+------+-----+ + * | payload length | row count | row1 | row2 | ... | + * +----------------+-----------+------+------+-----+ + */ + + private static final ObDirectLoadLogger logger = ObDirectLoadLogger.getLogger(); + private final static int integerReservedSize = 5; // 预留5个字节用来编码Integer + private final static int reservedSize = integerReservedSize * 2; // 预留2个Integer + private final static int defaultBufferSize = 1 * 1024 * 1024; // 1M + + private final int bufferSize; + private ArrayList payloadBufferList = new ArrayList(64); + private int totalRowCount = 0; + + private ObByteBuf buffer = null; + private int currentRowCount = 0; + private Row row = new Row(); + + public ObDirectLoadBucket() { + bufferSize = defaultBufferSize; + } + + public ObDirectLoadBucket(int bufferSize) { + this.bufferSize = bufferSize; + } + + public boolean isEmpty() { + return (getRowNum() == 0); + } + + public int getRowNum() { + return totalRowCount + currentRowCount; + } + + @Override + public String toString() { + return String.format("{rowNum:%d}", getRowNum()); + } + + public void addRow(ObObj[] cells) throws ObDirectLoadException { + if (cells == null || cells.length == 0) { + logger.warn("cells cannot be null or empty, cells:" + cells); + throw new ObDirectLoadIllegalArgumentException("cells cannot be null or empty, cells:" + + cells); + } + row.setCells(cells); + appendRow(row); + } + + public void addRow(List cells) throws ObDirectLoadException { + if (cells == null || cells.isEmpty()) { + logger.warn("cells cannot be null or empty, cells:" + cells); + throw new ObDirectLoadIllegalArgumentException("cells cannot be null or empty, cells:" + + cells); + } + row.setCells(cells); + appendRow(row); + } + + private void appendRow(Row row) { + final int rowEncodedSize = row.getEncodedSize(); + while (true) { + if (buffer == null) { + allocBuffer(rowEncodedSize); + } else if (buffer.writableBytes() < rowEncodedSize) { + sealBuffer(); + } else { + row.encode(buffer); + ++currentRowCount; + break; + } + } + } + + private void allocBuffer(int encodedSize) { + final int needSize = encodedSize + reservedSize; + final int allocBufferSize = (needSize + bufferSize - 1) / bufferSize * bufferSize; + buffer = new ObByteBuf(allocBufferSize); + buffer.reserve(reservedSize); + } + + private void sealBuffer() { + // 编码row count + encodeVi32(buffer.bytes, integerReservedSize, currentRowCount); + // 编码payload length + encodeVi32(buffer.bytes, 0, buffer.readableBytes() - integerReservedSize); + payloadBufferList.add(buffer); + totalRowCount += currentRowCount; + currentRowCount = 0; + buffer = null; + } + + private void encodeVi32(byte[] buf, int pos, int value) { + // 前面的byte的高位都设置为1 + for (int i = 0; i < integerReservedSize - 1; ++i, ++pos) { + buf[pos] = (byte) (value | 0x80); + value >>>= 7; + } + // 最后一个byte的高位设置为0 + buf[pos] = (byte) (value & 0x7f); + } + + public List getPayloadBufferList() { + if (buffer != null) { + sealBuffer(); + } + return payloadBufferList; + } + + private static class Row { + + private final long SeqNo = 0; + private ObObj[] cells = null; + + public Row() { + } + + public void setCells(ObObj[] cells) { + this.cells = cells; + } + + public void setCells(List cells) { + this.cells = cells.toArray(new ObObj[0]); + } + + /** + * Encode. + */ + public void encode(ObByteBuf buf) { + Serialization.encodeVi64(buf, SeqNo); + Serialization.encodeVi32(buf, cells.length); + for (int i = 0; i < cells.length; ++i) { + cells[i].encode(buf); + } + } + + /** + * Get encoded size. + */ + public int getEncodedSize() { + int size = 0; + size += Serialization.getNeedBytes(SeqNo); + size += Serialization.getNeedBytes(cells.length); + for (int i = 0; i < cells.length; ++i) { + size += cells[i].getEncodedSize(); + } + return size; + } + + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadConnection.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadConnection.java new file mode 100644 index 00000000..26122b1c --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadConnection.java @@ -0,0 +1,472 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load; + +import java.util.LinkedList; +import java.util.Properties; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; + +import com.alipay.oceanbase.rpc.ObGlobal; +import com.alipay.oceanbase.rpc.direct_load.exception.*; +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadProtocol; +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadProtocolFactory; +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadRpc; +import com.alipay.oceanbase.rpc.direct_load.util.ObDirectLoadUtil; +import com.alipay.oceanbase.rpc.property.Property; +import com.alipay.oceanbase.rpc.protocol.payload.ObPayload; +import com.alipay.oceanbase.rpc.table.ObTable; + +public class ObDirectLoadConnection { + + private final ObDirectLoadConnectionFactory connectionFactory; + private final ObDirectLoadTraceId traceId; + private final ObDirectLoadLogger logger; + + private String ip = null; + private int port = 0; + + private String tenantName = null; + private String userName = null; + private String password = null; + private String databaseName = null; + + private int writeConnectionNum = 0; + + private long heartBeatTimeout = 0; + private long heartBeatInterval = 0; + + private boolean isInited = false; + private boolean isClosed = false; + + private ObDirectLoadProtocol protocol = null; + + private LinkedList statementList = null; // statement列表 + + ObDirectLoadConnection(ObDirectLoadConnectionFactory connectionFactory) { + this.connectionFactory = connectionFactory; + this.traceId = ObDirectLoadTraceId.generateTraceId(); + this.logger = ObDirectLoadLogger.getLogger(this.traceId); + } + + public ObDirectLoadTraceId getTraceId() { + return traceId; + } + + public ObDirectLoadLogger getLogger() { + return logger; + } + + public synchronized void init(Builder builder) throws ObDirectLoadException { + if (isInited) { + logger.warn("init twice, connection:" + this); + throw new ObDirectLoadIllegalStateException("init twice, connection:" + this); + } + if (isClosed) { + logger.warn("already closed, connection:" + this); + throw new ObDirectLoadIllegalStateException("already closed, connection:" + this); + } + fillParams(builder); + initCheck(); + initProtocol(); + statementList = new LinkedList(); + isInited = true; + logger.info("connection init successful, args:" + builder); + } + + public void close() { + logger.info("connection close"); + ObDirectLoadStatement[] statements = null; + synchronized (this) { + if (isClosed) { + logger.info("connection is closed"); + return; + } + isClosed = true; + statements = statementList.toArray(new ObDirectLoadStatement[0]); + } + // close all statements + if (statements.length > 0) { + logger.info("connection close wait statements close, size:" + statements.length); + for (ObDirectLoadStatement statement : statements) { + statement.close(); + } + } + logger.info("connection close successful"); + connectionFactory.closeConnection(this); + } + + public void checkStatus() throws ObDirectLoadException { + if (!isInited) { + throw new ObDirectLoadIllegalStateException("connection not init"); + } + if (isClosed) { + throw new ObDirectLoadIllegalStateException("connection is closed"); + } + } + + private void fillParams(Builder builder) throws ObDirectLoadException { + if (builder == null) { + logger.warn("builder cannot be null"); + throw new ObDirectLoadIllegalArgumentException("builder cannot be null"); + } + ip = builder.ip; + port = builder.port; + tenantName = builder.tenantName; + userName = builder.userName; + password = builder.password; + databaseName = builder.databaseName; + + heartBeatTimeout = builder.heartBeatTimeout; + heartBeatInterval = builder.heartBeatInterval; + + writeConnectionNum = builder.writeConnectionNum; + } + + private void initCheck() throws ObDirectLoadException { + ObDirectLoadUtil.checkNonEmpty(ip, "ip", logger); + ObDirectLoadUtil.checkInRange(port, 1, 65535, "port", logger); + ObDirectLoadUtil.checkNonEmpty(tenantName, "tenantName", logger); + ObDirectLoadUtil.checkNonEmpty(userName, "userName", logger); + ObDirectLoadUtil.checkNotNull(password, "password", logger); + ObDirectLoadUtil.checkNonEmpty(databaseName, "databaseName", logger); + ObDirectLoadUtil.checkPositive(writeConnectionNum, "writeConnectionNum", logger); + if (heartBeatTimeout < 3000) { + logger.warn("Param 'heartBeatTimeout' must not be less than 3000 ms, value:" + + heartBeatTimeout); + throw new ObDirectLoadIllegalArgumentException( + "Param 'heartBeatTimeout' must not be less than 3000 ms, value:" + heartBeatTimeout); + } + if (heartBeatInterval < 100) { + logger.warn("Param 'heartBeatInterval' must not be less than 1 ms, value:" + + heartBeatInterval); + throw new ObDirectLoadIllegalArgumentException( + "Param 'heartBeatInterval' must not be less than 1 ms, value:" + heartBeatInterval); + } + if (heartBeatTimeout <= heartBeatInterval) { + logger + .warn("Param 'heartBeatInterval' must not be greater than or equal to Param 'heartBeatTimeout', heartBeatTimeout:" + + heartBeatTimeout + ", heartBeatInterval:" + heartBeatInterval); + throw new ObDirectLoadIllegalArgumentException( + "Param 'heartBeatInterval' must not be greater than or equal to Param 'heartBeatTimeout', heartBeatTimeout:" + + heartBeatTimeout + ", heartBeatInterval:" + heartBeatInterval); + } + } + + private void initProtocol() throws ObDirectLoadException { + // 构造一个连接, 获取版本号 + ObTable table = null; + synchronized (connectionFactory) { // 防止并发访问ObGlobal.OB_VERSION + ObGlobal.OB_VERSION = 0; + try { + Properties properties = new Properties(); + properties.setProperty(Property.SERVER_CONNECTION_POOL_SIZE.getKey(), + String.valueOf(1)); + table = new ObTable.Builder(ip, port) + .setLoginInfo(tenantName, userName, password, databaseName) + .setProperties(properties).build(); + } catch (Exception e) { + throw new ObDirectLoadException(e); + } + } + this.protocol = ObDirectLoadProtocolFactory.getProtocol(ObGlobal.OB_VERSION); + this.protocol.init(); + table.close(); + } + + public ObDirectLoadProtocol getProtocol() { + return protocol; + } + + public long getHeartBeatTimeout() { + return heartBeatTimeout; + } + + public long getHeartBeatInterval() { + return heartBeatInterval; + } + + public String toString() { + return String + .format( + "{ip:\"%s\", port:%d, tenantName:\"%s\", userName:\"%s\", databaseName:\"%s\", writeConnectionNum:%d}", + ip, port, tenantName, userName, databaseName, writeConnectionNum); + } + + public void executeWithConnection(final ObDirectLoadRpc rpc, ObTable table, long timeoutMillis) + throws ObDirectLoadException { + try { + rpc.setRpcTimeout(timeoutMillis); + ObPayload request = rpc.getRequest(); + ObPayload result = table.execute(request); + rpc.setResult(result); + } catch (Exception e) { + throw ObDirectLoadExceptionUtil.convertException(e); + } + } + + public synchronized ObDirectLoadStatement createStatement() throws ObDirectLoadException { + if (!isInited) { + logger.warn("connection not init"); + throw new ObDirectLoadIllegalStateException("connection not init"); + } + if (isClosed) { + logger.warn("connection is closed"); + throw new ObDirectLoadIllegalStateException("connection is closed"); + } + ObDirectLoadStatement stmt = new ObDirectLoadStatement(this); + this.statementList.addLast(stmt); + return stmt; + } + + public synchronized void closeStatement(ObDirectLoadStatement stmt) { + this.statementList.remove(stmt); + } + + public ObDirectLoadStatement.Builder getStatementBuilder() { + return new ObDirectLoadStatement.Builder(this); + } + + ObDirectLoadStatement buildStatement(ObDirectLoadStatement.Builder builder) + throws ObDirectLoadException { + ObDirectLoadStatement stmt = null; + try { + stmt = createStatement(); + stmt.init(builder); + } catch (Exception e) { + logger.warn("build statement failed, args:" + builder, e); + closeStatement(stmt); + throw e; + } + return stmt; + } + + public static final class Builder { + + private ObDirectLoadConnectionFactory connectionFactory = null; + + private String ip = null; + private int port = 0; + + private String tenantName = null; + private String userName = null; + private String password = null; + private String databaseName = null; + + private int writeConnectionNum = 1; + + private long heartBeatTimeout = 60 * 1000; // 60s + private long heartBeatInterval = 10 * 1000; // 10s + + private static final long MAX_HEART_BEAT_TIMEOUT = 1L * 365 * 24 * 3600 * 1000; // 1year + + Builder(ObDirectLoadConnectionFactory connectionFactory) { + this.connectionFactory = connectionFactory; + } + + public Builder setServerInfo(String ip, int port) { + this.ip = ip; + this.port = port; + return this; + } + + public Builder setLoginInfo(String tenantName, String userName, String password, + String databaseName) { + this.tenantName = tenantName; + this.userName = userName; + this.password = password; + this.databaseName = databaseName; + return this; + } + + public Builder enableParallelWrite(int writeParallel) { + this.writeConnectionNum = writeParallel; + return this; + } + + public Builder setHeartBeatInfo(long heartBeatTimeout, long heartBeatInterval) { + this.heartBeatTimeout = Math.min(heartBeatTimeout, MAX_HEART_BEAT_TIMEOUT); + this.heartBeatInterval = heartBeatInterval; + return this; + } + + public String toString() { + return String + .format( + "{ip:\"%s\", port:%d, tenantName:\"%s\", userName:\"%s\", databaseName:\"%s\", writeConnectionNum:%d, heartBeatTimeout:%d, heartBeatInterval:%d}", + ip, port, tenantName, userName, databaseName, writeConnectionNum, + heartBeatTimeout, heartBeatInterval); + } + + public ObDirectLoadConnection build() throws ObDirectLoadException { + return connectionFactory.buildConnection(this); + } + + } + + public static final class ObTablePool { + + private static final int highPrioConnectionIdx = 0; // for heart beat + private static final int controlConnectionIdx = 1; // for begin and commit + private static final int writeConnectionStartIdx = 2; // for write + + private final ObDirectLoadConnection connection; + private final ObDirectLoadLogger logger; + private final long timeoutMillis; + + private ObTable[] tables; + + private BlockingQueue availableWriteObTableQueue = null; + private int availableWriteObTableNum = 0; + + private boolean isInited = false; + private boolean isClosed = false; + + ObTablePool(ObDirectLoadConnection connection, ObDirectLoadLogger logger, long timeoutMillis) { + this.connection = connection; + this.logger = logger; + this.timeoutMillis = timeoutMillis; + } + + public void init() throws ObDirectLoadException { + synchronized (connection.connectionFactory) { // 防止并发访问ObGlobal.OB_VERSION + initTables(); + } + initAvailableWriteObTableQueue(); + isInited = true; + } + + public void close() { + if (tables != null) { + for (int i = 0; i < tables.length; ++i) { + ObTable table = tables[i]; + if (table != null) { + table.close(); + } + } + } + tables = null; + isClosed = true; + } + + private void initTables() throws ObDirectLoadException { + final int poolSize = writeConnectionStartIdx + connection.writeConnectionNum; + Properties properties = new Properties(); + properties + .setProperty(Property.SERVER_CONNECTION_POOL_SIZE.getKey(), String.valueOf(1)); + properties.setProperty(Property.RPC_EXECUTE_TIMEOUT.getKey(), + String.valueOf(timeoutMillis)); + properties.setProperty(Property.RPC_OPERATION_TIMEOUT.getKey(), + String.valueOf(timeoutMillis)); + tables = new ObTable[poolSize]; + try { + for (int i = 0; i < tables.length; ++i) { + tables[i] = new ObTable.Builder(connection.ip, connection.port) + .setLoginInfo(connection.tenantName, connection.userName, + connection.password, connection.databaseName).setProperties(properties) + .build(); + } + } catch (Exception e) { + throw new ObDirectLoadException(e); + } + } + + private void initAvailableWriteObTableQueue() throws ObDirectLoadException { + this.availableWriteObTableQueue = new ArrayBlockingQueue( + connection.writeConnectionNum); + try { + for (int i = 0; i < connection.writeConnectionNum; ++i) { + ObTable table = tables[writeConnectionStartIdx + i]; + this.availableWriteObTableQueue.put(table); + } + this.availableWriteObTableNum = connection.writeConnectionNum; + } catch (Exception e) { + throw new ObDirectLoadException(e); + } + } + + public ObTable getHighPrioObTable() throws ObDirectLoadException { + if (!isInited) { + logger.warn("ob table pool not init"); + throw new ObDirectLoadIllegalStateException("ob table pool not init"); + } + if (isClosed) { + logger.warn("ob table pool is closed"); + throw new ObDirectLoadIllegalStateException("ob table pool is closed"); + } + return tables[highPrioConnectionIdx]; + } + + public ObTable getControlObTable() throws ObDirectLoadException { + if (!isInited) { + logger.warn("ob table pool not init"); + throw new ObDirectLoadIllegalStateException("ob table pool not init"); + } + if (isClosed) { + logger.warn("ob table pool is closed"); + throw new ObDirectLoadIllegalStateException("ob table pool is closed"); + } + return tables[controlConnectionIdx]; + } + + public ObTable takeWriteObTable(long timeoutMillis) throws ObDirectLoadException { + if (!isInited) { + logger.warn("ob table pool not init"); + throw new ObDirectLoadIllegalStateException("ob table pool not init"); + } + try { + final long startTime = System.currentTimeMillis(); + ObTable table = null; + while (table == null) { + if (isClosed) { + logger.warn("ob table pool is closed"); + throw new ObDirectLoadIllegalStateException("ob table pool is closed"); + } + if (availableWriteObTableNum == 0) { + logger.warn("ob table pool no avaiable write ob table"); + throw new ObDirectLoadUnexpectedException( + "ob table pool no avaiable write ob table"); + } + if (startTime + timeoutMillis < System.currentTimeMillis()) { + logger.warn("ob table pool task write ob table timeout"); + throw new ObDirectLoadTimeoutException( + "ob table pool task write ob table timeout"); + } + table = availableWriteObTableQueue.poll(1000, TimeUnit.MILLISECONDS); + } + return table; + } catch (Exception e) { + logger.warn("ob table pool task write ob table failed", e); + throw ObDirectLoadExceptionUtil.convertException(e); + } + } + + public void putWriteObTable(ObTable table) { + try { + availableWriteObTableQueue.put(table); + } catch (Exception e) { + --availableWriteObTableNum; + logger.warn("ob table pool put write ob table failed, availableWriteObTableNum:" + + availableWriteObTableNum, e); + } + } + + }; + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadConnectionFactory.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadConnectionFactory.java new file mode 100644 index 00000000..966983d9 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadConnectionFactory.java @@ -0,0 +1,52 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load; + +import com.alipay.oceanbase.rpc.direct_load.exception.*; + +public class ObDirectLoadConnectionFactory { + + private static final ObDirectLoadLogger logger = ObDirectLoadLogger.getLogger(); + + public ObDirectLoadConnection createConnection() throws ObDirectLoadException { + ObDirectLoadConnection connection = new ObDirectLoadConnection(this); + logger.debug("create connection, id:" + connection.getTraceId()); + return connection; + } + + public void closeConnection(ObDirectLoadConnection connection) { + if (connection == null) { + return; + } + logger.debug("close connection, id:" + connection.getTraceId()); + } + + public ObDirectLoadConnection buildConnection(ObDirectLoadConnection.Builder builder) + throws ObDirectLoadException { + ObDirectLoadConnection connection = null; + try { + connection = createConnection(); + connection.init(builder); + } catch (Exception e) { + logger.warn("build connection failed, args:" + builder, e); + throw e; + } + return connection; + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadLogger.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadLogger.java new file mode 100644 index 00000000..abfdc71d --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadLogger.java @@ -0,0 +1,158 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load; + +import org.slf4j.Logger; + +import com.alipay.oceanbase.rpc.util.TableClientLoggerFactory; + +public class ObDirectLoadLogger { + private static final Logger logger = TableClientLoggerFactory + .getDIRECTLogger(); + private final ObDirectLoadTraceId traceId; + + private static final ObDirectLoadLogger DEFAULT_LOGGER = new ObDirectLoadLogger( + ObDirectLoadTraceId.DEFAULT_TRACE_ID); + + public static ObDirectLoadLogger getLogger() { + return DEFAULT_LOGGER; + } + + public static ObDirectLoadLogger getLogger(ObDirectLoadTraceId traceId) { + return new ObDirectLoadLogger(traceId); + } + + public ObDirectLoadLogger(ObDirectLoadTraceId traceId) { + this.traceId = traceId; + } + + private String formatString(String msg) { + return String.format("[%s] %s", this.traceId, msg); + } + + // trace + + public void trace(String msg) { + logger.trace(formatString(msg)); + } + + public void trace(String format, Object arg) { + logger.trace(formatString(format), arg); + } + + public void trace(String format, Object arg1, Object arg2) { + logger.trace(formatString(format), arg1, arg2); + } + + public void trace(String format, Object... arguments) { + logger.trace(formatString(format), arguments); + } + + public void trace(String msg, Throwable t) { + logger.trace(formatString(msg), t); + } + + // debug + + public void debug(String msg) { + logger.debug(formatString(msg)); + } + + public void debug(String format, Object arg) { + logger.debug(formatString(format), arg); + } + + public void debug(String format, Object arg1, Object arg2) { + logger.debug(formatString(format), arg1, arg2); + } + + public void debug(String format, Object... arguments) { + logger.debug(formatString(format), arguments); + } + + public void debug(String msg, Throwable t) { + logger.debug(formatString(msg), t); + } + + // info + + public void info(String msg) { + logger.info(formatString(msg)); + } + + public void info(String format, Object arg) { + logger.info(formatString(format), arg); + } + + public void info(String format, Object arg1, Object arg2) { + logger.info(formatString(format), arg1, arg2); + } + + public void info(String format, Object... arguments) { + logger.info(formatString(format), arguments); + } + + public void info(String msg, Throwable t) { + logger.info(formatString(msg), t); + } + + // warn + + public void warn(String msg) { + logger.warn(formatString(msg)); + } + + public void warn(String format, Object arg) { + logger.warn(formatString(format), arg); + } + + public void warn(String format, Object arg1, Object arg2) { + logger.warn(formatString(format), arg1, arg2); + } + + public void warn(String format, Object... arguments) { + logger.warn(formatString(format), arguments); + } + + public void warn(String msg, Throwable t) { + logger.warn(formatString(msg), t); + } + + // error + + public void error(String msg) { + logger.error(formatString(msg)); + } + + public void error(String format, Object arg) { + logger.error(formatString(format), arg); + } + + public void error(String format, Object arg1, Object arg2) { + logger.error(formatString(format), arg1, arg2); + } + + public void error(String format, Object... arguments) { + logger.error(formatString(format), arguments); + } + + public void error(String msg, Throwable t) { + logger.error(formatString(msg), t); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadManager.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadManager.java new file mode 100644 index 00000000..2022b4e1 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadManager.java @@ -0,0 +1,42 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load; + +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadProtocolFactory; + +public class ObDirectLoadManager { + + private static final ObDirectLoadConnectionFactory connectionFactory = new ObDirectLoadConnectionFactory(); + + private ObDirectLoadManager() { + } + + /** + * 检查observer版本是否支持旁路导入 + * @param obVersion + * @return {@code true} 支持 {@code false} 不支持 + */ + public static boolean checkIsSupported(long obVersion) { + return ObDirectLoadProtocolFactory.checkIsSupported(obVersion); + } + + public static ObDirectLoadConnection.Builder getConnectionBuilder() { + return new ObDirectLoadConnection.Builder(connectionFactory); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadRuntimeInfo.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadRuntimeInfo.java new file mode 100644 index 00000000..8c7d61f8 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadRuntimeInfo.java @@ -0,0 +1,52 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load; + +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; + +public class ObDirectLoadRuntimeInfo { + + protected long lastScheduledTime = 0; + protected ObDirectLoadException lastScheduledCause = null; + protected int scheduledCount = 0; + + public long getLastScheduledTime() { + return lastScheduledTime; + } + + public void setLastScheduledTime(long scheduledTime) { + this.lastScheduledTime = scheduledTime; + } + + public ObDirectLoadException getLastScheduledCause() { + return lastScheduledCause; + } + + public void setLastScheduledCause(ObDirectLoadException cause) { + this.lastScheduledCause = cause; + } + + public int getScheduledCount() { + return scheduledCount; + } + + public void incScheduledCount() { + this.scheduledCount++; + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadStatement.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadStatement.java new file mode 100644 index 00000000..8c94e715 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadStatement.java @@ -0,0 +1,355 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load; + +import java.util.Arrays; + +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadIllegalArgumentException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadIllegalStateException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadTimeoutException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadUnexpectedException; +import com.alipay.oceanbase.rpc.direct_load.execution.ObDirectLoadStatementExecutor; +import com.alipay.oceanbase.rpc.direct_load.future.ObDirectLoadStatementFailedFuture; +import com.alipay.oceanbase.rpc.direct_load.future.ObDirectLoadStatementFuture; +import com.alipay.oceanbase.rpc.direct_load.util.ObDirectLoadUtil; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObLoadDupActionType; + +public class ObDirectLoadStatement { + + private final ObDirectLoadConnection connection; + private final ObDirectLoadTraceId traceId; + private final ObDirectLoadLogger logger; + + private String tableName = null; + private String[] columnNames = null; + private String[] partitionNames = null; + private ObLoadDupActionType dupAction = ObLoadDupActionType.INVALID_MODE; + + private int parallel = 0; + private long queryTimeout = 0; + + private long maxErrorRowCount = 0; + private String loadMethod = "full"; + + private boolean isInited = false; + private boolean isClosed = false; + + private ObDirectLoadConnection.ObTablePool obTablePool = null; + private ObDirectLoadStatementExecutor executor = null; + private long startQueryTimeMillis = 0; + + ObDirectLoadStatement(ObDirectLoadConnection connection) { + this.connection = connection; + this.traceId = ObDirectLoadTraceId.generateTraceId(); + this.logger = ObDirectLoadLogger.getLogger(this.traceId); + } + + public ObDirectLoadConnection getConnection() { + return connection; + } + + public ObDirectLoadTraceId getTraceId() { + return traceId; + } + + public ObDirectLoadLogger getLogger() { + return logger; + } + + public synchronized void init(Builder builder) throws ObDirectLoadException { + if (isInited) { + logger.warn("statement init twice"); + throw new ObDirectLoadIllegalStateException("statement init twice"); + } + if (isClosed) { + logger.warn("statement is closed"); + throw new ObDirectLoadIllegalStateException("statement is closed"); + } + fillParams(builder); + initCheck(); + obTablePool = new ObDirectLoadConnection.ObTablePool(connection, logger, queryTimeout); + obTablePool.init(); + executor = new ObDirectLoadStatementExecutor(this); + startQueryTimeMillis = System.currentTimeMillis(); + isInited = true; + logger.info("statement init successful, args:" + builder); + } + + public synchronized void close() { + logger.info("statement close"); + if (isClosed) { + logger.info("statement is closed"); + return; + } + isClosed = true; + if (executor != null) { + executor.close(); + executor = null; + } + if (obTablePool != null) { + obTablePool.close(); + obTablePool = null; + } + logger.info("statement close successful"); + connection.closeStatement(this); + } + + private void fillParams(Builder builder) throws ObDirectLoadException { + if (builder == null) { + logger.warn("builder cannot be null"); + throw new ObDirectLoadIllegalArgumentException("builder cannot be null"); + } + tableName = builder.tableName; + columnNames = builder.columnNames; + partitionNames = builder.partitionNames; + dupAction = builder.dupAction; + parallel = builder.parallel; + queryTimeout = builder.queryTimeout; + maxErrorRowCount = builder.maxErrorRowCount; + loadMethod = builder.loadMethod; + if (loadMethod.compareToIgnoreCase("inc_replace") == 0) { + // inc_replace模式强制设置dupAction为STOP_ON_DUP + dupAction = ObLoadDupActionType.STOP_ON_DUP; + } + } + + private void initCheck() throws ObDirectLoadException { + ObDirectLoadUtil.checkNonEmpty(tableName, "tableName", logger); + if (columnNames == null) { + columnNames = new String[0]; + } else { + ObDirectLoadUtil.checkNonEmptyAndUnique(columnNames, "columnNames", logger); + } + if (partitionNames == null) { + partitionNames = new String[0]; + } else { + ObDirectLoadUtil.checkNonEmptyAndUnique(partitionNames, "partitionNames", logger); + } + ObDirectLoadUtil.checkNonValid(dupAction, ObLoadDupActionType.INVALID_MODE, "dupAction", + logger); + ObDirectLoadUtil.checkPositive(parallel, "parallel", logger); + ObDirectLoadUtil.checkPositive(queryTimeout, "queryTimeout", logger); + ObDirectLoadUtil.checkPositiveOrZero(maxErrorRowCount, "maxErrorRowCount", logger); + ObDirectLoadUtil.checkNonEmpty(loadMethod, "loadMethod", logger); + } + + public void checkStatus() throws ObDirectLoadException { + if (!isInited) { + logger.warn("statement not init"); + throw new ObDirectLoadIllegalStateException("statement not init"); + } + if (isClosed) { + logger.warn("statement is closed"); + throw new ObDirectLoadIllegalStateException("statement is closed"); + } + } + + public String getTableName() { + return tableName; + } + + public String[] getColumnNames() { + return columnNames; + } + + public String[] getPartitionNames() { + return partitionNames; + } + + public ObLoadDupActionType getDupAction() { + return dupAction; + } + + public int getParallel() { + return parallel; + } + + public long getQueryTimeout() { + return queryTimeout; + } + + public long getMaxErrorRowCount() { + return maxErrorRowCount; + } + + public String getLoadMethod() { + return loadMethod; + } + + public void checkTimeout() throws ObDirectLoadException { + if (startQueryTimeMillis == 0) { + logger.warn("statement not start"); + throw new ObDirectLoadUnexpectedException("statement not start"); + } + if (startQueryTimeMillis + queryTimeout < System.currentTimeMillis()) { + logger.warn("statement timeout"); + throw new ObDirectLoadTimeoutException("statement timeout"); + } + } + + public long getTimeoutRemain() { + long remainTimeout = queryTimeout; + if (startQueryTimeMillis > 0) { + remainTimeout -= (System.currentTimeMillis() - startQueryTimeMillis); + } + return remainTimeout; + } + + public ObDirectLoadConnection.ObTablePool getObTablePool() { + return obTablePool; + } + + @Deprecated + public void setBeginRpcTimeout(long timeoutMillis) { + } + + @Deprecated + public void setWriteRpcTimeout(long timeoutMillis) { + } + + public String toString() { + return String + .format( + "{tableName:%s, columnNames:%s, partitionNames:%s, dupAction:%s, parallel:%d, queryTimeout:%d, maxErrorRowCount:%d, loadMethod:%s, executor:%s}", + tableName, Arrays.toString(columnNames), Arrays.toString(partitionNames), + dupAction, parallel, queryTimeout, maxErrorRowCount, loadMethod, executor); + } + + public ObDirectLoadStatementFuture beginAsync() { + try { + checkStatus(); + return executor.begin(); + } catch (ObDirectLoadException e) { + logger.warn("statement begin failed", e); + return new ObDirectLoadStatementFailedFuture(this, e); + } + } + + public void begin() throws ObDirectLoadException { + ObDirectLoadStatementFuture future = beginAsync(); + future.await(); + if (!future.isSuccess()) { + throw future.cause(); + } + } + + public ObDirectLoadStatementFuture commitAsync() { + try { + checkStatus(); + return executor.commit(); + } catch (ObDirectLoadException e) { + logger.warn("statement commit failed", e); + return new ObDirectLoadStatementFailedFuture(this, e); + } + } + + public void commit() throws ObDirectLoadException { + ObDirectLoadStatementFuture future = commitAsync(); + future.await(); + if (!future.isSuccess()) { + throw future.cause(); + } + } + + public void write(ObDirectLoadBucket bucket) throws ObDirectLoadException { + if (bucket == null || bucket.isEmpty()) { + logger.warn("Param 'bucket' must not be null or empty, value:" + bucket); + throw new ObDirectLoadIllegalArgumentException( + "Param 'bucket' must not be null or empty, value:" + bucket); + } + checkStatus(); + executor.write(bucket); + } + + public static final class Builder { + + private final ObDirectLoadConnection connection; + + private String tableName = null; + private String[] columnNames = null; + private String[] partitionNames = null; + private ObLoadDupActionType dupAction = ObLoadDupActionType.INVALID_MODE; + + private int parallel = 0; + private long queryTimeout = 0; + + private long maxErrorRowCount = 0; + private String loadMethod = "full"; + + private static final long MAX_QUERY_TIMEOUT = 1L * 365 * 24 * 3600 * 1000; // 1year + + Builder(ObDirectLoadConnection connection) { + this.connection = connection; + } + + public Builder setTableName(String tableName) { + this.tableName = tableName; + return this; + } + + public Builder setColumnNames(String[] columnNames) { + this.columnNames = columnNames; + return this; + } + + public Builder setPartitionNames(String[] partitionNames) { + this.partitionNames = partitionNames; + return this; + } + + public Builder setDupAction(ObLoadDupActionType dupAction) { + this.dupAction = dupAction; + return this; + } + + public Builder setParallel(int parallel) { + this.parallel = parallel; + return this; + } + + public Builder setQueryTimeout(long queryTimeout) { + this.queryTimeout = Math.min(queryTimeout, MAX_QUERY_TIMEOUT); + return this; + } + + public Builder setMaxErrorRowCount(long maxErrorRowCount) { + this.maxErrorRowCount = maxErrorRowCount; + return this; + } + + public Builder setLoadMethod(String loadMethod) { + this.loadMethod = loadMethod; + return this; + } + + public String toString() { + return String + .format( + "{tableName:%s, columnNames:%s, partitionNames:%s, dupAction:%s, parallel:%d, queryTimeout:%d, maxErrorRowCount:%d, loadMethod:%s}", + tableName, Arrays.toString(columnNames), Arrays.toString(partitionNames), + dupAction, parallel, queryTimeout, maxErrorRowCount, loadMethod); + } + + public ObDirectLoadStatement build() throws ObDirectLoadException { + return connection.buildStatement(this); + } + + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadTraceId.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadTraceId.java new file mode 100644 index 00000000..f74559b3 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadTraceId.java @@ -0,0 +1,92 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load; + +import java.net.InetAddress; +import java.util.concurrent.atomic.AtomicLong; + +public class ObDirectLoadTraceId { + + private final long uniqueId; + private final long sequence; + + public ObDirectLoadTraceId(long uniqueId, long sequence) { + this.uniqueId = uniqueId; + this.sequence = sequence; + } + + public String toString() { + return String.format("Y%X-%016X", uniqueId, sequence); + } + + public long getUniqueId() { + return uniqueId; + } + + public long getSequence() { + return sequence; + } + + public static final ObDirectLoadTraceId DEFAULT_TRACE_ID; + public static TraceIdGenerator traceIdGenerator; + + static { + DEFAULT_TRACE_ID = new ObDirectLoadTraceId(0, 0); + traceIdGenerator = new TraceIdGenerator(); + } + + public static ObDirectLoadTraceId generateTraceId() { + return traceIdGenerator.generate(); + } + + public static class TraceIdGenerator { + + private final ObDirectLoadLogger logger = ObDirectLoadLogger.getLogger(); + + private final long uniqueId; + private AtomicLong sequence; + + public TraceIdGenerator() { + long ip = 0; + try { + ip = ipToLong(InetAddress.getLocalHost().getHostAddress()); + } catch (Exception e) { + logger.warn("get local host address failed", e); + } + long port = (long) (Math.random() % 65536) << 32; + long isUserRequest = (1l << (32 + 16)); + long reserved = 0; + uniqueId = ip | port | isUserRequest | reserved; + sequence = new AtomicLong(0); + } + + private static long ipToLong(String strIp) { + String[] ip = strIp.split("\\."); + return (Long.parseLong(ip[0]) << 24) + (Long.parseLong(ip[1]) << 16) + + (Long.parseLong(ip[2]) << 8) + (Long.parseLong(ip[3])); + } + + public ObDirectLoadTraceId generate() { + long newSequence = System.currentTimeMillis() * 1000 + sequence.incrementAndGet() + % 1000; + return new ObDirectLoadTraceId(uniqueId, newSequence); + } + + }; + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadException.java new file mode 100644 index 00000000..bd922461 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadException.java @@ -0,0 +1,42 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadException extends Exception { + + public ObDirectLoadException() { + } + + public ObDirectLoadException(String message) { + super(message); + } + + public ObDirectLoadException(String message, Throwable cause) { + super(message, cause); + } + + public ObDirectLoadException(Throwable cause) { + super(cause); + } + + protected ObDirectLoadException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadExceptionUtil.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadExceptionUtil.java new file mode 100644 index 00000000..d1f5c3aa --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadExceptionUtil.java @@ -0,0 +1,89 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +import com.alipay.oceanbase.rpc.bolt.transport.TransportCodes; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObTableLoadClientStatus; +import com.alipay.oceanbase.rpc.exception.ObTableException; +import com.alipay.oceanbase.rpc.exception.ObTableTransportException; +import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes; + +public class ObDirectLoadExceptionUtil { + + public static ObDirectLoadException convertException(Exception e) { + if (e instanceof ObDirectLoadException) { + return (ObDirectLoadException) e; + } + // runtime exception + if (e instanceof NullPointerException) { + return new ObDirectLoadNullPointerException(e); + } + if (e instanceof IllegalArgumentException) { + return new ObDirectLoadIllegalArgumentException(e); + } + if (e instanceof IllegalStateException) { + return new ObDirectLoadIllegalStateException(e); + } + if (e instanceof java.util.concurrent.TimeoutException) { + return new ObDirectLoadTimeoutException(e); + } + if (e instanceof io.netty.handler.timeout.TimeoutException) { + return new ObDirectLoadTimeoutException(e); + } + // interrupted exception + if (e instanceof InterruptedException) { + return new ObDirectLoadInterruptedException(e); + } + // rpc exception + if (e instanceof ObTableTransportException) { + int errorCode = ((ObTableTransportException) e).getErrorCode(); + if (errorCode == TransportCodes.BOLT_TIMEOUT) { + return new ObDirectLoadRpcTimeoutException(e); + } else if (errorCode == TransportCodes.BOLT_SEND_FAILED) { + return new ObDirectLoadRpcSendFailedException(e); + } else if (errorCode == TransportCodes.BOLT_RESPONSE_NULL) { + return new ObDirectLoadRpcResponseNullException(e); + } else if (errorCode == TransportCodes.BOLT_CHECKSUM_ERR) { + return new ObDirectLoadRpcChecksumErrorException(e); + } else { + return new ObDirectLoadRpcException(e); + } + } + // server exception + if (e instanceof ObTableException) { + int errorCode = ((ObTableException) e).getErrorCode(); + return new ObDirectLoadServerException(errorCode, e); + } + // unknow exception + return new ObDirectLoadException(e); + } + + public static ObDirectLoadInterruptedException convertException(InterruptedException e) { + return new ObDirectLoadInterruptedException(e); + } + + public static ObDirectLoadServerStatusException convertException(ObTableLoadClientStatus status, + int errorCode) { + ResultCodes resultCodes = ResultCodes.valueOf(errorCode); + if (resultCodes != null) { + return new ObDirectLoadServerStatusException(status, resultCodes); + } + return new ObDirectLoadServerStatusException(status, errorCode); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadIllegalArgumentException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadIllegalArgumentException.java new file mode 100644 index 00000000..744e77d9 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadIllegalArgumentException.java @@ -0,0 +1,37 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadIllegalArgumentException extends ObDirectLoadRuntimeException { + + public ObDirectLoadIllegalArgumentException() { + } + + public ObDirectLoadIllegalArgumentException(String message) { + super(message); + } + + public ObDirectLoadIllegalArgumentException(String message, Throwable cause) { + super(message, cause); + } + + public ObDirectLoadIllegalArgumentException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadIllegalStateException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadIllegalStateException.java new file mode 100644 index 00000000..1f5f38e2 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadIllegalStateException.java @@ -0,0 +1,37 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadIllegalStateException extends ObDirectLoadRuntimeException { + + public ObDirectLoadIllegalStateException() { + } + + public ObDirectLoadIllegalStateException(String message) { + super(message); + } + + public ObDirectLoadIllegalStateException(Throwable cause) { + super(cause); + } + + public ObDirectLoadIllegalStateException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadInterruptedException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadInterruptedException.java new file mode 100644 index 00000000..fc20b164 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadInterruptedException.java @@ -0,0 +1,37 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadInterruptedException extends ObDirectLoadException { + + public ObDirectLoadInterruptedException() { + } + + public ObDirectLoadInterruptedException(String message) { + super(message); + } + + public ObDirectLoadInterruptedException(String message, Throwable cause) { + super(message, cause); + } + + public ObDirectLoadInterruptedException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadNotSupportedException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadNotSupportedException.java new file mode 100644 index 00000000..983fdd63 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadNotSupportedException.java @@ -0,0 +1,29 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadNotSupportedException extends ObDirectLoadRuntimeException { + + public ObDirectLoadNotSupportedException() { + } + + public ObDirectLoadNotSupportedException(String message) { + super(message); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadNullPointerException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadNullPointerException.java new file mode 100644 index 00000000..3d37d094 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadNullPointerException.java @@ -0,0 +1,33 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadNullPointerException extends ObDirectLoadRuntimeException { + + public ObDirectLoadNullPointerException() { + } + + public ObDirectLoadNullPointerException(String message) { + super(message); + } + + public ObDirectLoadNullPointerException(Throwable cause) { + super(cause); + } + +} \ No newline at end of file diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcChecksumErrorException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcChecksumErrorException.java new file mode 100644 index 00000000..b5f0f51f --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcChecksumErrorException.java @@ -0,0 +1,26 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadRpcChecksumErrorException extends ObDirectLoadRpcException { + + public ObDirectLoadRpcChecksumErrorException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcException.java new file mode 100644 index 00000000..3e82d2e4 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcException.java @@ -0,0 +1,42 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadRpcException extends ObDirectLoadException { + + public ObDirectLoadRpcException() { + } + + public ObDirectLoadRpcException(String message) { + super(message); + } + + public ObDirectLoadRpcException(String message, Throwable cause) { + super(message, cause); + } + + public ObDirectLoadRpcException(Throwable cause) { + super(cause); + } + + protected ObDirectLoadRpcException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcResponseNullException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcResponseNullException.java new file mode 100644 index 00000000..4a60fb2c --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcResponseNullException.java @@ -0,0 +1,26 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadRpcResponseNullException extends ObDirectLoadRpcException { + + public ObDirectLoadRpcResponseNullException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcSendFailedException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcSendFailedException.java new file mode 100644 index 00000000..527dcdf7 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcSendFailedException.java @@ -0,0 +1,26 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadRpcSendFailedException extends ObDirectLoadRpcException { + + public ObDirectLoadRpcSendFailedException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcTimeoutException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcTimeoutException.java new file mode 100644 index 00000000..df354d8d --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRpcTimeoutException.java @@ -0,0 +1,26 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadRpcTimeoutException extends ObDirectLoadRpcException { + + public ObDirectLoadRpcTimeoutException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRuntimeException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRuntimeException.java new file mode 100644 index 00000000..a6ada0f3 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadRuntimeException.java @@ -0,0 +1,42 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadRuntimeException extends ObDirectLoadException { + + public ObDirectLoadRuntimeException() { + } + + public ObDirectLoadRuntimeException(String message) { + super(message); + } + + public ObDirectLoadRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public ObDirectLoadRuntimeException(Throwable cause) { + super(cause); + } + + protected ObDirectLoadRuntimeException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadServerException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadServerException.java new file mode 100644 index 00000000..97f3b4b6 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadServerException.java @@ -0,0 +1,43 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadServerException extends ObDirectLoadException { + + private final int errorCode; + + public ObDirectLoadServerException(int errorCode) { + super("error code: " + errorCode); + this.errorCode = errorCode; + } + + public ObDirectLoadServerException(int errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + + public ObDirectLoadServerException(int errorCode, Throwable cause) { + super(cause.getMessage(), cause); + this.errorCode = errorCode; + } + + public int getErrorCode() { + return errorCode; + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadServerStatusException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadServerStatusException.java new file mode 100644 index 00000000..b8ffa6ad --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadServerStatusException.java @@ -0,0 +1,48 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObTableLoadClientStatus; +import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes; + +public class ObDirectLoadServerStatusException extends ObDirectLoadException { + + private final ObTableLoadClientStatus status; + private final int errorCode; + + public ObDirectLoadServerStatusException(ObTableLoadClientStatus status, int errorCode) { + super("status:" + status + ", errorCode:" + errorCode); + this.status = status; + this.errorCode = errorCode; + } + + public ObDirectLoadServerStatusException(ObTableLoadClientStatus status, ResultCodes errorCode) { + super("status:" + status + ", errorCode:" + errorCode); + this.status = status; + this.errorCode = errorCode.errorCode; + } + + public ObTableLoadClientStatus getStatus() { + return status; + } + + public int getErrorCode() { + return errorCode; + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadTimeoutException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadTimeoutException.java new file mode 100644 index 00000000..a456dc02 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadTimeoutException.java @@ -0,0 +1,33 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadTimeoutException extends ObDirectLoadRuntimeException { + + public ObDirectLoadTimeoutException() { + } + + public ObDirectLoadTimeoutException(String message) { + super(message); + } + + public ObDirectLoadTimeoutException(Throwable cause) { + super(cause); + } + +} \ No newline at end of file diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadUnexpectedException.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadUnexpectedException.java new file mode 100644 index 00000000..76054823 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/exception/ObDirectLoadUnexpectedException.java @@ -0,0 +1,29 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.exception; + +public class ObDirectLoadUnexpectedException extends ObDirectLoadRuntimeException { + + public ObDirectLoadUnexpectedException() { + } + + public ObDirectLoadUnexpectedException(String message) { + super(message); + } + +} \ No newline at end of file diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementAbortTask.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementAbortTask.java new file mode 100644 index 00000000..a057e4cb --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementAbortTask.java @@ -0,0 +1,111 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.execution; + +import java.util.concurrent.TimeUnit; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadConnection; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadServerException; +import com.alipay.oceanbase.rpc.direct_load.future.ObDirectLoadStatementAsyncPromiseTask; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadAbortRpc; +import com.alipay.oceanbase.rpc.direct_load.util.ObDirectLoadIntervalUtil; +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadProtocol; +import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes; +import com.alipay.oceanbase.rpc.table.ObTable; + +public class ObDirectLoadStatementAbortTask extends ObDirectLoadStatementAsyncPromiseTask { + + private final ObDirectLoadConnection connection; + private final ObDirectLoadProtocol protocol; + private final ObDirectLoadStatementExecutor executor; + + private static final int STATE_NONE = 0; + private static final int STATE_SEND_ABORT = 1; + private static final int STATE_SUCC = 3; + private static final int STATE_FAIL = 4; + + private int state = STATE_NONE; + private ObDirectLoadIntervalUtil intervalUtil = new ObDirectLoadIntervalUtil(); + + public ObDirectLoadStatementAbortTask(ObDirectLoadStatement statement, + ObDirectLoadStatementExecutor executor) { + super(statement); + this.connection = statement.getConnection(); + this.protocol = connection.getProtocol(); + this.executor = executor; + } + + @Override + public void run() { + try { + if (state == STATE_NONE) { + state = STATE_SEND_ABORT; + } + if (state == STATE_SEND_ABORT) { + sendAbort(); + } + if (state == STATE_SUCC) { + setSuccess(); + } + } catch (ObDirectLoadException e) { + logger.warn("statement abort task run failed", e); + state = STATE_FAIL; + setFailure(e); + } + } + + private void sendAbort() throws ObDirectLoadException { + try { + doSendAbort(); + if (intervalUtil.reachTimeInterval(10 * 1000)) { + logger.info("statement waiting abort"); + } + schedule(500, TimeUnit.MILLISECONDS); + } catch (ObDirectLoadException e) { + if (e instanceof ObDirectLoadServerException) { + final int errorCode = ((ObDirectLoadServerException) e).getErrorCode(); + if (errorCode == ResultCodes.OB_ENTRY_NOT_EXIST.errorCode) { + logger.info("statement is aborted"); + state = STATE_SUCC; + return; + } + } + throw e; + } + + } + + private ObDirectLoadAbortRpc doSendAbort() throws ObDirectLoadException { + final ObTable table = statement.getObTablePool().getControlObTable(); + final long timeoutMillis = statement.getTimeoutRemain(); + + ObDirectLoadAbortRpc rpc = protocol.getAbortRpc(executor.getTraceId()); + rpc.setSvrAddr(executor.getSvrAddr()); + rpc.setTableId(executor.getTableId()); + rpc.setTaskId(executor.getTaskId()); + + logger.debug("statement send abort rpc"); + connection.executeWithConnection(rpc, table, timeoutMillis); + logger.debug("statement abort rpc response successful"); + + return rpc; + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementBeginTask.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementBeginTask.java new file mode 100644 index 00000000..a82c851e --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementBeginTask.java @@ -0,0 +1,271 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.execution; + +import java.util.concurrent.TimeUnit; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadConnection; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadRuntimeInfo; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadExceptionUtil; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadRpcException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadServerException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadServerStatusException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadTimeoutException; +import com.alipay.oceanbase.rpc.direct_load.future.ObDirectLoadStatementAsyncPromiseTask; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadBeginRpc; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadGetStatusRpc; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObTableLoadClientStatus; +import com.alipay.oceanbase.rpc.direct_load.util.ObDirectLoadIntervalUtil; +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadProtocol; +import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes; +import com.alipay.oceanbase.rpc.table.ObTable; + +public class ObDirectLoadStatementBeginTask extends ObDirectLoadStatementAsyncPromiseTask { + + private final ObDirectLoadConnection connection; + private final ObDirectLoadProtocol protocol; + private final ObDirectLoadStatementExecutor executor; + private final ObDirectLoadStatementExecutor.BeginProxy proxy; + + private static final int STATE_NONE = 0; + private static final int STATE_SEND_BEGIN = 1; + private static final int STATE_WAIT_STATUS_RUNNING = 2; + private static final int STATE_SUCC = 3; + private static final int STATE_FAIL = 4; + + private int state = STATE_NONE; + private int retryCount = 0; + private int rebeginCount = 0; + private ObDirectLoadIntervalUtil intervalUtil = new ObDirectLoadIntervalUtil(); + private ObDirectLoadRuntimeInfo runtimeInfo = new ObDirectLoadRuntimeInfo(); + + public ObDirectLoadStatementBeginTask(ObDirectLoadStatement statement, + ObDirectLoadStatementExecutor executor) { + super(statement); + this.connection = statement.getConnection(); + this.protocol = connection.getProtocol(); + this.executor = executor; + this.proxy = executor.getBeginProxy(); + } + + @Override + public ObDirectLoadRuntimeInfo getRuntimeInfo() { + return runtimeInfo; + } + + @Override + public void run() { + runtimeInfo.incScheduledCount(); + runtimeInfo.setLastScheduledTime(System.currentTimeMillis()); + try { + proxy.checkStatus(); + if (state == STATE_NONE) { + state = STATE_SEND_BEGIN; + } + if (state == STATE_SEND_BEGIN) { + sendBegin(); + } + if (state == STATE_WAIT_STATUS_RUNNING) { + waitStatusRunning(); + } + if (state == STATE_SUCC) { + proxy.setSuccess(); + setSuccess(); + } + } catch (ObDirectLoadException e) { + logger.warn("statement begin task run failed", e); + state = STATE_FAIL; + proxy.setFailure(e); + setFailure(e); + } + } + + private static boolean isRetryCode(int errorCode) { + return (errorCode == ResultCodes.OB_ENTRY_NOT_EXIST.errorCode // -4018 + || errorCode == ResultCodes.OB_SIZE_OVERFLOW.errorCode // -4019 + || errorCode == ResultCodes.OB_EAGAIN.errorCode // -4023 + || errorCode == ResultCodes.OB_NOT_MASTER.errorCode // -4038 + || errorCode == ResultCodes.OB_OP_NOT_ALLOW.errorCode // -4179 + || errorCode == ResultCodes.OB_LS_NOT_EXIST.errorCode // -4719 + || errorCode == ResultCodes.OB_TABLET_NOT_EXIST.errorCode // -4725 + || errorCode == ResultCodes.OB_SCHEMA_EAGAIN.errorCode // -5627 + || errorCode == ResultCodes.OB_ERR_PARALLEL_DDL_CONFLICT.errorCode // -5827 + ); + } + + private boolean canRetry(ObDirectLoadException e) { + boolean bResult = false; + if (e instanceof ObDirectLoadRpcException) { + // 只对异步begin的rpc超时重试, 同步begin重试大概率还是超时 + bResult = (e instanceof ObDirectLoadTimeoutException); + } else if (e instanceof ObDirectLoadServerException) { + final int errorCode = ((ObDirectLoadServerException) e).getErrorCode(); + bResult = isRetryCode(errorCode); + } else if (e instanceof ObDirectLoadServerStatusException) { + final int errorCode = ((ObDirectLoadServerStatusException) e).getErrorCode(); + bResult = isRetryCode(errorCode); + } + // TODO: 细化可重试异常 + return bResult; + } + + private void sendBegin() throws ObDirectLoadException { + try { + ObDirectLoadBeginRpc rpc = null; + try { + rpc = doSendBeginRpc(); + } catch (ObDirectLoadException e) { + logger.warn("statement send begin rpc failed", e); + throw e; + } + ObTableLoadClientStatus status = rpc.getStatus(); + int errorCode = rpc.getErrorCode(); + switch (status) { + case INITIALIZING: + case WAITTING: + proxy.setSuccess0(rpc.getSvrAddr(), rpc.getTableId(), rpc.getTaskId()); + state = STATE_WAIT_STATUS_RUNNING; + break; + case RUNNING: + proxy.setSuccess0(rpc.getSvrAddr(), rpc.getTableId(), rpc.getTaskId()); + logger.info("statement server status reach running"); + state = STATE_SUCC; + break; + case ERROR: + logger.warn("statement server status is error, errorCode:" + errorCode); + throw ObDirectLoadExceptionUtil.convertException(status, errorCode); + case ABORT: + logger.warn("statement server status is abort, errorCode:" + errorCode); + if (errorCode == ResultCodes.OB_SUCCESS.errorCode) { + errorCode = ResultCodes.OB_CANCELED.errorCode; + } + throw ObDirectLoadExceptionUtil.convertException(status, errorCode); + default: + logger.warn("statement server status is unexpected, status:" + status); + throw ObDirectLoadExceptionUtil.convertException(status, errorCode); + } + } catch (ObDirectLoadException e) { + if (canRetry(e)) { + ++retryCount; + logger.info("statement retry send begin rpc after 1s, retryCount:" + retryCount); + // retry after 1s + schedule(1000, TimeUnit.MILLISECONDS); + return; + } + throw e; + } + } + + private ObDirectLoadBeginRpc doSendBeginRpc() throws ObDirectLoadException { + final ObTable table = statement.getObTablePool().getControlObTable(); + final long timeoutMillis = statement.getTimeoutRemain(); + + ObDirectLoadBeginRpc rpc = protocol.getBeginRpc(statement.getTraceId()); + rpc.setTableName(statement.getTableName()); + rpc.setParallel(statement.getParallel()); + rpc.setMaxErrorRowCount(statement.getMaxErrorRowCount()); + rpc.setDupAction(statement.getDupAction()); + rpc.setTimeout(statement.getQueryTimeout() * 1000); + rpc.setHeartBeatTimeout(connection.getHeartBeatTimeout() * 1000); + rpc.setLoadMethod(statement.getLoadMethod()); + rpc.setColumnNames(statement.getColumnNames()); + rpc.setPartitionNames(statement.getPartitionNames()); + + logger.info("statement send begin rpc, arg:" + rpc.getArg()); + connection.executeWithConnection(rpc, table, timeoutMillis); + logger.info("statement begin rpc response successful, svrAddr:" + rpc.getSvrAddr() + + ", res:" + rpc.getRes()); + + return rpc; + } + + private void waitStatusRunning() throws ObDirectLoadException { + try { + ObDirectLoadGetStatusRpc rpc = null; + try { + rpc = doSendGetStatus(); + } catch (ObDirectLoadException e) { + logger.warn("statement send get status rpc failed", e); + throw e; + } + ObTableLoadClientStatus status = rpc.getStatus(); + int errorCode = rpc.getErrorCode(); + switch (status) { + case INITIALIZING: + case WAITTING: + if (intervalUtil.reachTimeInterval(10000)) { // 每隔10s打印一次 + logger.info("statement waiting server status reach running, status:" + + status); + } + // retry after 500ms + schedule(500, TimeUnit.MILLISECONDS); + break; + case RUNNING: + logger.info("statement server status reach running"); + state = STATE_SUCC; + break; + case ERROR: + logger.warn("statement server status is error, errorCode:" + errorCode); + throw ObDirectLoadExceptionUtil.convertException(status, errorCode); + case ABORT: + logger.warn("statement server status is abort, errorCode:" + errorCode); + if (errorCode == ResultCodes.OB_SUCCESS.errorCode) { + errorCode = ResultCodes.OB_CANCELED.errorCode; + } + throw ObDirectLoadExceptionUtil.convertException(status, errorCode); + default: + logger.warn("statement server status is unexpected, status:" + status); + throw ObDirectLoadExceptionUtil.convertException(status, errorCode); + } + } catch (ObDirectLoadException e) { + if (e instanceof ObDirectLoadServerStatusException) { + if (canRetry(e)) { + ++rebeginCount; + retryCount = 0; + logger.info("statement retry begin after 1s, rebeginCount:" + rebeginCount); + proxy.clear(); + state = STATE_NONE; + schedule(1000, TimeUnit.MILLISECONDS); + return; + } + throw e; + } + // retry after 500ms + schedule(500, TimeUnit.MILLISECONDS); + } + } + + private ObDirectLoadGetStatusRpc doSendGetStatus() throws ObDirectLoadException { + final ObTable table = statement.getObTablePool().getControlObTable(); + final long timeoutMillis = statement.getTimeoutRemain(); + + ObDirectLoadGetStatusRpc rpc = protocol.getGetStatusRpc(executor.getTraceId()); + rpc.setSvrAddr(executor.getSvrAddr()); + rpc.setTableId(executor.getTableId()); + rpc.setTaskId(executor.getTaskId()); + + logger.debug("statement send get status rpc, arg:" + rpc.getArg()); + connection.executeWithConnection(rpc, table, timeoutMillis); + logger.debug("statement get status rpc response successful, res:" + rpc.getRes()); + + return rpc; + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementCommitTask.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementCommitTask.java new file mode 100644 index 00000000..d6a7960a --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementCommitTask.java @@ -0,0 +1,183 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.execution; + +import java.util.concurrent.TimeUnit; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadConnection; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadRuntimeInfo; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadExceptionUtil; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadServerStatusException; +import com.alipay.oceanbase.rpc.direct_load.future.ObDirectLoadStatementAsyncPromiseTask; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadCommitRpc; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadGetStatusRpc; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObTableLoadClientStatus; +import com.alipay.oceanbase.rpc.direct_load.util.ObDirectLoadIntervalUtil; +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadProtocol; +import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes; +import com.alipay.oceanbase.rpc.table.ObTable; + +public class ObDirectLoadStatementCommitTask extends ObDirectLoadStatementAsyncPromiseTask { + + private final ObDirectLoadConnection connection; + private final ObDirectLoadProtocol protocol; + private final ObDirectLoadStatementExecutor executor; + private final ObDirectLoadStatementExecutor.CommitProxy proxy; + + private static final int STATE_NONE = 0; + private static final int STATE_SEND_COMMIT = 1; + private static final int STATE_WAIT_STATUS_COMMIT = 2; + private static final int STATE_SUCC = 3; + private static final int STATE_FAIL = 4; + + private int state = STATE_NONE; + private ObDirectLoadIntervalUtil intervalUtil = new ObDirectLoadIntervalUtil(); + private ObDirectLoadRuntimeInfo runtimeInfo = new ObDirectLoadRuntimeInfo(); + + public ObDirectLoadStatementCommitTask(ObDirectLoadStatement statement, + ObDirectLoadStatementExecutor executor) { + super(statement); + this.connection = statement.getConnection(); + this.protocol = connection.getProtocol(); + this.executor = executor; + this.proxy = executor.getCommitProxy(); + } + + @Override + public ObDirectLoadRuntimeInfo getRuntimeInfo() { + return runtimeInfo; + } + + @Override + public void run() { + runtimeInfo.incScheduledCount(); + runtimeInfo.setLastScheduledTime(System.currentTimeMillis()); + try { + proxy.checkStatus(); + if (state == STATE_NONE) { + state = STATE_SEND_COMMIT; + } + if (state == STATE_SEND_COMMIT) { + sendCommit(); + } + if (state == STATE_WAIT_STATUS_COMMIT) { + waitStatusCommit(); + } + if (state == STATE_SUCC) { + proxy.setSuccess(); + setSuccess(); + } + } catch (ObDirectLoadException e) { + logger.warn("statement commit task run failed", e); + state = STATE_FAIL; + proxy.setFailure(e); + setFailure(e); + } + } + + private void sendCommit() throws ObDirectLoadException { + try { + doSendCommit(); + state = STATE_WAIT_STATUS_COMMIT; + } catch (ObDirectLoadException e) { + logger.warn("statement send commit rpc failed", e); + throw e; + } + } + + private ObDirectLoadCommitRpc doSendCommit() throws ObDirectLoadException { + final ObTable table = statement.getObTablePool().getControlObTable(); + final long timeoutMillis = statement.getTimeoutRemain(); + + ObDirectLoadCommitRpc rpc = protocol.getCommitRpc(executor.getTraceId()); + rpc.setSvrAddr(executor.getSvrAddr()); + rpc.setTableId(executor.getTableId()); + rpc.setTaskId(executor.getTaskId()); + + logger.info("statement send commit rpc, arg:" + rpc.getArg()); + connection.executeWithConnection(rpc, table, timeoutMillis); + logger.info("statement commit rpc response successful, res:" + rpc.getRes()); + + return rpc; + } + + private void waitStatusCommit() throws ObDirectLoadException { + try { + ObDirectLoadGetStatusRpc rpc = null; + try { + rpc = doGetStatus(); + } catch (ObDirectLoadException e) { + logger.warn("statement send get status rpc failed", e); + throw e; + } + ObTableLoadClientStatus status = rpc.getStatus(); + int errorCode = rpc.getErrorCode(); + switch (status) { + case COMMITTING: + if (intervalUtil.reachTimeInterval(10000)) { // 每隔1s打印一次 + logger.info("statement waiting server status reach commit, status:" + + status); + } + // retry after 500ms + schedule(500, TimeUnit.MILLISECONDS); + break; + case COMMIT: + logger.info("statement server status reach commit"); + state = STATE_SUCC; + break; + case ERROR: + logger.warn("statement server status is error, errorCode:" + errorCode); + throw ObDirectLoadExceptionUtil.convertException(status, errorCode); + case ABORT: + logger.warn("statement server status is abort, errorCode:" + errorCode); + if (errorCode == ResultCodes.OB_SUCCESS.errorCode) { + errorCode = ResultCodes.OB_CANCELED.errorCode; + } + throw ObDirectLoadExceptionUtil.convertException(status, errorCode); + default: + logger.warn("statement server status is unexpected, status:" + status); + throw ObDirectLoadExceptionUtil.convertException(status, errorCode); + } + } catch (ObDirectLoadException e) { + if (e instanceof ObDirectLoadServerStatusException) { + throw e; + } + // retry after 500ms + schedule(500, TimeUnit.MILLISECONDS); + } + } + + private ObDirectLoadGetStatusRpc doGetStatus() throws ObDirectLoadException { + final ObTable table = statement.getObTablePool().getControlObTable(); + final long timeoutMillis = statement.getTimeoutRemain(); + + ObDirectLoadGetStatusRpc rpc = protocol.getGetStatusRpc(executor.getTraceId()); + rpc.setSvrAddr(executor.getSvrAddr()); + rpc.setTableId(executor.getTableId()); + rpc.setTaskId(executor.getTaskId()); + + logger.debug("statement send get status rpc, arg:" + rpc.getArg()); + connection.executeWithConnection(rpc, table, timeoutMillis); + logger.debug("statement get status rpc response successful, res:" + rpc.getRes()); + + return rpc; + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementExecutor.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementExecutor.java new file mode 100644 index 00000000..882da946 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementExecutor.java @@ -0,0 +1,545 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.execution; + +import java.util.concurrent.atomic.AtomicInteger; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadBucket; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadConnection; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadLogger; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadTraceId; +import com.alipay.oceanbase.rpc.direct_load.exception.*; +import com.alipay.oceanbase.rpc.direct_load.future.*; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; + +public class ObDirectLoadStatementExecutor { + + // begin : NONE -> PREPARE_BEGIN -> BEGINNING -> LOADING | FAIL + // commit : LOADING -> PREPARE_COMMIT -> COMMITTING -> COMMIT | FAIL + // heartbeat : LOADING -> LOADING | FAIL + // abort : LOADING | FAIL -> ABORT + private static final int NONE = 0; + private static final int BEGINNING = 1; + private static final int LOADING = 2; // 可以导入数据 + private static final int COMMITTING = 3; + private static final int COMMIT = 4; + private static final int FAIL = 5; + private static final int ABORT = 6; + private AtomicInteger stateFlag = new AtomicInteger(NONE); + + private final ObDirectLoadStatement statement; + private final ObDirectLoadTraceId traceId; + private final ObDirectLoadLogger logger; + + private ObDirectLoadStatementFuture beginFuture = null; + private ObDirectLoadStatementFuture commitFuture = null; + private ObDirectLoadStatementHeartBeatTask heartBeatTask = null; + private ObDirectLoadStatementFuture abortFuture = null; + + private long tableId = 0; + private long taskId = 0; + private ObAddr svrAddr = null; + private ObDirectLoadException cause = null; // 失败原因 + + public ObDirectLoadStatementExecutor(ObDirectLoadStatement statement) { + this.statement = statement; + this.traceId = statement.getTraceId(); + this.logger = statement.getLogger(); + } + + public ObDirectLoadStatement getStatement() { + return statement; + } + + public ObDirectLoadTraceId getTraceId() { + return traceId; + } + + public ObDirectLoadLogger getLogger() { + return logger; + } + + public long getTableId() { + return tableId; + } + + public long getTaskId() { + return taskId; + } + + public ObAddr getSvrAddr() { + return svrAddr; + } + + public String toString() { + return String.format("{svrAddr:%s, tableId:%d, taskId:%d}", svrAddr, tableId, taskId); + } + + public synchronized ObDirectLoadStatementFuture begin() { + logger.info("statement call begin"); + ObDirectLoadStatementAsyncPromiseTask task = null; + try { + compareAndSetState(NONE, BEGINNING, "begin"); + } catch (ObDirectLoadException e) { + logger.warn("statement begin failed", e); + return new ObDirectLoadStatementFailedFuture(statement, e); + } + try { + task = new ObDirectLoadStatementBeginTask(statement, this); + task.submit(); + beginFuture = task; + } catch (ObDirectLoadException e) { + logger.warn("statement start begin failed", e); + cause = e; + tryCompareAndSetState(BEGINNING, FAIL, "set begin failure"); + } + return task; + } + + public synchronized ObDirectLoadStatementFuture commit() { + logger.info("statement call commit"); + ObDirectLoadStatementAsyncPromiseTask task = null; + try { + compareAndSetState(LOADING, COMMITTING, "commit"); + } catch (ObDirectLoadException e) { + logger.warn("statement commit failed", e); + return new ObDirectLoadStatementFailedFuture(statement, e); + } + try { + task = new ObDirectLoadStatementCommitTask(statement, this); + task.submit(); + commitFuture = task; + } catch (ObDirectLoadException e) { + logger.warn("statement start commit failed", e); + cause = e; + tryCompareAndSetState(COMMITTING, FAIL, "set commit failure"); + } + return task; + } + + public synchronized void close() { + // 如果begin还在执行, 等待begin结束 + if (beginFuture != null && !beginFuture.isDone()) { + logger.info("statement close wait begin"); + try { + beginFuture.await(); + } catch (ObDirectLoadInterruptedException e) { + logger.warn("statement wait begin failed"); + } + } + beginFuture = null; + // 如果commit还在执行, 等待commit结束 + if (commitFuture != null && !commitFuture.isDone()) { + logger.info("statement close wait commit"); + try { + commitFuture.await(); + } catch (ObDirectLoadInterruptedException e) { + logger.warn("statement wait commit failed"); + } + } + commitFuture = null; + // 如果heart beat还在执行, 取消heart beat + if (heartBeatTask != null && !heartBeatTask.isDone()) { + logger.info("statement close wait heart beat"); + final boolean canceled = heartBeatTask.cancel(); + if (!canceled) { + try { + heartBeatTask.await(); + } catch (ObDirectLoadInterruptedException e) { + logger.warn("statement wait heart beat failed"); + } + } + } + heartBeatTask = null; + // 退出任务 + abortIfNeed(); + if (abortFuture != null) { + try { + if (!abortFuture.isDone()) { + logger.info("statement close wait abort"); + abortFuture.await(); + } + if (!abortFuture.isSuccess()) { + throw abortFuture.cause(); + } + logger.info("statement abort successful"); + } catch (ObDirectLoadException e) { + logger.warn("statement abort failed", e); + } + } + } + + private void abortIfNeed() { + logger.debug("statement abort if need"); + if (abortFuture != null) { + logger.debug("statement in abort"); + return; + } + final int state = stateFlag.get(); + boolean needAbort = false; + boolean unexpectedState = false; + String reason = ""; + if (state == NONE) { + reason = "not begin"; + } else if (state == BEGINNING) { + unexpectedState = true; + reason = "begin not finish"; + } else if (state == LOADING) { + needAbort = true; + } else if (state == COMMITTING) { + unexpectedState = true; + reason = "commit not finish"; + } else if (state == COMMIT) { + reason = "already commit"; + } else if (state == FAIL) { + if (svrAddr != null) { + needAbort = true; + } else { + reason = "begin fail"; + } + } else if (state == ABORT) { + reason = "already abort"; + } + if (!needAbort) { + if (unexpectedState) { + logger.warn("statement cannot abort because " + reason); + } else { + logger.debug("statement no need abort because " + reason); + setState(ABORT); + } + } else { + abort(); + } + } + + private ObDirectLoadStatementFuture abort() { + logger.info("statement call abort"); + setState(ABORT); + ObDirectLoadStatementAsyncPromiseTask task = null; + try { + task = new ObDirectLoadStatementAbortTask(statement, this); + task.submit(); + abortFuture = task; + } catch (ObDirectLoadException e) { + logger.warn("statement start abort failed", e); + } + return task; + } + + void startHeartBeat() throws ObDirectLoadException { + logger.info("statement start heart beat"); + try { + ObDirectLoadStatementHeartBeatTask task = new ObDirectLoadStatementHeartBeatTask( + statement, this); + task.submit(); + heartBeatTask = task; + } catch (ObDirectLoadException e) { + logger.warn("statement start heart beat failed", e); + throw e; + } + } + + void stopHeartBeat() { + logger.info("statement stop heart beat"); + try { + ObDirectLoadStatementHeartBeatTask task = heartBeatTask; + if (task == null) { + logger.warn("statement heart beat not start"); + throw new ObDirectLoadUnexpectedException("statement heart beat not start"); + } + final boolean canceled = task.cancel(); + if (!canceled) { + return; + } + heartBeatTask = null; + } catch (ObDirectLoadException e) { + logger.warn("statement stop heart beat failed", e); + } + } + + public void write(ObDirectLoadBucket bucket) throws ObDirectLoadException { + checkState(LOADING, "write"); + ObDirectLoadStatementPromiseTask task = new ObDirectLoadStatementWriteTask(statement, this, + bucket); + task.run(); + if (!task.isDone()) { + logger.warn("statement write task unexpected not done"); + throw new ObDirectLoadUnexpectedException("statement write task unexpected not done"); + } + if (!task.isSuccess()) { + throw task.cause(); + } + } + + private String getUnexpectedStateReason(int state) { + String reason = ""; + if (state == NONE) { + reason = "not begin"; + } else if (state == BEGINNING) { + reason = "is beginning"; + } else if (state == LOADING) { + reason = "is loading"; + } else if (state == COMMITTING) { + reason = "is committing"; + } else if (state == COMMIT) { + reason = "is commit"; + } else if (state == FAIL || state == ABORT) { + reason = "is fail"; + } else { + reason = "unknow state"; + } + return reason; + } + + void compareAndSetState(int expect, int update, String action) + throws ObDirectLoadIllegalStateException { + if (!stateFlag.compareAndSet(expect, update)) { + final int state = stateFlag.get(); + String reason = getUnexpectedStateReason(state); + String message = "statement cannot " + action + " because " + reason + ", state:" + + state + ", expect:" + expect + ", update:" + update; + logger.warn(message); + if (cause == null) { + throw new ObDirectLoadIllegalStateException(message); + } else { + throw new ObDirectLoadIllegalStateException(message, cause); + } + } + } + + boolean tryCompareAndSetState(int expect, int update, String action) { + boolean bResult = stateFlag.compareAndSet(expect, update); + if (!bResult) { + final int state = stateFlag.get(); + String reason = getUnexpectedStateReason(state); + String message = "statement cannot " + action + " because " + reason + ", state:" + + state + ", expect:" + expect + ", update:" + update; + logger.warn(message); + } + return bResult; + } + + void setState(int update) { + stateFlag.set(update); + } + + void checkState(int expect, String action) throws ObDirectLoadException { + final int state = stateFlag.get(); + if (state != expect) { + String reason = getUnexpectedStateReason(state); + String message = "statement cannot " + action + " because " + reason + ", state:" + + state + ", expect:" + expect; + logger.warn(message); + if (cause == null) { + throw new ObDirectLoadIllegalStateException(message); + } else { + throw new ObDirectLoadIllegalStateException(message, cause); + } + } + } + + /** + * check state in range [start, end] + */ + void checkState(int start, int end, String action) throws ObDirectLoadIllegalStateException { + final int state = stateFlag.get(); + if (state < start || state > end) { + String reason = getUnexpectedStateReason(state); + String message = "statement cannot " + action + " because " + reason + ", state:" + + state + ", expect:[" + start + ", " + end + "]"; + logger.warn(message); + if (cause == null) { + throw new ObDirectLoadIllegalStateException(message); + } else { + throw new ObDirectLoadIllegalStateException(message, cause); + } + } + } + + BeginProxy getBeginProxy() { + return new BeginProxy(this); + } + + CommitProxy getCommitProxy() { + return new CommitProxy(this); + } + + WriteProxy getWriteProxy() { + return new WriteProxy(this); + } + + HeartBeatProxy getHeartBeatProxy() { + return new HeartBeatProxy(this); + } + + private static abstract class BaseProxy { + + protected final ObDirectLoadConnection connection; + protected final ObDirectLoadStatement statement; + protected final ObDirectLoadStatementExecutor executor; + protected final ObDirectLoadLogger logger; + + BaseProxy(ObDirectLoadStatementExecutor executor) { + this.executor = executor; + this.statement = executor.getStatement(); + this.connection = statement.getConnection(); + this.logger = statement.getLogger(); + } + + void checkState() throws ObDirectLoadException { + } + + void checkStatus() throws ObDirectLoadException { + connection.checkStatus(); + statement.checkStatus(); + checkState(); + statement.checkTimeout(); + } + + }; + + static final class BeginProxy extends BaseProxy { + + BeginProxy(ObDirectLoadStatementExecutor executor) { + super(executor); + } + + @Override + void checkState() throws ObDirectLoadException { + executor.checkState(BEGINNING, "begin"); + } + + void setSuccess0(ObAddr addr, long tableId, long taskId) throws ObDirectLoadException { + executor.checkState(BEGINNING, "begin"); + executor.svrAddr = addr; + executor.tableId = tableId; + executor.taskId = taskId; + executor.startHeartBeat(); + } + + void setSuccess() throws ObDirectLoadException { + executor.compareAndSetState(BEGINNING, LOADING, "set begin success"); + executor.beginFuture = null; + logger.info("statement begin successful"); + } + + void setFailure(ObDirectLoadException cause) { + try { + executor.compareAndSetState(BEGINNING, FAIL, "set begin failure"); + } catch (ObDirectLoadException e) { + return; + } + executor.cause = cause; + logger.warn("statement begin failed", cause); + synchronized (executor) { + executor.abortIfNeed(); + } + } + + void clear() { + executor.stopHeartBeat(); + } + + }; + + static final class CommitProxy extends BaseProxy { + + CommitProxy(ObDirectLoadStatementExecutor executor) { + super(executor); + } + + @Override + void checkState() throws ObDirectLoadException { + executor.checkState(COMMITTING, "commit"); + } + + void setSuccess() throws ObDirectLoadException { + executor.compareAndSetState(COMMITTING, COMMIT, "set commit success"); + executor.commitFuture = null; + logger.info("statement commit successful"); + executor.stopHeartBeat(); + } + + void setFailure(ObDirectLoadException cause) { + try { + executor.compareAndSetState(COMMITTING, FAIL, "set commit failure"); + } catch (ObDirectLoadException e) { + return; + } + executor.cause = cause; + logger.warn("statement commit failed", cause); + synchronized (executor) { + executor.abortIfNeed(); + } + } + + }; + + static final class WriteProxy extends BaseProxy { + + WriteProxy(ObDirectLoadStatementExecutor executor) { + super(executor); + } + + @Override + void checkState() throws ObDirectLoadException { + executor.checkState(LOADING, "write"); + } + + void setSuccess() throws ObDirectLoadException { + // do nothing + } + + void setFailure(ObDirectLoadException cause) { + // do nothing + } + + }; + + static final class HeartBeatProxy extends BaseProxy { + + HeartBeatProxy(ObDirectLoadStatementExecutor executor) { + super(executor); + } + + @Override + void checkState() throws ObDirectLoadException { + executor.checkState(BEGINNING, COMMIT, "heart beat"); + } + + void setSuccess() throws ObDirectLoadException { + // do nothing + } + + void setFailure(ObDirectLoadException cause) { + try { + executor.compareAndSetState(LOADING, FAIL, "set heart beat failure"); + } catch (ObDirectLoadException e) { + return; + } + executor.cause = cause; + logger.warn("statement heart beat failed", cause); + synchronized (executor) { + executor.abortIfNeed(); + } + } + + }; + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementHeartBeatTask.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementHeartBeatTask.java new file mode 100644 index 00000000..6c01dbbe --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementHeartBeatTask.java @@ -0,0 +1,188 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.execution; + +import java.util.concurrent.TimeUnit; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadConnection; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadExceptionUtil; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadRpcException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadRpcTimeoutException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadServerException; +import com.alipay.oceanbase.rpc.direct_load.future.ObDirectLoadStatementAsyncPromiseTask; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadGetStatusRpc; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadHeartBeatRpc; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObTableLoadClientStatus; +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadProtocol; +import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes; +import com.alipay.oceanbase.rpc.table.ObTable; + +public class ObDirectLoadStatementHeartBeatTask extends ObDirectLoadStatementAsyncPromiseTask { + + private final ObDirectLoadConnection connection; + private final ObDirectLoadProtocol protocol; + private final ObDirectLoadStatementExecutor executor; + private final ObDirectLoadStatementExecutor.HeartBeatProxy proxy; + + private boolean isRunning = false; + private boolean isCancel = false; + + public ObDirectLoadStatementHeartBeatTask(ObDirectLoadStatement statement, + ObDirectLoadStatementExecutor executor) { + super(statement); + this.connection = statement.getConnection(); + this.protocol = connection.getProtocol(); + this.executor = executor; + this.proxy = executor.getHeartBeatProxy(); + } + + public synchronized boolean cancel() { + isCancel = true; + return !isRunning; + } + + @Override + public void run() { + try { + synchronized (this) { + isRunning = true; + if (isCancel) { + setSuccess(); + return; + } + } + proxy.checkStatus(); + sendHeartBeat(); + synchronized (this) { + if (isCancel) { + setSuccess(); + return; + } + } + } catch (ObDirectLoadException e) { + logger.warn("statement heart beat task run failed", e); + proxy.setFailure(e); + setFailure(e); + } finally { + synchronized (this) { + isRunning = false; + } + } + } + + private void sendHeartBeat() throws ObDirectLoadException { + try { + ObTableLoadClientStatus status = ObTableLoadClientStatus.MAX_STATUS; + int errorCode = ResultCodes.OB_SUCCESS.errorCode; + try { + ObDirectLoadHeartBeatRpc rpc = doSendHeartBeat(); + status = rpc.getStatus(); + errorCode = rpc.getErrorCode(); + } catch (ObDirectLoadException e) { + logger.warn("statement send heart beat rpc failed", e); + boolean sendGetStatus = false; + if (e instanceof ObDirectLoadServerException) { + final int ret = ((ObDirectLoadServerException) e).getErrorCode(); + if (ret == ResultCodes.OB_ENTRY_NOT_EXIST.errorCode) { + // 如果心跳找不到任务, 则通过get status获取错误码 + sendGetStatus = true; + try { + ObDirectLoadGetStatusRpc rpc2 = doSendGetStatus(); + status = rpc2.getStatus(); + errorCode = rpc2.getErrorCode(); + } catch (ObDirectLoadException e2) { + logger.warn("statement send get status rpc failed", e2); + throw e2; + } + } + } + if (!sendGetStatus) { + throw e; + } + } + switch (status) { + case INITIALIZING: + case WAITTING: + case RUNNING: + case COMMITTING: + case COMMIT: + schedule(connection.getHeartBeatInterval(), TimeUnit.MILLISECONDS); + break; + case ERROR: + logger.warn("statement server status is error, errorCode:" + errorCode); + throw ObDirectLoadExceptionUtil.convertException(status, errorCode); + case ABORT: + logger.warn("statement server status is abort, errorCode:" + errorCode); + if (errorCode == ResultCodes.OB_SUCCESS.errorCode) { + errorCode = ResultCodes.OB_CANCELED.errorCode; + } + throw ObDirectLoadExceptionUtil.convertException(status, errorCode); + default: + logger.warn("statement server status is unexpected, status:" + status); + throw ObDirectLoadExceptionUtil.convertException(status, errorCode); + } + } catch (ObDirectLoadException e) { + logger.warn("statement send heart beat failed", e); + boolean canRetry = false; + if (e instanceof ObDirectLoadRpcException) { + if (e instanceof ObDirectLoadRpcTimeoutException) { + canRetry = true; + schedule(500, TimeUnit.MILLISECONDS); + } + } + if (!canRetry) { + throw e; + } + } + } + + private ObDirectLoadHeartBeatRpc doSendHeartBeat() throws ObDirectLoadException { + final ObTable table = statement.getObTablePool().getHighPrioObTable(); + final long timeoutMillis = statement.getTimeoutRemain(); + + ObDirectLoadHeartBeatRpc rpc = protocol.getHeartBeatRpc(executor.getTraceId()); + rpc.setSvrAddr(executor.getSvrAddr()); + rpc.setTableId(executor.getTableId()); + rpc.setTaskId(executor.getTaskId()); + + logger.info("statement send heart beat rpc, arg:" + rpc.getArg()); + connection.executeWithConnection(rpc, table, timeoutMillis); + logger.info("statement heart beat rpc response successful, res:" + rpc.getRes()); + + return rpc; + } + + private ObDirectLoadGetStatusRpc doSendGetStatus() throws ObDirectLoadException { + final ObTable table = statement.getObTablePool().getControlObTable(); + final long timeoutMillis = statement.getTimeoutRemain(); + + ObDirectLoadGetStatusRpc rpc = protocol.getGetStatusRpc(executor.getTraceId()); + rpc.setSvrAddr(executor.getSvrAddr()); + rpc.setTableId(executor.getTableId()); + rpc.setTaskId(executor.getTaskId()); + + logger.debug("statement send get status rpc, arg:" + rpc.getArg()); + connection.executeWithConnection(rpc, table, timeoutMillis); + logger.debug("statement get status rpc response successful, res:" + rpc.getRes()); + + return rpc; + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementWriteTask.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementWriteTask.java new file mode 100644 index 00000000..03931913 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/execution/ObDirectLoadStatementWriteTask.java @@ -0,0 +1,122 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.execution; + +import java.util.List; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadBucket; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadConnection; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadExceptionUtil; +import com.alipay.oceanbase.rpc.direct_load.future.ObDirectLoadStatementPromiseTask; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadInsertRpc; +import com.alipay.oceanbase.rpc.table.ObTable; +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadProtocol; +import com.alipay.oceanbase.rpc.util.ObByteBuf; + +public class ObDirectLoadStatementWriteTask extends ObDirectLoadStatementPromiseTask { + + private final ObDirectLoadConnection connection; + private final ObDirectLoadProtocol protocol; + private final ObDirectLoadStatementExecutor executor; + private final ObDirectLoadStatementExecutor.WriteProxy proxy; + private final ObDirectLoadBucket bucket; + + public ObDirectLoadStatementWriteTask(ObDirectLoadStatement statement, + ObDirectLoadStatementExecutor executor, + ObDirectLoadBucket bucket) { + super(statement); + this.connection = statement.getConnection(); + this.protocol = connection.getProtocol(); + this.executor = executor; + this.proxy = executor.getWriteProxy(); + this.bucket = bucket; + } + + @Override + public void run() { + ObTable table = null; + try { + List payloadBuffers = bucket.getPayloadBufferList(); + int index = 0; + table = statement.getObTablePool().takeWriteObTable(statement.getTimeoutRemain()); + while (index < payloadBuffers.size()) { + ObByteBuf payloadBuffer = payloadBuffers.get(index); + sendInsert(table, payloadBuffer); + ++index; + } + proxy.setSuccess(); + setSuccess(); + } catch (ObDirectLoadException e) { + logger.warn("statement write task run failed", e); + proxy.setFailure(e); + setFailure(e); + } finally { + if (table != null) { + statement.getObTablePool().putWriteObTable(table); + table = null; + } + } + } + + private void sendInsert(ObTable table, ObByteBuf payloadBuffer) throws ObDirectLoadException { + int retryCount = 0; + int retryInterval = 1; + while (true) { + proxy.checkStatus(); + try { + final long timeoutMillis = statement.getTimeoutRemain(); + doSendInsert(table, payloadBuffer, timeoutMillis); + break; + } catch (ObDirectLoadException e) { + logger.warn("statement send insert failed, retry after " + retryInterval + + "s, retryCount:" + retryCount, e); + // 忽略所有发送失败错误码, 重试到任务状态为FAIL + ++retryCount; + try { + Thread.sleep(retryInterval * 1000); + if (retryInterval == 1) { + retryInterval = 2; + } else { + retryInterval = Math.min(retryInterval * retryInterval, 60); // 最大60s + } + } catch (Exception ex) { + throw ObDirectLoadExceptionUtil.convertException(ex); + } + } + } + } + + private ObDirectLoadInsertRpc doSendInsert(ObTable table, ObByteBuf payloadBuffer, + long timeoutMillis) throws ObDirectLoadException { + // send insert rpc + ObDirectLoadInsertRpc rpc = protocol.getInsertRpc(executor.getTraceId()); + rpc.setSvrAddr(executor.getSvrAddr()); + rpc.setTableId(executor.getTableId()); + rpc.setTaskId(executor.getTaskId()); + rpc.setPayloadBuffer(payloadBuffer); + + logger.debug("statement send insert rpc, arg:" + rpc.getArg()); + connection.executeWithConnection(rpc, table, timeoutMillis); + logger.debug("statement insert rpc response successful, res:" + rpc.getRes()); + + return rpc; + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementAsyncPromiseTask.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementAsyncPromiseTask.java new file mode 100644 index 00000000..b035492c --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementAsyncPromiseTask.java @@ -0,0 +1,68 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.future; + +import java.util.concurrent.TimeUnit; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadExceptionUtil; +import com.alipay.oceanbase.rpc.util.NamedThreadFactory; +import com.alipay.remoting.util.NettyEventLoopUtil; + +import io.netty.channel.EventLoopGroup; + +public abstract class ObDirectLoadStatementAsyncPromiseTask extends + ObDirectLoadStatementPromiseTask { + + private static final int backgroundThreadCount = 2; + private static final EventLoopGroup eventLoopGroup = NettyEventLoopUtil + .newEventLoopGroup( + backgroundThreadCount, + new NamedThreadFactory( + "direct-load", true)); + + public ObDirectLoadStatementAsyncPromiseTask(ObDirectLoadStatement statement) { + super(statement); + } + + public void submit() throws ObDirectLoadException { + try { + eventLoopGroup.submit(this); + } catch (Exception e) { + ObDirectLoadException cause = ObDirectLoadExceptionUtil.convertException(e); + setFailure(cause); + throw cause; + } + } + + protected void schedule(long delay, TimeUnit unit) throws ObDirectLoadException { + try { + eventLoopGroup.schedule(this, delay, unit); + } catch (Exception e) { + ObDirectLoadException cause = ObDirectLoadExceptionUtil.convertException(e); + // setFailure(cause); + throw cause; + } + } + + protected void schedule(long delayMillis) throws ObDirectLoadException { + schedule(delayMillis, TimeUnit.MILLISECONDS); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementCompleteFuture.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementCompleteFuture.java new file mode 100644 index 00000000..0af3635c --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementCompleteFuture.java @@ -0,0 +1,64 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.future; + +import java.util.concurrent.TimeUnit; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadRuntimeInfo; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadInterruptedException; + +abstract class ObDirectLoadStatementCompleteFuture implements ObDirectLoadStatementFuture { + + protected final ObDirectLoadStatement statement; + + ObDirectLoadStatementCompleteFuture(ObDirectLoadStatement statement) { + this.statement = statement; + } + + @Override + public ObDirectLoadStatement getStatement() { + return this.statement; + } + + @Override + public boolean isDone() { + return true; + } + + @Override + public void await() throws ObDirectLoadInterruptedException { + return; + } + + @Override + public boolean await(long timeoutMillis) throws ObDirectLoadInterruptedException { + return true; + } + + @Override + public boolean await(long timeout, TimeUnit unit) throws ObDirectLoadInterruptedException { + return true; + } + + @Override + public ObDirectLoadRuntimeInfo getRuntimeInfo() { + return new ObDirectLoadRuntimeInfo(); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementDefaultPromise.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementDefaultPromise.java new file mode 100644 index 00000000..cc61bc3a --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementDefaultPromise.java @@ -0,0 +1,119 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.future; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadLogger; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadRuntimeInfo; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; +import com.alipay.oceanbase.rpc.direct_load.exception.*; + +public class ObDirectLoadStatementDefaultPromise implements ObDirectLoadStatementPromise { + + protected final ObDirectLoadStatement statement; + protected final ObDirectLoadLogger logger; + + private CountDownLatch waiter = new CountDownLatch(1); + + private static int NONE = 0; + private static int SET_RESULT = 1; // 设置结果中 + private static int SUCC = 2; // 成功 + private static int FAIL = 3; // 失败 + private AtomicInteger resultFlag = new AtomicInteger(NONE); + private ObDirectLoadException cause = null; + + public ObDirectLoadStatementDefaultPromise(ObDirectLoadStatement statement) { + this.statement = statement; + this.logger = statement.getLogger(); + } + + @Override + public ObDirectLoadStatement getStatement() { + return this.statement; + } + + @Override + public boolean isDone() { + return (resultFlag.get() > SET_RESULT); + } + + @Override + public boolean isSuccess() { + return (resultFlag.get() == SUCC); + } + + @Override + public ObDirectLoadException cause() { + return this.cause; + } + + @Override + public void await() throws ObDirectLoadInterruptedException { + try { + waiter.await(); + } catch (InterruptedException e) { + throw ObDirectLoadExceptionUtil.convertException(e); + } + } + + @Override + public boolean await(long timeoutMillis) throws ObDirectLoadInterruptedException { + try { + return waiter.await(timeoutMillis, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + throw ObDirectLoadExceptionUtil.convertException(e); + } + } + + @Override + public boolean await(long timeout, TimeUnit unit) throws ObDirectLoadInterruptedException { + try { + return waiter.await(timeout, unit); + } catch (InterruptedException e) { + throw ObDirectLoadExceptionUtil.convertException(e); + } + } + + @Override + public ObDirectLoadStatementPromise setSuccess() { + if (resultFlag.compareAndSet(NONE, SET_RESULT)) { + resultFlag.set(SUCC); + waiter.countDown(); + } + return this; + } + + @Override + public ObDirectLoadStatementPromise setFailure(ObDirectLoadException cause) { + if (resultFlag.compareAndSet(NONE, SET_RESULT)) { + this.cause = cause; + resultFlag.set(FAIL); + waiter.countDown(); + } + return this; + } + + @Override + public ObDirectLoadRuntimeInfo getRuntimeInfo() { + return new ObDirectLoadRuntimeInfo(); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementFailedFuture.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementFailedFuture.java new file mode 100644 index 00000000..58d22b16 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementFailedFuture.java @@ -0,0 +1,43 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.future; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; + +public final class ObDirectLoadStatementFailedFuture extends ObDirectLoadStatementCompleteFuture { + + private final ObDirectLoadException cause; + + public ObDirectLoadStatementFailedFuture(ObDirectLoadStatement statement, + ObDirectLoadException cause) { + super(statement); + this.cause = cause; + } + + @Override + public boolean isSuccess() { + return false; + } + + @Override + public ObDirectLoadException cause() { + return this.cause; + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementFuture.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementFuture.java new file mode 100644 index 00000000..8b10465b --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementFuture.java @@ -0,0 +1,103 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.future; + +import java.util.concurrent.TimeUnit; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadRuntimeInfo; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; +import com.alipay.oceanbase.rpc.direct_load.exception.*; + +public interface ObDirectLoadStatementFuture { + + /** + * 获取关联的stmt对象 + */ + ObDirectLoadStatement getStatement(); + + /** + * 异步任务是否完成, 结果可能是成功、失败、取消 + * + * @return {@code true} 异步任务完成 {@code false} 异步任务未完成 + */ + boolean isDone(); + + /** + * 异步任务是否被取消 + * + * @return {@code true} 异步任务被取消 + */ + // boolean isCancelled(); + + /** + * 异步任务是否成功 + * + * @return {@code true} 异步任务成功 + */ + boolean isSuccess(); + + /** + * 异步任务失败的原因 + */ + ObDirectLoadException cause(); + + /** + * + * 添加监听器.异步任务完成时会通知监听器. + */ + // ObDirectLoadStatementFuture addListener(ObDirectLoadStatementFutureListener listener); + + /** + * 等待异步任务完成 + */ + void await() throws ObDirectLoadInterruptedException; + + /** + * 等待异步任务完成 + * + * @param timeoutMillis 超时时间, 单位:ms + * + * @return {@code true} 异步任务完成 {@code false} 等待超时 + */ + boolean await(long timeoutMillis) throws ObDirectLoadInterruptedException; + + /** + * 等待异步任务完成 + * + * @param timeout 超时时间 + * @param unit 超时时间单位 + * + * @return {@code true} 异步任务完成 {@code false} 等待超时 + */ + boolean await(long timeout, TimeUnit unit) throws ObDirectLoadInterruptedException; + + /** + * 取消异步任务 + * + * @param mayInterruptIfRunning 是否中断执行中的异步任务 + * + * @return {@code true} 取消成功 {@code false} 取消失败 + */ + // boolean cancel(boolean mayInterruptIfRunning); + + /** + * 获取运行时信息 + */ + ObDirectLoadRuntimeInfo getRuntimeInfo(); + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementPromise.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementPromise.java new file mode 100644 index 00000000..f6a25543 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementPromise.java @@ -0,0 +1,34 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.future; + +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; + +public interface ObDirectLoadStatementPromise extends ObDirectLoadStatementFuture { + + /** + * 标记异步操作结果为成功 + */ + ObDirectLoadStatementPromise setSuccess(); + + /** + * 标记异步操作结果为失败 + */ + ObDirectLoadStatementPromise setFailure(ObDirectLoadException cause); + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementPromiseTask.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementPromiseTask.java new file mode 100644 index 00000000..fe3dc09a --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementPromiseTask.java @@ -0,0 +1,30 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.future; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; + +public abstract class ObDirectLoadStatementPromiseTask extends ObDirectLoadStatementDefaultPromise + implements + Runnable { + + public ObDirectLoadStatementPromiseTask(ObDirectLoadStatement statement) { + super(statement); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementSucceedFuture.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementSucceedFuture.java new file mode 100644 index 00000000..a657a3c9 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/future/ObDirectLoadStatementSucceedFuture.java @@ -0,0 +1,39 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.future; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; + +public final class ObDirectLoadStatementSucceedFuture extends ObDirectLoadStatementCompleteFuture { + + public ObDirectLoadStatementSucceedFuture(ObDirectLoadStatement statement) { + super(statement); + } + + @Override + public boolean isSuccess() { + return true; + } + + @Override + public ObDirectLoadException cause() { + return null; + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocol.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocol.java new file mode 100644 index 00000000..dd01b770 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocol.java @@ -0,0 +1,43 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadTraceId; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.*; +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; + +public interface ObDirectLoadProtocol { + + void init() throws ObDirectLoadException; + + int getProtocolVersion(); + + // rpc + ObDirectLoadBeginRpc getBeginRpc(ObDirectLoadTraceId traceId); + + ObDirectLoadCommitRpc getCommitRpc(ObDirectLoadTraceId traceId); + + ObDirectLoadAbortRpc getAbortRpc(ObDirectLoadTraceId traceId); + + ObDirectLoadGetStatusRpc getGetStatusRpc(ObDirectLoadTraceId traceId); + + ObDirectLoadInsertRpc getInsertRpc(ObDirectLoadTraceId traceId); + + ObDirectLoadHeartBeatRpc getHeartBeatRpc(ObDirectLoadTraceId traceId); + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocolFactory.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocolFactory.java new file mode 100644 index 00000000..e5032132 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocolFactory.java @@ -0,0 +1,83 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol; + +import com.alipay.oceanbase.rpc.ObGlobal; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadLogger; +import com.alipay.oceanbase.rpc.direct_load.exception.*; +import com.alipay.oceanbase.rpc.direct_load.protocol.v0.ObDirectLoadProtocolV0; + +public class ObDirectLoadProtocolFactory { + + private static final ObDirectLoadLogger logger = ObDirectLoadLogger.getLogger(); + + // 起始版本 + // 4_2_1_release + public static final long OB_VERSION_4_2_1_0 = ObGlobal.calcVersion(4, (short) 2, + (byte) 1, (byte) 0); + // 4_2_x_release + public static final long OB_VERSION_4_2_2_0 = ObGlobal.calcVersion(4, (short) 2, + (byte) 2, (byte) 0); + // master + public static final long OB_VERSION_4_3_0_0 = ObGlobal.calcVersion(4, (short) 3, + (byte) 0, (byte) 0); + + // 最低支持版本 + // 4_2_1_release + public static final long OB_VERSION_4_2_1_7 = ObGlobal.calcVersion(4, (short) 2, + (byte) 1, (byte) 7); + // 4_2_x_release + public static final long OB_VERSION_4_2_4_0 = ObGlobal.calcVersion(4, (short) 2, + (byte) 4, (byte) 0); + // master + public static final long OB_VERSION_4_3_0_1 = ObGlobal.calcVersion(4, (short) 3, + (byte) 0, (byte) 1); + + public static long getSupportedMinimumObVersion(long obVersion) { + long minimumObVersion = 0; + if (obVersion < OB_VERSION_4_2_1_0) { // < 421 + minimumObVersion = OB_VERSION_4_2_1_7; + } else if (obVersion < OB_VERSION_4_2_2_0) { // 421 + minimumObVersion = OB_VERSION_4_2_1_7; + } else if (obVersion < OB_VERSION_4_3_0_0) { // 42x + minimumObVersion = OB_VERSION_4_2_4_0; + } else { // master + minimumObVersion = OB_VERSION_4_3_0_1; + } + return minimumObVersion; + } + + public static boolean checkIsSupported(long obVersion) { + final long minimumObVersion = getSupportedMinimumObVersion(obVersion); + return (obVersion >= minimumObVersion); + } + + public static ObDirectLoadProtocol getProtocol(long obVersion) throws ObDirectLoadException { + final long minimumObVersion = getSupportedMinimumObVersion(obVersion); + if (obVersion < minimumObVersion) { + logger.warn("direct load in ob version " + ObGlobal.getObVsnString(obVersion) + + "is not supported, minimum version required is " + + ObGlobal.getObVsnString(minimumObVersion)); + throw new ObDirectLoadNotSupportedException( + "direct load in ob version " + ObGlobal.getObVsnString(obVersion) + + " is not supported, minimum version required is " + + ObGlobal.getObVsnString(minimumObVersion)); + } + return new ObDirectLoadProtocolV0(); + } +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadRpc.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadRpc.java new file mode 100644 index 00000000..404d41b2 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadRpc.java @@ -0,0 +1,39 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol; + +import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; +import com.alipay.oceanbase.rpc.protocol.payload.ObPayload; +import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; +import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadOperationType; + +public interface ObDirectLoadRpc { + + ObTableDirectLoadOperationType getOpType(); + + ObSimplePayload getArg(); + + ObPayload getRequest(); + + void setResult(ObPayload result) throws ObDirectLoadException; + + ObSimplePayload getRes(); + + void setRpcTimeout(long timeoutMillis); + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadAbortRpc.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadAbortRpc.java new file mode 100644 index 00000000..734f351b --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadAbortRpc.java @@ -0,0 +1,32 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.payload; + +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadRpc; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; + +public interface ObDirectLoadAbortRpc extends ObDirectLoadRpc { + + // arg + void setSvrAddr(ObAddr addr); + + void setTableId(long tableId); + + void setTaskId(long taskId); + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadBeginRpc.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadBeginRpc.java new file mode 100644 index 00000000..b895a513 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadBeginRpc.java @@ -0,0 +1,56 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.payload; + +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadRpc; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObLoadDupActionType; + +public interface ObDirectLoadBeginRpc extends ObDirectLoadRpc { + + // arg + void setTableName(String tableName); + + void setParallel(long parallel); + + void setMaxErrorRowCount(long maxErrorRowCount); + + void setDupAction(ObLoadDupActionType dupAction); + + void setTimeout(long timeout); + + void setHeartBeatTimeout(long heartBeatTimeout); + + void setLoadMethod(String loadMethod); + + void setColumnNames(String[] columnNames); + + void setPartitionNames(String[] partitionNames); + + // res + ObAddr getSvrAddr(); + + long getTableId(); + + long getTaskId(); + + ObTableLoadClientStatus getStatus(); + + int getErrorCode(); + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadCommitRpc.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadCommitRpc.java new file mode 100644 index 00000000..ee213a8f --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadCommitRpc.java @@ -0,0 +1,32 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.payload; + +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadRpc; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; + +public interface ObDirectLoadCommitRpc extends ObDirectLoadRpc { + + // arg + void setSvrAddr(ObAddr addr); + + void setTableId(long tableId); + + void setTaskId(long taskId); + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadGetStatusRpc.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadGetStatusRpc.java new file mode 100644 index 00000000..b48118eb --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadGetStatusRpc.java @@ -0,0 +1,36 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.payload; + +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadRpc; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; + +public interface ObDirectLoadGetStatusRpc extends ObDirectLoadRpc { + + // arg + void setSvrAddr(ObAddr addr); + + void setTableId(long tableId); + + void setTaskId(long taskId); + + // res + ObTableLoadClientStatus getStatus(); + + int getErrorCode(); +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadHeartBeatRpc.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadHeartBeatRpc.java new file mode 100644 index 00000000..9ee966c4 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadHeartBeatRpc.java @@ -0,0 +1,37 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.payload; + +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadRpc; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; + +public interface ObDirectLoadHeartBeatRpc extends ObDirectLoadRpc { + + // arg + void setSvrAddr(ObAddr addr); + + void setTableId(long tableId); + + void setTaskId(long taskId); + + // res + ObTableLoadClientStatus getStatus(); + + int getErrorCode(); + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadInsertRpc.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadInsertRpc.java new file mode 100644 index 00000000..1953a8af --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObDirectLoadInsertRpc.java @@ -0,0 +1,38 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.payload; + +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadRpc; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; +import com.alipay.oceanbase.rpc.util.ObByteBuf; +import com.alipay.oceanbase.rpc.util.ObBytesString; + +public interface ObDirectLoadInsertRpc extends ObDirectLoadRpc { + + // arg + void setSvrAddr(ObAddr addr); + + void setTableId(long tableId); + + void setTaskId(long taskId); + + void setPayload(ObBytesString payload); + + void setPayloadBuffer(ObByteBuf payloadBuffer); + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableLoadClientStatus.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObTableLoadClientStatus.java similarity index 83% rename from src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableLoadClientStatus.java rename to src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObTableLoadClientStatus.java index 35f6cdd0..7852ab8b 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableLoadClientStatus.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/payload/ObTableLoadClientStatus.java @@ -15,14 +15,15 @@ * #L% */ -package com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load; +package com.alipay.oceanbase.rpc.direct_load.protocol.payload; import java.util.HashMap; import java.util.Map; public enum ObTableLoadClientStatus { - RUNNING(0), COMMITTING(1), COMMIT(2), ERROR(3), ABORT(4), MAX_STATUS(5); + RUNNING(0), COMMITTING(1), COMMIT(2), ERROR(3), ABORT(4), INITIALIZING(5), WAITTING(6), MAX_STATUS( + 7); private final int value; private static final Map map = new HashMap(); diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/ObDirectLoadProtocolV0.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/ObDirectLoadProtocolV0.java new file mode 100644 index 00000000..a8842fb3 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/ObDirectLoadProtocolV0.java @@ -0,0 +1,72 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.v0; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadTraceId; +import com.alipay.oceanbase.rpc.direct_load.exception.*; +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadProtocol; +import com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.*; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.*; + +public class ObDirectLoadProtocolV0 implements ObDirectLoadProtocol { + + private static final int PROTOCOL_VERSION = 0; + + public ObDirectLoadProtocolV0() { + } + + @Override + public void init() throws ObDirectLoadException { + } + + @Override + public int getProtocolVersion() { + return PROTOCOL_VERSION; + } + + @Override + public ObDirectLoadBeginRpc getBeginRpc(ObDirectLoadTraceId traceId) { + return new ObDirectLoadBeginRpcV0(traceId); + } + + @Override + public ObDirectLoadCommitRpc getCommitRpc(ObDirectLoadTraceId traceId) { + return new ObDirectLoadCommitRpcV0(traceId); + } + + @Override + public ObDirectLoadAbortRpc getAbortRpc(ObDirectLoadTraceId traceId) { + return new ObDirectLoadAbortRpcV0(traceId); + } + + @Override + public ObDirectLoadGetStatusRpc getGetStatusRpc(ObDirectLoadTraceId traceId) { + return new ObDirectLoadGetStatusRpcV0(traceId); + } + + @Override + public ObDirectLoadInsertRpc getInsertRpc(ObDirectLoadTraceId traceId) { + return new ObDirectLoadInsertRpcV0(traceId); + } + + @Override + public ObDirectLoadHeartBeatRpc getHeartBeatRpc(ObDirectLoadTraceId traceId) { + return new ObDirectLoadHeartBeatRpcV0(traceId); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadAbortRpcV0.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadAbortRpcV0.java new file mode 100644 index 00000000..992ecbbe --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadAbortRpcV0.java @@ -0,0 +1,68 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadTraceId; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadAbortRpc; +import com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl.ObTableDirectLoadAbortArg; +import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; +import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadOperationType; + +public class ObDirectLoadAbortRpcV0 extends ObDirectLoadDefaultRpcV0 implements + ObDirectLoadAbortRpc { + + public static final ObTableDirectLoadOperationType OP_TYPE = ObTableDirectLoadOperationType.ABORT; + + private ObTableDirectLoadAbortArg arg = new ObTableDirectLoadAbortArg(); + + public ObDirectLoadAbortRpcV0(ObDirectLoadTraceId traceId) { + super(traceId); + } + + @Override + public ObTableDirectLoadOperationType getOpType() { + return OP_TYPE; + } + + @Override + public ObSimplePayload getArg() { + return arg; + } + + @Override + public ObSimplePayload getRes() { + return null; + } + + @Override + public void setSvrAddr(ObAddr addr) { + request.getHeader().setAddr(addr); + } + + @Override + public void setTableId(long tableId) { + arg.setTableId(tableId); + } + + @Override + public void setTaskId(long taskId) { + arg.setTaskId(taskId); + } + +} \ No newline at end of file diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadBeginRpcV0.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadBeginRpcV0.java new file mode 100644 index 00000000..bfdfe9a7 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadBeginRpcV0.java @@ -0,0 +1,134 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadTraceId; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadBeginRpc; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObTableLoadClientStatus; +import com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl.ObTableDirectLoadBeginArg; +import com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl.ObTableDirectLoadBeginRes; +import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObLoadDupActionType; +import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadOperationType; + +public class ObDirectLoadBeginRpcV0 extends ObDirectLoadDefaultRpcV0 implements + ObDirectLoadBeginRpc { + + public static final ObTableDirectLoadOperationType OP_TYPE = ObTableDirectLoadOperationType.BEGIN; + + private ObTableDirectLoadBeginArg arg = new ObTableDirectLoadBeginArg(); + private ObTableDirectLoadBeginRes res = new ObTableDirectLoadBeginRes(); + + public ObDirectLoadBeginRpcV0(ObDirectLoadTraceId traceId) { + super(traceId); + // set default value + arg.setForceCreate(true); + arg.setAsyncBegin(true); + } + + @Override + public ObTableDirectLoadOperationType getOpType() { + return OP_TYPE; + } + + @Override + public ObSimplePayload getArg() { + return arg; + } + + @Override + public ObSimplePayload getRes() { + return res; + } + + // arg + + @Override + public void setTableName(String tableName) { + arg.setTableName(tableName); + } + + @Override + public void setParallel(long parallel) { + arg.setParallel(parallel); + } + + @Override + public void setMaxErrorRowCount(long maxErrorRowCount) { + arg.setMaxErrorRowCount(maxErrorRowCount); + } + + @Override + public void setDupAction(ObLoadDupActionType dupAction) { + arg.setDupAction(dupAction); + } + + @Override + public void setTimeout(long timeout) { + arg.setTimeout(timeout); + } + + @Override + public void setHeartBeatTimeout(long heartBeatTimeout) { + arg.setHeartBeatTimeout(heartBeatTimeout); + } + + @Override + public void setLoadMethod(String loadMethod) { + arg.setLoadMethod(loadMethod); + } + + @Override + public void setColumnNames(String[] columnNames) { + arg.setColumnNames(columnNames); + } + + @Override + public void setPartitionNames(String[] partitionNames) { + arg.setPartitionNames(partitionNames); + } + + // res + + @Override + public ObAddr getSvrAddr() { + return this.result.getHeader().getAddr(); + } + + @Override + public long getTableId() { + return res.getTableId(); + } + + @Override + public long getTaskId() { + return res.getTaskId(); + } + + @Override + public ObTableLoadClientStatus getStatus() { + return res.getStatus(); + } + + @Override + public int getErrorCode() { + return res.getErrorCode(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadCommitRpcV0.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadCommitRpcV0.java new file mode 100644 index 00000000..a1196df6 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadCommitRpcV0.java @@ -0,0 +1,68 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadTraceId; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadCommitRpc; +import com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl.ObTableDirectLoadCommitArg; +import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; +import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadOperationType; + +public class ObDirectLoadCommitRpcV0 extends ObDirectLoadDefaultRpcV0 implements + ObDirectLoadCommitRpc { + + public static final ObTableDirectLoadOperationType OP_TYPE = ObTableDirectLoadOperationType.COMMIT; + + private ObTableDirectLoadCommitArg arg = new ObTableDirectLoadCommitArg(); + + public ObDirectLoadCommitRpcV0(ObDirectLoadTraceId traceId) { + super(traceId); + } + + @Override + public ObTableDirectLoadOperationType getOpType() { + return OP_TYPE; + } + + @Override + public ObSimplePayload getArg() { + return arg; + } + + @Override + public ObSimplePayload getRes() { + return null; + } + + @Override + public void setSvrAddr(ObAddr addr) { + request.getHeader().setAddr(addr); + } + + @Override + public void setTableId(long tableId) { + arg.setTableId(tableId); + } + + @Override + public void setTaskId(long taskId) { + arg.setTaskId(taskId); + } + +} \ No newline at end of file diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadDefaultRpcV0.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadDefaultRpcV0.java new file mode 100644 index 00000000..0d8606fc --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadDefaultRpcV0.java @@ -0,0 +1,99 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadLogger; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadTraceId; +import com.alipay.oceanbase.rpc.direct_load.exception.*; +import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadRpc; +import com.alipay.oceanbase.rpc.protocol.payload.ObPayload; +import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; +import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadRequest; +import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadResult; +import com.alipay.oceanbase.rpc.util.ObBytesString; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; + +public abstract class ObDirectLoadDefaultRpcV0 implements ObDirectLoadRpc { + + protected final ObDirectLoadLogger logger; + + protected final ObTableDirectLoadRequest request; + protected ObTableDirectLoadResult result; + + public ObDirectLoadDefaultRpcV0(ObDirectLoadTraceId traceId) { + logger = ObDirectLoadLogger.getLogger(traceId); + request = new ObTableDirectLoadRequest(); + request.setTraceId(traceId.getUniqueId(), traceId.getSequence()); + } + + @Override + public ObPayload getRequest() { + ObTableDirectLoadRequest.Header header = request.getHeader(); + header.setOperationType(getOpType()); + request.setArgContent(new ObBytesString(getArg().encode())); + return request; + } + + @Override + public void setResult(ObPayload result) throws ObDirectLoadException { + if (result instanceof ObTableDirectLoadResult) { + this.result = (ObTableDirectLoadResult) result; + } else { + throw new ObDirectLoadUnexpectedException("unexpected result type, result:" + result); + } + + ObTableDirectLoadResult.Header header = this.result.getHeader(); + ObBytesString resContent = this.result.getResContent(); + if (header.getOperationType() != getOpType()) { + logger.warn("operation type in result header is error, type:" + + header.getOperationType()); + throw new ObDirectLoadUnexpectedException( + "operation type in result header is error, type:" + header.getOperationType()); + } + + ObSimplePayload res = getRes(); + if (res == null) { + if (resContent.length() != 0) { + logger.warn("res content must be empty"); + throw new ObDirectLoadUnexpectedException("res content must be empty"); + } + } else { + if (resContent.length() == 0) { + logger.warn("res content cannot be empty"); + throw new ObDirectLoadUnexpectedException("res content cannot be empty"); + } + + ByteBuf buf = ByteBufAllocator.DEFAULT.buffer(this.result.getResContent().length()); + try { + buf.writeBytes(resContent.bytes); + res.decode(buf); + } catch (Exception e) { + throw ObDirectLoadExceptionUtil.convertException(e); + } finally { + buf.release(); + } + } + } + + @Override + public void setRpcTimeout(long timeoutMillis) { + request.setTimeout(timeoutMillis * 1000); + } +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadGetStatusRpcV0.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadGetStatusRpcV0.java new file mode 100644 index 00000000..1cd56414 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadGetStatusRpcV0.java @@ -0,0 +1,81 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadTraceId; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadGetStatusRpc; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObTableLoadClientStatus; +import com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl.ObTableDirectLoadGetStatusArg; +import com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl.ObTableDirectLoadGetStatusRes; +import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; +import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadOperationType; + +public class ObDirectLoadGetStatusRpcV0 extends ObDirectLoadDefaultRpcV0 implements + ObDirectLoadGetStatusRpc { + + public static final ObTableDirectLoadOperationType OP_TYPE = ObTableDirectLoadOperationType.GET_STATUS; + + private ObTableDirectLoadGetStatusArg arg = new ObTableDirectLoadGetStatusArg(); + private ObTableDirectLoadGetStatusRes res = new ObTableDirectLoadGetStatusRes(); + + public ObDirectLoadGetStatusRpcV0(ObDirectLoadTraceId traceId) { + super(traceId); + } + + @Override + public ObTableDirectLoadOperationType getOpType() { + return OP_TYPE; + } + + @Override + public ObSimplePayload getArg() { + return arg; + } + + @Override + public ObSimplePayload getRes() { + return res; + } + + @Override + public void setSvrAddr(ObAddr addr) { + request.getHeader().setAddr(addr); + } + + @Override + public void setTableId(long tableId) { + arg.setTableId(tableId); + } + + @Override + public void setTaskId(long taskId) { + arg.setTaskId(taskId); + } + + @Override + public ObTableLoadClientStatus getStatus() { + return res.getStatus(); + } + + @Override + public int getErrorCode() { + return res.getErrorCode(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadHeartBeatRpcV0.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadHeartBeatRpcV0.java new file mode 100644 index 00000000..4ff146bf --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadHeartBeatRpcV0.java @@ -0,0 +1,82 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadTraceId; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadHeartBeatRpc; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObTableLoadClientStatus; +import com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl.ObTableDirectLoadHeartBeatArg; +import com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl.ObTableDirectLoadHeartBeatRes; +import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; +import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadOperationType; + +public class ObDirectLoadHeartBeatRpcV0 extends ObDirectLoadDefaultRpcV0 implements + ObDirectLoadHeartBeatRpc { + + public static final ObTableDirectLoadOperationType OP_TYPE = ObTableDirectLoadOperationType.HEART_BEAT; + + private ObTableDirectLoadHeartBeatArg arg = new ObTableDirectLoadHeartBeatArg(); + private ObTableDirectLoadHeartBeatRes res = new ObTableDirectLoadHeartBeatRes(); + + public ObDirectLoadHeartBeatRpcV0(ObDirectLoadTraceId traceId) { + super(traceId); + request.setGroupId(22/*OBCG_DIRECT_LOAD_HIGH_PRIO*/); + } + + @Override + public ObTableDirectLoadOperationType getOpType() { + return OP_TYPE; + } + + @Override + public ObSimplePayload getArg() { + return arg; + } + + @Override + public ObSimplePayload getRes() { + return res; + } + + @Override + public void setSvrAddr(ObAddr addr) { + request.getHeader().setAddr(addr); + } + + @Override + public void setTableId(long tableId) { + arg.setTableId(tableId); + } + + @Override + public void setTaskId(long taskId) { + arg.setTaskId(taskId); + } + + @Override + public ObTableLoadClientStatus getStatus() { + return res.getStatus(); + } + + @Override + public int getErrorCode() { + return res.getErrorCode(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadInsertRpcV0.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadInsertRpcV0.java new file mode 100644 index 00000000..c5e36eff --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/ObDirectLoadInsertRpcV0.java @@ -0,0 +1,80 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadTraceId; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObDirectLoadInsertRpc; +import com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl.ObTableDirectLoadInsertArg; +import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; +import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadOperationType; +import com.alipay.oceanbase.rpc.util.ObByteBuf; +import com.alipay.oceanbase.rpc.util.ObBytesString; + +public class ObDirectLoadInsertRpcV0 extends ObDirectLoadDefaultRpcV0 implements + ObDirectLoadInsertRpc { + + public static final ObTableDirectLoadOperationType OP_TYPE = ObTableDirectLoadOperationType.INSERT; + + private ObTableDirectLoadInsertArg arg = new ObTableDirectLoadInsertArg(); + + public ObDirectLoadInsertRpcV0(ObDirectLoadTraceId traceId) { + super(traceId); + } + + @Override + public ObTableDirectLoadOperationType getOpType() { + return OP_TYPE; + } + + @Override + public ObSimplePayload getArg() { + return arg; + } + + @Override + public ObSimplePayload getRes() { + return null; + } + + @Override + public void setSvrAddr(ObAddr addr) { + request.getHeader().setAddr(addr); + } + + @Override + public void setTableId(long tableId) { + arg.setTableId(tableId); + } + + @Override + public void setTaskId(long taskId) { + arg.setTaskId(taskId); + } + + @Override + public void setPayload(ObBytesString payload) { + arg.setPayload(payload); + } + + @Override + public void setPayloadBuffer(ObByteBuf payloadBuffer) { + arg.setPayloadBuffer(payloadBuffer); + } + +} \ No newline at end of file diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadAbortArg.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadAbortArg.java similarity index 92% rename from src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadAbortArg.java rename to src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadAbortArg.java index 26ccd0a8..4378768a 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadAbortArg.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadAbortArg.java @@ -15,7 +15,7 @@ * #L% */ -package com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load; +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl; import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; import com.alipay.oceanbase.rpc.util.ObByteBuf; @@ -51,6 +51,10 @@ public void setTaskId(long taskId) { this.taskId = taskId; } + public String toString() { + return String.format("{tableId:%d, taskId:%d}", tableId, taskId); + } + /** * Encode. */ diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadBeginArg.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadBeginArg.java similarity index 64% rename from src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadBeginArg.java rename to src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadBeginArg.java index 945f253e..48d23cbd 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadBeginArg.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadBeginArg.java @@ -15,9 +15,12 @@ * #L% */ -package com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load; +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl; + +import java.util.Arrays; import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; +import com.alipay.oceanbase.rpc.protocol.payload.impl.ObLoadDupActionType; import com.alipay.oceanbase.rpc.util.ObByteBuf; import com.alipay.oceanbase.rpc.util.Serialization; @@ -30,7 +33,12 @@ // dup_action_, // timeout_, // heartbeat_timeout_, -// force_create_); +// force_create_, +// async_begin_, +// load_method_, +// column_names_, +// partition_names_ +// ); public class ObTableDirectLoadBeginArg implements ObSimplePayload { @@ -41,6 +49,10 @@ public class ObTableDirectLoadBeginArg implements ObSimplePayload { private long timeout = 0; private long heartBeatTimeout = 0; private boolean forceCreate = false; + private boolean asyncBegin = false; + private String loadMethod = new String(); + private String[] columnNames = new String[0]; + private String[] partitionNames = new String[0]; public ObTableDirectLoadBeginArg() { } @@ -101,6 +113,47 @@ public void setForceCreate(boolean forceCreate) { this.forceCreate = forceCreate; } + public boolean getAsyncBegin() { + return asyncBegin; + } + + public void setAsyncBegin(boolean asyncBegin) { + this.asyncBegin = asyncBegin; + } + + public String getLoadMethod() { + return loadMethod; + } + + public void setLoadMethod(String loadMethod) { + this.loadMethod = loadMethod; + } + + public String[] getColumnNames() { + return columnNames; + } + + public void setColumnNames(String[] columnNames) { + this.columnNames = columnNames; + } + + public String[] getPartitionNames() { + return partitionNames; + } + + public void setPartitionNames(String[] partitionNames) { + this.partitionNames = partitionNames; + } + + public String toString() { + return String + .format( + "{tableName:%s, parallel:%d, maxErrorRowCount:%d, dupAction:%s, timeout:%d, heartBeatTimeout:%d, forceCreate:%s, asyncBegin:%s, loadMethod:%s, columnNames:%s, partitionNames:%s}", + tableName, parallel, maxErrorRowCount, dupAction, timeout, heartBeatTimeout, + forceCreate, asyncBegin, loadMethod, Arrays.toString(columnNames), + Arrays.toString(partitionNames)); + } + /** * Encode. */ @@ -124,6 +177,10 @@ public void encode(ObByteBuf buf) { Serialization.encodeVi64(buf, timeout); Serialization.encodeVi64(buf, heartBeatTimeout); Serialization.encodeI8(buf, (byte) (forceCreate ? 1 : 0)); + Serialization.encodeI8(buf, (byte) (asyncBegin ? 1 : 0)); + Serialization.encodeVString(buf, loadMethod); + Serialization.encodeVStringArray(buf, columnNames); + Serialization.encodeVStringArray(buf, partitionNames); } /** @@ -138,6 +195,10 @@ public ObTableDirectLoadBeginArg decode(ByteBuf buf) { timeout = Serialization.decodeVi64(buf); heartBeatTimeout = Serialization.decodeVi64(buf); forceCreate = (Serialization.decodeI8(buf) != 0); + asyncBegin = (Serialization.decodeI8(buf) != 0); + loadMethod = Serialization.decodeVString(buf); + columnNames = Serialization.decodeVStringArray(buf); + partitionNames = Serialization.decodeVStringArray(buf); return this; } @@ -154,6 +215,10 @@ public int getEncodedSize() { len += Serialization.getNeedBytes(timeout); len += Serialization.getNeedBytes(heartBeatTimeout); len += 1; /*forceCreate*/ + len += 1; /*asyncBegin*/ + len += Serialization.getNeedBytes(loadMethod); + len += Serialization.getNeedBytes(columnNames); + len += Serialization.getNeedBytes(partitionNames); return len; } diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadBeginRes.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadBeginRes.java similarity index 84% rename from src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadBeginRes.java rename to src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadBeginRes.java index a4da51c2..afbc1255 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadBeginRes.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadBeginRes.java @@ -15,8 +15,11 @@ * #L% */ -package com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load; +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl; +import java.util.Arrays; + +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObTableLoadClientStatus; import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes; import com.alipay.oceanbase.rpc.util.ObByteBuf; @@ -85,6 +88,11 @@ public void setErrorCode(int errorCode) { this.errorCode = errorCode; } + public String toString() { + return String.format("{tableId:%d, taskId:%d, columnNames:%s, status:%s, errorCode:%d}", + tableId, taskId, Arrays.toString(columnNames), status, errorCode); + } + /** * Encode. */ @@ -103,10 +111,7 @@ public byte[] encode() { public void encode(ObByteBuf buf) { Serialization.encodeVi64(buf, tableId); Serialization.encodeVi64(buf, taskId); - Serialization.encodeVi32(buf, columnNames.length); - for (int i = 0; i < columnNames.length; ++i) { - Serialization.encodeVString(columnNames[i]); - } + Serialization.encodeVStringArray(buf, columnNames); Serialization.encodeI8(buf, status.getByteValue()); Serialization.encodeVi32(buf, errorCode); } @@ -118,11 +123,7 @@ public void encode(ObByteBuf buf) { public ObTableDirectLoadBeginRes decode(ByteBuf buf) { tableId = Serialization.decodeVi64(buf); taskId = Serialization.decodeVi64(buf); - int columnNameCount = Serialization.decodeVi32(buf); - columnNames = new String[columnNameCount]; - for (int i = 0; i < columnNameCount; ++i) { - columnNames[i] = Serialization.decodeVString(buf); - } + columnNames = Serialization.decodeVStringArray(buf); status = ObTableLoadClientStatus.valueOf(Serialization.decodeI8(buf)); errorCode = Serialization.decodeVi32(buf); return this; @@ -136,10 +137,7 @@ public int getEncodedSize() { int len = 0; len += Serialization.getNeedBytes(tableId); len += Serialization.getNeedBytes(taskId); - len += Serialization.getNeedBytes(columnNames.length); - for (int i = 0; i < columnNames.length; ++i) { - len += Serialization.getNeedBytes(columnNames[i]); - } + len += Serialization.getNeedBytes(columnNames); len += 1; /*status*/ len += Serialization.getNeedBytes(errorCode); return len; diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadCommitArg.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadCommitArg.java similarity index 92% rename from src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadCommitArg.java rename to src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadCommitArg.java index 2a17c017..1158eb4a 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadCommitArg.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadCommitArg.java @@ -15,7 +15,7 @@ * #L% */ -package com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load; +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl; import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; import com.alipay.oceanbase.rpc.util.ObByteBuf; @@ -51,6 +51,10 @@ public void setTaskId(long taskId) { this.taskId = taskId; } + public String toString() { + return String.format("{tableId:%d, taskId:%d}", tableId, taskId); + } + /** * Encode. */ diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadGetStatusArg.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadGetStatusArg.java similarity index 92% rename from src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadGetStatusArg.java rename to src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadGetStatusArg.java index 0f4f614b..c99dabdf 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadGetStatusArg.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadGetStatusArg.java @@ -15,7 +15,7 @@ * #L% */ -package com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load; +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl; import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; import com.alipay.oceanbase.rpc.util.ObByteBuf; @@ -51,6 +51,10 @@ public void setTaskId(long taskId) { this.taskId = taskId; } + public String toString() { + return String.format("{tableId:%d, taskId:%d}", tableId, taskId); + } + /** * Encode. */ diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadGetStatusRes.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadGetStatusRes.java similarity index 90% rename from src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadGetStatusRes.java rename to src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadGetStatusRes.java index 8c804e73..d60d510c 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadGetStatusRes.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadGetStatusRes.java @@ -15,8 +15,9 @@ * #L% */ -package com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load; +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObTableLoadClientStatus; import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes; import com.alipay.oceanbase.rpc.util.ObByteBuf; @@ -52,6 +53,10 @@ public void setErrorCode(int errorCode) { this.errorCode = errorCode; } + public String toString() { + return String.format("{status:%s, errorCode:%d}", status, errorCode); + } + /** * Encode. */ diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadHeartBeatArg.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadHeartBeatArg.java similarity index 92% rename from src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadHeartBeatArg.java rename to src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadHeartBeatArg.java index 01d48b78..a7b09ea5 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadHeartBeatArg.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadHeartBeatArg.java @@ -15,7 +15,7 @@ * #L% */ -package com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load; +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl; import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; import com.alipay.oceanbase.rpc.util.ObByteBuf; @@ -51,6 +51,10 @@ public void setTaskId(long taskId) { this.taskId = taskId; } + public String toString() { + return String.format("{tableId:%d, taskId:%d}", tableId, taskId); + } + /** * Encode. */ diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadHeartBeatRes.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadHeartBeatRes.java similarity index 90% rename from src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadHeartBeatRes.java rename to src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadHeartBeatRes.java index 11f7cd40..b15080a7 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadHeartBeatRes.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadHeartBeatRes.java @@ -15,8 +15,9 @@ * #L% */ -package com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load; +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObTableLoadClientStatus; import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes; import com.alipay.oceanbase.rpc.util.ObByteBuf; @@ -52,6 +53,10 @@ public void setErrorCode(int errorCode) { this.errorCode = errorCode; } + public String toString() { + return String.format("{status:%s, errorCode:%d}", status, errorCode); + } + /** * Encode. */ diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadInsertArg.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadInsertArg.java similarity index 64% rename from src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadInsertArg.java rename to src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadInsertArg.java index 453a1719..9c66db7a 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadInsertArg.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/payload/impl/ObTableDirectLoadInsertArg.java @@ -15,7 +15,7 @@ * #L% */ -package com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load; +package com.alipay.oceanbase.rpc.direct_load.protocol.v0.payload.impl; import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; import com.alipay.oceanbase.rpc.util.ObByteBuf; @@ -31,9 +31,13 @@ public class ObTableDirectLoadInsertArg implements ObSimplePayload { - private long tableId = 0; - private long taskId = 0; - private ObBytesString payload = new ObBytesString(); + private final static ObBytesString emptyPayload = new ObBytesString(); + private final static ObByteBuf emptyPayloadBuffer = new ObByteBuf(0); + + private long tableId = 0; + private long taskId = 0; + private ObBytesString payload = emptyPayload; + private ObByteBuf payloadBuffer = emptyPayloadBuffer; public ObTableDirectLoadInsertArg() { } @@ -65,6 +69,19 @@ public void setPayload(ObBytesString payload) { this.payload = payload; } + public String toString() { + return String.format("{tableId:%d, taskId:%d, payload:%d, payloadBuffer:%d}", tableId, + taskId, payload.length(), payloadBuffer.readableBytes()); + } + + public ObByteBuf getPayloadBuffer() { + return payloadBuffer; + } + + public void setPayloadBuffer(ObByteBuf payloadBuffer) { + this.payloadBuffer = payloadBuffer; + } + /** * Encode. */ @@ -83,7 +100,11 @@ public byte[] encode() { public void encode(ObByteBuf buf) { Serialization.encodeVi64(buf, tableId); Serialization.encodeVi64(buf, taskId); - Serialization.encodeBytesString(buf, payload); + if (payloadBuffer != emptyPayloadBuffer) { + buf.writeBytes(payloadBuffer.bytes, 0, payloadBuffer.readableBytes()); + } else { + Serialization.encodeBytesString(buf, payload); + } } /** @@ -102,8 +123,10 @@ public ObTableDirectLoadInsertArg decode(ByteBuf buf) { */ @Override public int getEncodedSize() { - return Serialization.getNeedBytes(tableId) + Serialization.getNeedBytes(taskId) - + Serialization.getNeedBytes(payload); + return Serialization.getNeedBytes(tableId) + + Serialization.getNeedBytes(taskId) + + (payloadBuffer != emptyPayloadBuffer ? payloadBuffer.readableBytes() + : Serialization.getNeedBytes(payload)); } } diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/util/ObDirectLoadIntervalUtil.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/util/ObDirectLoadIntervalUtil.java new file mode 100644 index 00000000..e58214bc --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/util/ObDirectLoadIntervalUtil.java @@ -0,0 +1,40 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.util; + +import java.util.concurrent.atomic.AtomicLong; + +public class ObDirectLoadIntervalUtil { + + private AtomicLong lastTime = new AtomicLong(0); + private AtomicLong count = new AtomicLong(0); + + public boolean reachTimeInterval(long timeMillis) { + long curTime = System.currentTimeMillis(); + long oldTime = lastTime.get(); + if (timeMillis + oldTime <= curTime && lastTime.compareAndSet(oldTime, curTime)) { + return true; + } + return false; + } + + public boolean reachCountInterval(long c) { + return (count.incrementAndGet() % c == 0); + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/util/ObDirectLoadUtil.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/util/ObDirectLoadUtil.java new file mode 100644 index 00000000..72caeabc --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/util/ObDirectLoadUtil.java @@ -0,0 +1,269 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.direct_load.util; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; + +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadLogger; +import com.alipay.oceanbase.rpc.direct_load.exception.*; + +import io.netty.util.internal.ObjectUtil; + +public class ObDirectLoadUtil { + + private ObDirectLoadUtil() { + ObjectUtil.checkNotNull(null, null); + } + + /** + * Checks that the given argument is not null. + */ + public static T checkNotNull(T arg, final String name, ObDirectLoadLogger logger) + throws ObDirectLoadException { + if (arg == null) { + logger.warn("Param '" + name + "' must not be null"); + throw new ObDirectLoadIllegalArgumentException("Param '" + name + "' must not be null"); + } + return arg; + } + + /** + * Checks that the given argument is in range [start, end]. + */ + public static int checkInRange(int i, int start, int end, final String name, + ObDirectLoadLogger logger) throws ObDirectLoadException { + if (i < start || i > end) { + logger.warn("Param '" + name + "' is illegal value (expected: " + start + "-" + end + + "), value:" + i); + throw new ObDirectLoadIllegalArgumentException("Param '" + name + + "' is illegal value (expected: " + + start + "-" + end + "), value:" + i); + } + return i; + } + + /** + * Checks that the given argument is strictly positive. + */ + public static int checkPositive(int i, String name, ObDirectLoadLogger logger) + throws ObDirectLoadException { + if (i <= 0) { + logger.warn("Param '" + name + "' is illegal value (expected: > 0), value:" + i); + throw new ObDirectLoadIllegalArgumentException( + "Param '" + name + "' is illegal value (expected: > 0), value:" + i); + } + return i; + } + + /** + * Checks that the given argument is strictly positive. + */ + public static long checkPositive(long l, String name, ObDirectLoadLogger logger) + throws ObDirectLoadException { + if (l <= 0) { + logger.warn("Param '" + name + "' is illegal value (expected: > 0), value:" + l); + throw new ObDirectLoadIllegalArgumentException( + "Param '" + name + "' is illegal value (expected: > 0), value:" + l); + } + return l; + } + + /** + * Checks that the given argument is positive or zero. + */ + public static int checkPositiveOrZero(int i, String name, ObDirectLoadLogger logger) + throws ObDirectLoadException { + if (i < 0) { + logger.warn("Param '" + name + "' is illegal value (expected: >= 0), value:" + i); + throw new ObDirectLoadIllegalArgumentException( + "Param '" + name + "' is illegal value (expected: >= 0), value:" + i); + } + return i; + } + + /** + * Checks that the given argument is positive or zero. + */ + public static long checkPositiveOrZero(long l, String name, ObDirectLoadLogger logger) + throws ObDirectLoadException { + if (l < 0) { + logger.warn("Param '" + name + "' is illegal value (expected: >= 0), value:" + l); + throw new ObDirectLoadIllegalArgumentException( + "Param '" + name + "' is illegal value (expected: >= 0), value:" + l); + } + return l; + } + + /** + * Checks that the given argument is valid. + */ + public static T checkNonValid(T value, T invalidValue, String name, + ObDirectLoadLogger logger) throws ObDirectLoadException { + if (value == null || value.equals(invalidValue)) { + logger.warn("Param '" + name + "' must not be null or invalid value, value:" + value); + throw new ObDirectLoadIllegalArgumentException( + "Param '" + name + "' must not be null or invalid value, value:" + value); + } + return value; + } + + /** + * Checks that the given argument is neither null nor empty. + */ + public static T[] checkNonEmpty(T[] array, final String name, ObDirectLoadLogger logger) + throws ObDirectLoadException { + if (array == null || array.length == 0) { + logger.warn("Param '" + name + "' must not be null or empty, value:" + + Arrays.toString(array)); + throw new ObDirectLoadIllegalArgumentException("Param '" + name + + "' must not be null or empty, value:" + + Arrays.toString(array)); + } + return array; + } + + /** + * Checks that the given argument is neither null nor empty. + */ + public static byte[] checkNonEmpty(byte[] array, final String name, ObDirectLoadLogger logger) + throws ObDirectLoadException { + if (array == null || array.length == 0) { + logger.warn("Param '" + name + "' must not be null or empty, value:" + + Arrays.toString(array)); + throw new ObDirectLoadIllegalArgumentException("Param '" + name + + "' must not be null or empty, value:" + + Arrays.toString(array)); + } + return array; + } + + /** + * Checks that the given argument is neither null nor empty. + */ + public static char[] checkNonEmpty(char[] array, final String name, ObDirectLoadLogger logger) + throws ObDirectLoadException { + if (array == null || array.length == 0) { + logger.warn("Param '" + name + "' must not be null or empty, value:" + + Arrays.toString(array)); + throw new ObDirectLoadIllegalArgumentException("Param '" + name + + "' must not be null or empty, value:" + + Arrays.toString(array)); + } + return array; + } + + /** + * Checks that the given argument is neither null nor empty. + */ + public static > T checkNonEmpty(T collection, final String name, + ObDirectLoadLogger logger) + throws ObDirectLoadException { + if (collection == null || collection.isEmpty()) { + logger.warn("Param '" + name + "' must not be null or empty, value:" + collection); + throw new ObDirectLoadIllegalArgumentException("Param '" + name + + "' must not be null or empty, value:" + + collection); + } + return collection; + } + + /** + * Checks that the given argument is neither null nor empty. + */ + public static String checkNonEmpty(final String value, final String name, + ObDirectLoadLogger logger) throws ObDirectLoadException { + if (value == null || value.isEmpty()) { + logger.warn("Param '" + name + "' must not be null or empty, value:" + value); + throw new ObDirectLoadIllegalArgumentException("Param '" + name + + "' must not be null or empty, value:" + + value); + } + return value; + } + + /** + * Checks that the given argument is neither null nor empty. + */ + public static > T checkNonEmpty(T value, final String name, + ObDirectLoadLogger logger) + throws ObDirectLoadException { + if (value == null || value.isEmpty()) { + logger.warn("Param '" + name + "' must not be null or empty, value:" + value); + throw new ObDirectLoadIllegalArgumentException("Param '" + name + + "' must not be null or empty, value:" + + value); + } + return value; + } + + /** + * Checks that the given argument is not null. + */ + public static String checkNonEmptyArrayParam(String value, int index, String name, + ObDirectLoadLogger logger) + throws ObDirectLoadException { + if (value == null || value.isEmpty()) { + logger.warn("Array index " + index + " of parameter '" + name + + "' must not be null or empty, value:" + value); + throw new ObDirectLoadIllegalArgumentException("Array index " + index + + " of parameter '" + name + + "' must not be null or empty, value:" + + value); + } + return value; + } + + /** + * Check that the given array is neither null nor empty and does not contain elements + * is neither null nor empty elements. + */ + public static String[] deepCheckNonEmpty(String[] array, final String name, + ObDirectLoadLogger logger) + throws ObDirectLoadException { + checkNonEmpty(array, name, logger); + for (int index = 0; index < array.length; ++index) { + checkNonEmptyArrayParam(array[index], index, name, logger); + } + return array; + } + + /** + * Check that the given array is neither null nor empty and does not contain elements + * duplicate elements. + */ + public static String[] checkNonEmptyAndUnique(String[] array, final String name, + ObDirectLoadLogger logger) + throws ObDirectLoadException { + deepCheckNonEmpty(array, name, logger); + for (int i = 0; i < array.length - 1; ++i) { + for (int j = i + 1; j < array.length; ++j) { + if (array[i].equals(array[j])) { + logger.warn("Param '" + name + "' must not contain repeated elements, array:" + + Arrays.toString(array)); + throw new ObDirectLoadIllegalArgumentException( + "Param '" + name + "' must not contain repeated elements, array:" + + Arrays.toString(array)); + } + } + } + return array; + } + +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/packet/ObRpcPacketHeader.java b/src/main/java/com/alipay/oceanbase/rpc/protocol/packet/ObRpcPacketHeader.java index 5057a89e..f56b18e7 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/packet/ObRpcPacketHeader.java +++ b/src/main/java/com/alipay/oceanbase/rpc/protocol/packet/ObRpcPacketHeader.java @@ -546,4 +546,19 @@ public int getOriginalLen() { public void setOriginalLen(int originalLen) { this.originalLen = originalLen; } + + /* + * Get group id. + */ + public int getGroupId() { + return groupId; + } + + /* + * Set group id. + */ + public void setGroupId(int groupId) { + this.groupId = groupId; + } + } diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/AbstractPayload.java b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/AbstractPayload.java index a4e2322e..fa17103e 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/AbstractPayload.java +++ b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/AbstractPayload.java @@ -43,6 +43,7 @@ public abstract class AbstractPayload implements ObPayload { protected long tenantId = 1; private long version = 1; protected long timeout = RPC_OPERATION_TIMEOUT.getDefaultLong(); + protected int groupId = 0; /* * Get pcode. @@ -117,6 +118,21 @@ public void setTenantId(long tenantId) { this.tenantId = tenantId; } + /* + * Get group id. + */ + @Override + public int getGroupId() { + return groupId; + } + + /* + * Set group id. + */ + public void setGroupId(int groupId) { + this.groupId = groupId; + } + /* * Decode. */ diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/ObPayload.java b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/ObPayload.java index c1bd418b..fbafe00d 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/ObPayload.java +++ b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/ObPayload.java @@ -61,6 +61,11 @@ public interface ObPayload extends ObUnisVersion { */ long getUniqueId(); + /* + * @return group id + */ + int getGroupId(); + /* * @return encoded payload content */ diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/ResultCodes.java b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/ResultCodes.java index fdfef301..e7fa9555 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/ResultCodes.java +++ b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/ResultCodes.java @@ -636,6 +636,7 @@ public enum ResultCodes { OB_ERR_UNEXPECTED_TZ_TRANSITION(-5310), // OB_ERR_INVALID_COLUMN_ID(-5311), // OB_SCHEMA_EAGAIN(-5627), // + OB_ERR_PARALLEL_DDL_CONFLICT(-5827), // OB_TRANSACTION_SET_VIOLATION(-6001), // OB_TRANS_ROLLBACKED(-6002), // OB_ERR_EXCLUSIVE_LOCK_CONFLICT(-6003), // diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObLoadDupActionType.java b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/ObLoadDupActionType.java similarity index 95% rename from src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObLoadDupActionType.java rename to src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/ObLoadDupActionType.java index 359948b0..1586d17c 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObLoadDupActionType.java +++ b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/ObLoadDupActionType.java @@ -15,7 +15,7 @@ * #L% */ -package com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load; +package com.alipay.oceanbase.rpc.protocol.payload.impl; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadRequest.java b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadRequest.java index a5079126..bf8834d6 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadRequest.java +++ b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadRequest.java @@ -125,6 +125,21 @@ public long getPayloadContentSize() { + Serialization.getNeedBytes(argContent); } + @Override + public void setUniqueId(long uniqueId) { + // do nothing + } + + @Override + public void setSequence(long sequence) { + // do nothing + } + + public void setTraceId(long uniqueId, long sequence) { + super.setUniqueId(uniqueId); + super.setSequence(sequence); + } + public static class Header implements ObSimplePayload { private ObAddr addr = new ObAddr(); private ObTableDirectLoadOperationType operationType = ObTableDirectLoadOperationType.MAX_TYPE; diff --git a/src/main/java/com/alipay/oceanbase/rpc/table/ObDirectLoadBucket.java b/src/main/java/com/alipay/oceanbase/rpc/table/ObDirectLoadBucket.java deleted file mode 100644 index 464de222..00000000 --- a/src/main/java/com/alipay/oceanbase/rpc/table/ObDirectLoadBucket.java +++ /dev/null @@ -1,109 +0,0 @@ -/*- - * #%L - * com.oceanbase:obkv-table-client - * %% - * Copyright (C) 2021 - 2023 OceanBase - * %% - * OBKV Table Client Framework is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - * #L% - */ - -package com.alipay.oceanbase.rpc.table; - -import java.util.ArrayList; -import java.util.List; - -import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; -import com.alipay.oceanbase.rpc.protocol.payload.impl.ObObj; -import com.alipay.oceanbase.rpc.util.ObByteBuf; -import com.alipay.oceanbase.rpc.util.Serialization; - -import io.netty.buffer.ByteBuf; - -public class ObDirectLoadBucket implements ObSimplePayload { - - private ArrayList rowList = new ArrayList(); - - public ObDirectLoadBucket() { - } - - public boolean isEmpty() { - return rowList.isEmpty(); - } - - public int getRowCount() { - return rowList.size(); - } - - public void addRow(ObObj[] row) { - rowList.add(new ObDirectLoadObjRow(row)); - } - - public void addRow(List row) { - rowList.add(new ObDirectLoadObjRow(row)); - } - - public void addRow(ObDirectLoadObjRow row) { - if (row == null) { - throw new NullPointerException(); - } - rowList.add(row); - } - - /** - * Encode. - */ - @Override - public byte[] encode() { - int needBytes = getEncodedSize(); - ObByteBuf buf = new ObByteBuf(needBytes); - encode(buf); - return buf.bytes; - } - - /** - * Encode. - */ - @Override - public void encode(ObByteBuf buf) { - Serialization.encodeVi32(buf, rowList.size()); - for (int i = 0; i < rowList.size(); ++i) { - rowList.get(i).encode(buf); - } - } - - /** - * Decode. - */ - @Override - public ObDirectLoadBucket decode(ByteBuf buf) { - int count = Serialization.decodeVi32(buf); - for (int i = 0; i < count; ++i) { - ObDirectLoadObjRow row = new ObDirectLoadObjRow(); - row.decode(buf); - rowList.add(row); - } - return this; - } - - /** - * Get encoded size. - */ - @Override - public int getEncodedSize() { - int size = 0; - size += Serialization.getNeedBytes(rowList.size()); - for (int i = 0; i < rowList.size(); ++i) { - size += rowList.get(i).getEncodedSize(); - } - return size; - } - -} diff --git a/src/main/java/com/alipay/oceanbase/rpc/table/ObDirectLoadObjRow.java b/src/main/java/com/alipay/oceanbase/rpc/table/ObDirectLoadObjRow.java deleted file mode 100644 index 34cd4483..00000000 --- a/src/main/java/com/alipay/oceanbase/rpc/table/ObDirectLoadObjRow.java +++ /dev/null @@ -1,124 +0,0 @@ -/*- - * #%L - * com.oceanbase:obkv-table-client - * %% - * Copyright (C) 2021 - 2023 OceanBase - * %% - * OBKV Table Client Framework is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - * #L% - */ - -package com.alipay.oceanbase.rpc.table; - -import java.util.List; - -import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; -import com.alipay.oceanbase.rpc.protocol.payload.impl.ObObj; -import com.alipay.oceanbase.rpc.util.ObByteBuf; -import com.alipay.oceanbase.rpc.util.Serialization; - -import io.netty.buffer.ByteBuf; - -public class ObDirectLoadObjRow implements ObSimplePayload { - - private long SeqNo = 0; - private ObObj[] cells = new ObObj[0]; - - public ObDirectLoadObjRow() { - } - - public ObDirectLoadObjRow(ObObj[] cells) { - setCells(cells); - setSeqNo(0); - } - - public ObDirectLoadObjRow(List cells) { - setCells(cells); - setSeqNo(0); - } - - public ObObj[] getCells() { - return cells; - } - - public void setCells(ObObj[] cells) { - if (cells == null) - throw new NullPointerException(); - this.cells = cells; - } - - public void setCells(List cells) { - if (cells == null) - throw new NullPointerException(); - this.cells = cells.toArray(new ObObj[0]); - } - - public void setSeqNo(long SeqNo) { - this.SeqNo = SeqNo; - } - - public long getSeqNo() { - return SeqNo; - } - - /** - * Encode. - */ - @Override - public byte[] encode() { - int needBytes = getEncodedSize(); - ObByteBuf buf = new ObByteBuf(needBytes); - encode(buf); - return buf.bytes; - } - - /** - * Encode. - */ - @Override - public void encode(ObByteBuf buf) { - Serialization.encodeVi64(buf, SeqNo); - Serialization.encodeVi32(buf, cells.length); - for (int i = 0; i < cells.length; ++i) { - cells[i].encode(buf); - } - } - - /** - * Decode. - */ - @Override - public ObDirectLoadObjRow decode(ByteBuf buf) { - SeqNo = Serialization.decodeVi64(buf); - int count = Serialization.decodeVi32(buf); - cells = new ObObj[count]; - for (int i = 0; i < count; ++i) { - ObObj obj = new ObObj(); - obj.decode(buf); - cells[i] = obj; - } - return this; - } - - /** - * Get encoded size. - */ - @Override - public int getEncodedSize() { - int size = 0; - size += Serialization.getNeedBytes(SeqNo); - size += Serialization.getNeedBytes(cells.length); - for (int i = 0; i < cells.length; ++i) { - size += cells[i].getEncodedSize(); - } - return size; - } - -} diff --git a/src/main/java/com/alipay/oceanbase/rpc/table/ObDirectLoadParameter.java b/src/main/java/com/alipay/oceanbase/rpc/table/ObDirectLoadParameter.java deleted file mode 100644 index 0199b7f6..00000000 --- a/src/main/java/com/alipay/oceanbase/rpc/table/ObDirectLoadParameter.java +++ /dev/null @@ -1,93 +0,0 @@ -/*- - * #%L - * com.oceanbase:obkv-table-client - * %% - * Copyright (C) 2021 - 2023 OceanBase - * %% - * OBKV Table Client Framework is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - * #L% - */ - -package com.alipay.oceanbase.rpc.table; - -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObLoadDupActionType; - -public class ObDirectLoadParameter { - - private long parallel = 0; - private long maxErrorRowCount = 0; - private ObLoadDupActionType dupAction = ObLoadDupActionType.INVALID_MODE; - private long timeout = 0; - private long heartBeatTimeout = 0; - - public ObDirectLoadParameter() { - } - - public ObDirectLoadParameter(long parallel, long maxErrorRowCount, - ObLoadDupActionType dupAction, long timeout, long heartBeatTimeout) { - this.parallel = parallel; - this.maxErrorRowCount = maxErrorRowCount; - this.dupAction = dupAction; - this.timeout = timeout; - this.heartBeatTimeout = heartBeatTimeout; - } - - public long getParallel() { - return parallel; - } - - public ObDirectLoadParameter setParallel(int parallel) { - this.parallel = parallel; - return this; - } - - public long getMaxErrorRowCount() { - return maxErrorRowCount; - } - - public ObDirectLoadParameter setMaxErrorRowCount(long maxErrorRowCount) { - this.maxErrorRowCount = maxErrorRowCount; - return this; - } - - public ObLoadDupActionType getDupAction() { - return dupAction; - } - - public ObDirectLoadParameter setDupAction(ObLoadDupActionType dupAction) { - this.dupAction = dupAction; - return this; - } - - public long getTimeout() { - return timeout; - } - - public ObDirectLoadParameter setTimeout(long timeout) { - this.timeout = timeout; - return this; - } - - public long getHeartBeatTimeout() { - return heartBeatTimeout; - } - - public ObDirectLoadParameter setHeartBeatTimeout(long heartBeatTimeout) { - this.heartBeatTimeout = heartBeatTimeout; - return this; - } - - public String toString() { - return String.format( - "{parallel:%s, maxErrorRowCount:%d, dupAction:%s, timeout:%d, heartBeatTimeout:%d}", - parallel, maxErrorRowCount, dupAction, timeout, heartBeatTimeout); - } - -} diff --git a/src/main/java/com/alipay/oceanbase/rpc/table/ObTableDirectLoad.java b/src/main/java/com/alipay/oceanbase/rpc/table/ObTableDirectLoad.java deleted file mode 100644 index f0460599..00000000 --- a/src/main/java/com/alipay/oceanbase/rpc/table/ObTableDirectLoad.java +++ /dev/null @@ -1,368 +0,0 @@ -/*- - * #%L - * com.oceanbase:obkv-table-client - * %% - * Copyright (C) 2021 - 2023 OceanBase - * %% - * OBKV Table Client Framework is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - * #L% - */ - -package com.alipay.oceanbase.rpc.table; - -import com.alipay.oceanbase.rpc.ObGlobal; -import com.alipay.oceanbase.rpc.exception.ObTableException; -import com.alipay.oceanbase.rpc.property.AbstractPropertyAware; -import com.alipay.oceanbase.rpc.protocol.payload.ObPayload; -import com.alipay.oceanbase.rpc.protocol.payload.ObSimplePayload; -import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes; -import com.alipay.oceanbase.rpc.protocol.payload.impl.ObAddr; -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadAbortArg; -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadBeginArg; -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadBeginRes; -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadCommitArg; -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadGetStatusArg; -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadGetStatusRes; -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadInsertArg; -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadHeartBeatArg; -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadHeartBeatRes; -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadOperationType; -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadRequest; -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableDirectLoadResult; -import com.alipay.oceanbase.rpc.protocol.payload.impl.direct_load.ObTableLoadClientStatus; -import com.alipay.oceanbase.rpc.util.ObBytesString; -import com.alipay.oceanbase.rpc.util.TableClientLoggerFactory; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; - -import java.util.Properties; -import java.util.Timer; -import java.util.TimerTask; - -import org.slf4j.Logger; - -import static com.alipay.oceanbase.rpc.property.Property.*; - -public class ObTableDirectLoad extends AbstractPropertyAware { - - private static final Logger logger = TableClientLoggerFactory - .getLogger(ObTableDirectLoad.class); - - private ObTable table = null; - private String tableName; - private ObDirectLoadParameter parameter = null; - private boolean forceCreate = false; - - private long tableId = 0; - private long taskId = 0; - private String[] columnNames = new String[0]; - private ObTableLoadClientStatus status = ObTableLoadClientStatus.MAX_STATUS; - private int errorCode = ResultCodes.OB_SUCCESS.errorCode; - private ObAddr srvAddr = null; - - private Timer timer; - - /* Properities */ - protected int runtimeRetryTimes = RUNTIME_RETRY_TIMES.getDefaultInt(); - protected int runtimeRetryInterval = RUNTIME_RETRY_INTERVAL.getDefaultInt(); - - public ObTableDirectLoad(ObTable table, String tableName, ObDirectLoadParameter parameter, - boolean forceCreate) { - if (ObGlobal.OB_VERSION < ObGlobal.OB_VERSION_4_2_1_0) { - logger.warn("not supported ob version {}", ObGlobal.obVsnString()); - throw new ObTableException("not supported ob version " + ObGlobal.obVsnString(), - ResultCodes.OB_NOT_SUPPORTED.errorCode); - } - if (table == null || tableName == null || tableName.isEmpty() || parameter == null) { - logger.warn("invalid args, table:{}, tableName:{}, parameter:{}", table, tableName, - parameter); - throw new IllegalArgumentException("invalid args: " + table + ", " + tableName + ", " - + parameter); - } - this.table = table; - this.tableName = tableName; - this.parameter = parameter; - this.forceCreate = forceCreate; - initProperties(); - } - - @Override - public void setProperties(Properties properties) { - this.properties = properties; - initProperties(); - } - - public ObTable getTable() { - return table; - } - - public String getTableName() { - return tableName; - } - - public ObDirectLoadParameter getParameter() { - return parameter; - } - - public long getTableId() { - return tableId; - } - - public long getTaskId() { - return taskId; - } - - public String[] getColumnNames() { - return columnNames; - } - - public boolean isAvailable() { - return status != ObTableLoadClientStatus.MAX_STATUS; - } - - public boolean isRunning() { - return status == ObTableLoadClientStatus.RUNNING; - } - - public boolean isCommitting() { - return status == ObTableLoadClientStatus.COMMITTING; - } - - public boolean isCommit() { - return status == ObTableLoadClientStatus.COMMIT; - } - - public boolean isError() { - return status == ObTableLoadClientStatus.ERROR; - } - - public boolean isAbort() { - return status == ObTableLoadClientStatus.ABORT; - } - - public int getErrorCode() { - return errorCode; - } - - public ObAddr getSrvAddr() { - return srvAddr; - } - - public String toString() { - return String.format("{tableName:%s, tableId:%d, taskId:%d}", tableName, tableId, taskId); - } - - private void initProperties() { - runtimeRetryTimes = parseToInt(RUNTIME_RETRY_TIMES.getKey(), runtimeRetryTimes); - runtimeRetryInterval = parseToInt(RUNTIME_RETRY_INTERVAL.getKey(), runtimeRetryInterval); - } - - public void begin() throws Exception { - if (status != ObTableLoadClientStatus.MAX_STATUS) { - logger.warn("unexpected status to begin, table:{}, status:{}", this, status); - throw new ObTableException("unexpected status to begin, status:" + status, - ResultCodes.OB_STATE_NOT_MATCH.errorCode); - } - ObTableDirectLoadBeginArg arg = new ObTableDirectLoadBeginArg(); - ObTableDirectLoadBeginRes res = new ObTableDirectLoadBeginRes(); - arg.setTableName(tableName); - arg.setParallel(parameter.getParallel()); - arg.setMaxErrorRowCount(parameter.getMaxErrorRowCount()); - arg.setDupAction(parameter.getDupAction()); - arg.setTimeout(parameter.getTimeout()); - arg.setHeartBeatTimeout(parameter.getHeartBeatTimeout()); - arg.setForceCreate(forceCreate); - execute(ObTableDirectLoadOperationType.BEGIN, arg, res); - tableId = res.getTableId(); - taskId = res.getTaskId(); - columnNames = res.getColumnNames(); - status = res.getStatus(); - errorCode = res.getErrorCode(); - logger.info("begin suceess, table:{}", this); - startHeartBeat(); - } - - public void commit() throws Exception { - if (!isRunning()) { - logger.warn("unexpected status to commit, table:{}, status:{}", this, status); - throw new ObTableException("unexpected status to commit, status:" + status, - ResultCodes.OB_STATE_NOT_MATCH.errorCode); - } - ObTableDirectLoadCommitArg arg = new ObTableDirectLoadCommitArg(); - arg.setTableId(tableId); - arg.setTaskId(taskId); - execute(ObTableDirectLoadOperationType.COMMIT, arg); - logger.info("commit suceess, table:{}", this); - } - - public void abort() throws Exception { - if (status == ObTableLoadClientStatus.MAX_STATUS) { - logger.warn("unexpected status to abort, table:{}, status:{}", this, status); - throw new ObTableException("unexpected status to abort, status:" + status, - ResultCodes.OB_STATE_NOT_MATCH.errorCode); - } - if (isAbort()) { - return; - } - ObTableDirectLoadAbortArg arg = new ObTableDirectLoadAbortArg(); - arg.setTableId(tableId); - arg.setTaskId(taskId); - execute(ObTableDirectLoadOperationType.ABORT, arg); - logger.info("abort suceess, table:{}", this); - stopHeartBeat(); - } - - public ObTableLoadClientStatus getStatus() throws Exception { - if (status == ObTableLoadClientStatus.MAX_STATUS) { - logger.warn("unexpected status to get status, table:{}, status:{}", this, status); - throw new ObTableException("unexpected status to get status, status:" + status, - ResultCodes.OB_STATE_NOT_MATCH.errorCode); - } - ObTableDirectLoadGetStatusArg arg = new ObTableDirectLoadGetStatusArg(); - ObTableDirectLoadGetStatusRes res = new ObTableDirectLoadGetStatusRes(); - arg.setTableId(tableId); - arg.setTaskId(taskId); - execute(ObTableDirectLoadOperationType.GET_STATUS, arg, res); - status = res.getStatus(); - errorCode = res.getErrorCode(); - return status; - } - - public void insert(ObDirectLoadBucket bucket) throws Exception { - if (!isRunning()) { - logger.warn("unexpected status to insert, table:{}, status:{}", this, status); - throw new ObTableException("unexpected status to insert, status:" + status, - ResultCodes.OB_STATE_NOT_MATCH.errorCode); - } - ObTableDirectLoadInsertArg arg = new ObTableDirectLoadInsertArg(); - arg.setTableId(tableId); - arg.setTaskId(taskId); - arg.setPayload(new ObBytesString(bucket.encode())); - execute(ObTableDirectLoadOperationType.INSERT, arg); - } - - private void heartBeat() throws Exception { - ObTableDirectLoadHeartBeatArg arg = new ObTableDirectLoadHeartBeatArg(); - ObTableDirectLoadHeartBeatRes res = new ObTableDirectLoadHeartBeatRes(); - arg.setTableId(tableId); - arg.setTaskId(taskId); - execute(ObTableDirectLoadOperationType.HEART_BEAT, arg, res); - status = res.getStatus(); - errorCode = res.getErrorCode(); - } - - private void startHeartBeat() { - timer = new Timer(); - TimerTask task = new TimerTask() { - public void run() { - try { - heartBeat(); - } catch (Exception e) { - stopHeartBeat(); - logger.info(String.format("heart beat failed, table:%s", this), e); - } - } - }; - timer.schedule(task, 0, 10000); - logger.info("start heart beat, table:{}", this); - } - - private void stopHeartBeat() { - if (timer != null) { - timer.cancel(); - timer = null; - } - logger.info("stop heart beat, table:{}", this); - } - - private void execute(ObTableDirectLoadOperationType operationType, ObSimplePayload arg, - ObSimplePayload res) throws Exception { - ObTableDirectLoadRequest request = new ObTableDirectLoadRequest(); - ObTableDirectLoadRequest.Header header = new ObTableDirectLoadRequest.Header(); - if (operationType != ObTableDirectLoadOperationType.BEGIN) { - header.setAddr(srvAddr); - } - header.setOperationType(operationType); - request.setHeader(header); - request.setArgContent(new ObBytesString(arg.encode())); - ObTableDirectLoadResult result = (ObTableDirectLoadResult) rpcCall(request); - if (result.getHeader().getOperationType() != operationType) { - logger.warn("unexpected result operation type, table:{}, reqOpType:{}, resOpType:{}", - this, operationType, result.getHeader().getOperationType()); - throw new ObTableException("unexpected result operation type:" - + result.getHeader().getOperationType() - + ", request operation type:" + operationType, - ResultCodes.OB_ERR_UNEXPECTED.errorCode); - } - if (result.getResContent().length() == 0) { - logger.warn("unexpected empty res content, table:{}, OpType:{}", this, operationType); - throw new ObTableException("unexpected empty res content", - ResultCodes.OB_ERR_UNEXPECTED.errorCode); - } - if (operationType == ObTableDirectLoadOperationType.BEGIN) { - srvAddr = result.getHeader().getAddr(); - } - ByteBuf buf = ByteBufAllocator.DEFAULT.buffer(result.getResContent().length()); - try { - buf.writeBytes(result.getResContent().bytes); - res.decode(buf); - } finally { - buf.release(); - } - } - - private void execute(ObTableDirectLoadOperationType operationType, ObSimplePayload arg) - throws Exception { - ObTableDirectLoadRequest request = new ObTableDirectLoadRequest(); - ObTableDirectLoadRequest.Header header = new ObTableDirectLoadRequest.Header(); - if (operationType != ObTableDirectLoadOperationType.BEGIN) { - header.setAddr(srvAddr); - } - header.setOperationType(operationType); - request.setHeader(header); - request.setArgContent(new ObBytesString(arg.encode())); - ObTableDirectLoadResult result = (ObTableDirectLoadResult) rpcCall(request); - if (result.getHeader().getOperationType() != operationType) { - logger.warn("unexpected result operation type, table:{}, reqOpType:{}, resOpType:{}", - this, operationType, result.getHeader().getOperationType()); - throw new ObTableException("unexpected result operation type:" - + result.getHeader().getOperationType() - + ", request operation type:" + operationType, - ResultCodes.OB_ERR_UNEXPECTED.errorCode); - } - if (result.getResContent().length() != 0) { - logger.warn("unexpected res content not empty, table:{}, OpType:{}", this, - operationType); - throw new ObTableException("unexpected res content not empty", - ResultCodes.OB_ERR_UNEXPECTED.errorCode); - } - } - - private ObPayload rpcCall(ObTableDirectLoadRequest request) throws Exception { - int tries = 0; - while (true) { - try { - request.setTimeout(table.getObTableExecuteTimeout()); - return table.execute(request); - } catch (Exception e) { - logger.warn(String.format("table execute failed, table:%s, tries:%d, request:%s", - this, tries, request), e); - if (tries < runtimeRetryTimes) { - Thread.sleep(runtimeRetryInterval); - } else { - throw e; - } - ++tries; - } - } - } - -} diff --git a/src/main/java/com/alipay/oceanbase/rpc/util/ObByteBuf.java b/src/main/java/com/alipay/oceanbase/rpc/util/ObByteBuf.java index 696abcb2..51f90b84 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/util/ObByteBuf.java +++ b/src/main/java/com/alipay/oceanbase/rpc/util/ObByteBuf.java @@ -47,6 +47,31 @@ public int capacity() { return bytes.length; } + /** + * Returns the number of readable bytes. + */ + public int readableBytes() { + return pos; + } + + /** + * Returns the number of writable bytes. + */ + public int writableBytes() { + return bytes.length - pos; + } + + /* + * Reserve bytes. + */ + public void reserve(int size) { + if (pos + size > bytes.length) { + throw new IllegalArgumentException(String.format( + "size overflow, capacity(%d), pos(%d), reserve_size(%d)", bytes.length, pos, size)); + } + pos += size; + } + /** * Write byte * @param b byte diff --git a/src/main/java/com/alipay/oceanbase/rpc/util/Serialization.java b/src/main/java/com/alipay/oceanbase/rpc/util/Serialization.java index 7b8c0d8e..df9ff66e 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/util/Serialization.java +++ b/src/main/java/com/alipay/oceanbase/rpc/util/Serialization.java @@ -528,6 +528,21 @@ public static int getNeedBytes(String str) { return getNeedBytes(utf8Length) + utf8Length + 1; } + /** + * Get need bytes. + * @param strs input data + * @return bytes need for serialize string[] data + */ + public static int getNeedBytes(String[] strs) { + if (strs == null) + strs = new String[0]; + int needBytes = getNeedBytes(strs.length); + for (int i = 0; i < strs.length; ++i) { + needBytes += getNeedBytes(strs[i]); + } + return needBytes; + } + private static int getUtf8Length(int codePoint) { if (codePoint <= 0x7F) { return 1; @@ -694,6 +709,36 @@ public static void encodeVString(ObByteBuf buf, String str) { encodeVString(buf, str, StandardCharsets.UTF_8); } + /** + * Encode VString Array. + * @param buf encoded buf + * @param strs input data + */ + public static void encodeVStringArray(ObByteBuf buf, String[] strs) { + if (strs == null) { + strs = new String[0]; + } + encodeVi32(buf, strs.length); + for (int i = 0; i < strs.length; ++i) { + encodeVString(buf, strs[i]); + } + } + + /** + * Encode VString Array. + * @param strs input data + * @return output data buffer + */ + public static byte[] encodeVStringArray(String[] strs) { + if (strs == null) { + strs = new String[0]; + } + final int needBytes = getNeedBytes(strs); + ObByteBuf buf = new ObByteBuf(needBytes); + encodeVStringArray(buf, strs); + return buf.bytes; + } + /** * Encode BytesString * @param str input data @@ -889,6 +934,38 @@ public static String decodeVString(ByteBuf buffer, Charset charset) { return decodeVString(content, charset); } + /** + * Decode byte string array + * @param buffer input data + * @return output data + */ + public static String[] decodeVStringArray(ByteBuf buffer) { + final int count = decodeVi32(buffer); + String[] strs = new String[count]; + for (int i = 0; i < count; ++i) { + strs[i] = decodeVString(buffer); + } + return strs; + } + + public static String[] decodeVStringArray(ByteBuf buffer, String charset) { + final int count = decodeVi32(buffer); + String[] strs = new String[count]; + for (int i = 0; i < count; ++i) { + strs[i] = decodeVString(buffer, charset); + } + return strs; + } + + public static String[] decodeVStringArray(ByteBuf buffer, Charset charset) { + final int count = decodeVi32(buffer); + String[] strs = new String[count]; + for (int i = 0; i < count; ++i) { + strs[i] = decodeVString(buffer, charset); + } + return strs; + } + /** * Decode VString * @param content input data diff --git a/src/main/java/com/alipay/oceanbase/rpc/util/TableClientLoggerFactory.java b/src/main/java/com/alipay/oceanbase/rpc/util/TableClientLoggerFactory.java index 339da27c..4bcb1fbb 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/util/TableClientLoggerFactory.java +++ b/src/main/java/com/alipay/oceanbase/rpc/util/TableClientLoggerFactory.java @@ -31,17 +31,20 @@ public class TableClientLoggerFactory { public static final String OCEANBASE_TABLE_CLIENT_BOOT = "OBKV-BOOT"; public static final String OCEANBASE_TABLE_CLIENT_MONITOR = "OBKV-MONITOR"; public static final String OCEANBASE_TABLE_CLIENT_RUNTIME = "OBKV-RUNTIME"; + public static final String OCEANBASE_TABLE_CLIENT_DIRECT = "OBKV-DIRECT"; public static LogCode2Description LCD = LogCode2Description .create(OCEANBASE_TABLE_CLIENT_LOGGER_SPACE); public static Logger BOOT = NOPLogger.NOP_LOGGER; public static Logger MONITOR = NOPLogger.NOP_LOGGER; public static Logger RUNTIME = NOPLogger.NOP_LOGGER; + public static Logger DIRECT = NOPLogger.NOP_LOGGER; static { BOOT = getBootLogger(); MONITOR = getMonitorLogger(); RUNTIME = getRUNTIMELogger(); + DIRECT = getDIRECTLogger(); } public static Logger getLogger(String name) { @@ -90,6 +93,14 @@ public static Logger getRUNTIMELogger() { return RUNTIME; } + public static Logger getDIRECTLogger() { + if (DIRECT == NOPLogger.NOP_LOGGER) { + DIRECT = new WrappedLogger(getLogger(OCEANBASE_TABLE_CLIENT_DIRECT)); + } + + return DIRECT; + } + public static void changeLevel(Map levelMap) { for (Map.Entry entry : levelMap.entrySet()) { changeLevel(entry.getKey(), entry.getValue()); diff --git a/src/main/resources/oceanbase-table-client/log/log4j/log-conf.xml b/src/main/resources/oceanbase-table-client/log/log4j/log-conf.xml index 403587ff..e16d2fd5 100644 --- a/src/main/resources/oceanbase-table-client/log/log4j/log-conf.xml +++ b/src/main/resources/oceanbase-table-client/log/log4j/log-conf.xml @@ -51,6 +51,17 @@ + + + + + + + + + @@ -74,5 +85,10 @@ + + + + + diff --git a/src/main/resources/oceanbase-table-client/log/log4j2/log-conf.xml b/src/main/resources/oceanbase-table-client/log/log4j2/log-conf.xml index 5aece116..0c09c0b5 100644 --- a/src/main/resources/oceanbase-table-client/log/log4j2/log-conf.xml +++ b/src/main/resources/oceanbase-table-client/log/log4j2/log-conf.xml @@ -60,6 +60,19 @@ + + + + + %d-%m%n + + + + + + @@ -78,6 +91,10 @@ + + + + \ No newline at end of file diff --git a/src/main/resources/oceanbase-table-client/log/logback/log-conf.xml b/src/main/resources/oceanbase-table-client/log/logback/log-conf.xml index 8aae2c41..ba2d8b12 100644 --- a/src/main/resources/oceanbase-table-client/log/logback/log-conf.xml +++ b/src/main/resources/oceanbase-table-client/log/logback/log-conf.xml @@ -69,6 +69,23 @@ + + ${logging.path:-.}/oceanbase-table-client/oceanbase-table-client-direct.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{50} - %msg%n + + + + + ${logging.path:-.}/oceanbase-table-client/oceanbase-table-client-direct.%d{yyyy-MM-dd}.%i.log + false + 30 + 100MB + + + @@ -97,6 +114,15 @@ + + 0 + false + 1024 + false + + + @@ -118,4 +144,9 @@ + + + + + \ No newline at end of file From 165dbc0221d875f5035afaf6a3c2fe8585887e8e Mon Sep 17 00:00:00 2001 From: "suzhi.yt" Date: Tue, 10 Sep 2024 11:41:10 +0800 Subject: [PATCH 2/2] check parameters is supported --- .../direct_load/ObDirectLoadConnection.java | 2 +- .../direct_load/ObDirectLoadStatement.java | 3 +- .../protocol/ObDirectLoadProtocol.java | 3 ++ .../protocol/ObDirectLoadProtocolFactory.java | 7 +++- .../protocol/v0/ObDirectLoadProtocolV0.java | 37 ++++++++++++++++++- .../direct_load/ObTableDirectLoadResult.java | 1 - 6 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadConnection.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadConnection.java index 26122b1c..d5e8e4d2 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadConnection.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadConnection.java @@ -185,7 +185,7 @@ private void initProtocol() throws ObDirectLoadException { throw new ObDirectLoadException(e); } } - this.protocol = ObDirectLoadProtocolFactory.getProtocol(ObGlobal.OB_VERSION); + this.protocol = ObDirectLoadProtocolFactory.getProtocol(traceId, ObGlobal.OB_VERSION); this.protocol.init(); table.close(); } diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadStatement.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadStatement.java index 8c94e715..0925db8d 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadStatement.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/ObDirectLoadStatement.java @@ -45,7 +45,7 @@ public class ObDirectLoadStatement { private long queryTimeout = 0; private long maxErrorRowCount = 0; - private String loadMethod = "full"; + private String loadMethod = ""; private boolean isInited = false; private boolean isClosed = false; @@ -83,6 +83,7 @@ public synchronized void init(Builder builder) throws ObDirectLoadException { } fillParams(builder); initCheck(); + connection.getProtocol().checkIsSupported(this); obTablePool = new ObDirectLoadConnection.ObTablePool(connection, logger, queryTimeout); obTablePool.init(); executor = new ObDirectLoadStatementExecutor(this); diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocol.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocol.java index dd01b770..2b8d1d83 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocol.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocol.java @@ -17,6 +17,7 @@ package com.alipay.oceanbase.rpc.direct_load.protocol; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadTraceId; import com.alipay.oceanbase.rpc.direct_load.protocol.payload.*; import com.alipay.oceanbase.rpc.direct_load.exception.ObDirectLoadException; @@ -27,6 +28,8 @@ public interface ObDirectLoadProtocol { int getProtocolVersion(); + void checkIsSupported(ObDirectLoadStatement statement) throws ObDirectLoadException; + // rpc ObDirectLoadBeginRpc getBeginRpc(ObDirectLoadTraceId traceId); diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocolFactory.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocolFactory.java index e5032132..fda88e73 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocolFactory.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/ObDirectLoadProtocolFactory.java @@ -19,6 +19,7 @@ import com.alipay.oceanbase.rpc.ObGlobal; import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadLogger; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadTraceId; import com.alipay.oceanbase.rpc.direct_load.exception.*; import com.alipay.oceanbase.rpc.direct_load.protocol.v0.ObDirectLoadProtocolV0; @@ -67,7 +68,8 @@ public static boolean checkIsSupported(long obVersion) { return (obVersion >= minimumObVersion); } - public static ObDirectLoadProtocol getProtocol(long obVersion) throws ObDirectLoadException { + public static ObDirectLoadProtocol getProtocol(ObDirectLoadTraceId traceId, long obVersion) + throws ObDirectLoadException { final long minimumObVersion = getSupportedMinimumObVersion(obVersion); if (obVersion < minimumObVersion) { logger.warn("direct load in ob version " + ObGlobal.getObVsnString(obVersion) @@ -78,6 +80,7 @@ public static ObDirectLoadProtocol getProtocol(long obVersion) throws ObDirectLo + " is not supported, minimum version required is " + ObGlobal.getObVsnString(minimumObVersion)); } - return new ObDirectLoadProtocolV0(); + return new ObDirectLoadProtocolV0(traceId, obVersion); } + } diff --git a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/ObDirectLoadProtocolV0.java b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/ObDirectLoadProtocolV0.java index a8842fb3..6bc9e0f4 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/ObDirectLoadProtocolV0.java +++ b/src/main/java/com/alipay/oceanbase/rpc/direct_load/protocol/v0/ObDirectLoadProtocolV0.java @@ -17,6 +17,9 @@ package com.alipay.oceanbase.rpc.direct_load.protocol.v0; +import com.alipay.oceanbase.rpc.ObGlobal; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadLogger; +import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadStatement; import com.alipay.oceanbase.rpc.direct_load.ObDirectLoadTraceId; import com.alipay.oceanbase.rpc.direct_load.exception.*; import com.alipay.oceanbase.rpc.direct_load.protocol.ObDirectLoadProtocol; @@ -25,9 +28,16 @@ public class ObDirectLoadProtocolV0 implements ObDirectLoadProtocol { - private static final int PROTOCOL_VERSION = 0; + public static final long OB_VERSION_4_3_2_0 = ObGlobal.calcVersion(4, (short) 3, + (byte) 2, (byte) 0); - public ObDirectLoadProtocolV0() { + private static final int PROTOCOL_VERSION = 0; + private final ObDirectLoadLogger logger; + private final long obVersion; + + public ObDirectLoadProtocolV0(ObDirectLoadTraceId traceId, long obVersion) { + this.logger = ObDirectLoadLogger.getLogger(traceId); + this.obVersion = obVersion; } @Override @@ -39,6 +49,29 @@ public int getProtocolVersion() { return PROTOCOL_VERSION; } + @Override + public void checkIsSupported(ObDirectLoadStatement statement) throws ObDirectLoadException { + if (obVersion < OB_VERSION_4_3_2_0) { + // 432以下不支持inc|inc_replace + String loadMethod = statement.getLoadMethod(); + if (!loadMethod.isEmpty() && !loadMethod.equalsIgnoreCase("full")) { + logger.warn("load method in ob version " + ObGlobal.getObVsnString(obVersion) + + "is not supported, minimum version required is " + + ObGlobal.getObVsnString(OB_VERSION_4_3_2_0)); + throw new ObDirectLoadNotSupportedException( + "load method in ob version " + ObGlobal.getObVsnString(obVersion) + + " is not supported, minimum version required is " + + ObGlobal.getObVsnString(OB_VERSION_4_3_2_0)); + } + } else if (statement.getPartitionNames().length > 0) { + logger.warn("partition names in ob version " + ObGlobal.getObVsnString(obVersion) + + "is not supported"); + throw new ObDirectLoadNotSupportedException("partition names in ob version " + + ObGlobal.getObVsnString(obVersion) + + " is not supported"); + } + } + @Override public ObDirectLoadBeginRpc getBeginRpc(ObDirectLoadTraceId traceId) { return new ObDirectLoadBeginRpcV0(traceId); diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadResult.java b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadResult.java index bf22476e..cbf8a5f2 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadResult.java +++ b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/direct_load/ObTableDirectLoadResult.java @@ -150,7 +150,6 @@ public void encode(ObByteBuf buf) { */ @Override public Header decode(ByteBuf buf) { - addr = new ObAddr(); addr.decode(buf); operationType = ObTableDirectLoadOperationType.valueOf(Serialization.decodeI8(buf)); return this;