mirror of
https://github.com/apache/rocketmq.git
synced 2026-09-21 13:49:50 +08:00
[ISSUE #3949] Implement pull and stream
This commit is contained in:
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.rocketmq.proxy.grpc.adapter.channel;
|
||||
|
||||
import apache.rocketmq.v1.PullMessageRequest;
|
||||
import apache.rocketmq.v1.PullMessageResponse;
|
||||
import org.apache.rocketmq.proxy.channel.InvocationChannel;
|
||||
import org.apache.rocketmq.proxy.grpc.adapter.handler.PullMessageResponseHandler;
|
||||
|
||||
public class PullMessageChannel extends InvocationChannel<PullMessageRequest, PullMessageResponse> {
|
||||
public PullMessageChannel(PullMessageResponseHandler handler) {
|
||||
super(handler);
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.rocketmq.proxy.grpc.adapter.handler;
|
||||
|
||||
import apache.rocketmq.v1.PullMessageRequest;
|
||||
import apache.rocketmq.v1.PullMessageResponse;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import org.apache.rocketmq.common.message.MessageDecoder;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.common.protocol.ResponseCode;
|
||||
import org.apache.rocketmq.common.protocol.header.PullMessageResponseHeader;
|
||||
import org.apache.rocketmq.proxy.grpc.adapter.InvocationContext;
|
||||
import org.apache.rocketmq.proxy.grpc.common.Converter;
|
||||
import org.apache.rocketmq.proxy.grpc.common.ResponseBuilder;
|
||||
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
|
||||
|
||||
public class PullMessageResponseHandler implements ResponseHandler<PullMessageRequest, PullMessageResponse> {
|
||||
@Override public void handle(RemotingCommand responseCommand,
|
||||
InvocationContext<PullMessageRequest, PullMessageResponse> context) {
|
||||
try {
|
||||
PullMessageResponseHeader responseHeader = (PullMessageResponseHeader) responseCommand.readCustomHeader();
|
||||
PullMessageResponse.Builder builder = PullMessageResponse.newBuilder();
|
||||
if (responseCommand.getCode() == ResponseCode.SUCCESS) {
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(responseCommand.getBody());
|
||||
List<MessageExt> msgFoundList = MessageDecoder.decodes(byteBuffer);
|
||||
for (MessageExt messageExt : msgFoundList) {
|
||||
builder.addMessages(Converter.buildMessage(messageExt));
|
||||
}
|
||||
}
|
||||
PullMessageResponse response = builder.setCommon(ResponseBuilder.buildCommon(responseCommand.getCode(), responseCommand.getRemark()))
|
||||
.setMinOffset(responseHeader.getMinOffset())
|
||||
.setNextOffset(responseHeader.getNextBeginOffset())
|
||||
.setMaxOffset(responseHeader.getMaxOffset())
|
||||
.build();
|
||||
context.getResponse().complete(response);
|
||||
} catch (Exception e) {
|
||||
context.getResponse().completeExceptionally(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,12 +35,14 @@ import apache.rocketmq.v1.NackMessageResponse;
|
||||
import apache.rocketmq.v1.NoopCommand;
|
||||
import apache.rocketmq.v1.NotifyClientTerminationRequest;
|
||||
import apache.rocketmq.v1.NotifyClientTerminationResponse;
|
||||
import apache.rocketmq.v1.Partition;
|
||||
import apache.rocketmq.v1.PollCommandRequest;
|
||||
import apache.rocketmq.v1.PollCommandResponse;
|
||||
import apache.rocketmq.v1.PullMessageRequest;
|
||||
import apache.rocketmq.v1.PullMessageResponse;
|
||||
import apache.rocketmq.v1.QueryAssignmentRequest;
|
||||
import apache.rocketmq.v1.QueryAssignmentResponse;
|
||||
import apache.rocketmq.v1.QueryOffsetPolicy;
|
||||
import apache.rocketmq.v1.QueryOffsetRequest;
|
||||
import apache.rocketmq.v1.QueryOffsetResponse;
|
||||
import apache.rocketmq.v1.QueryRouteRequest;
|
||||
@@ -54,6 +56,7 @@ import apache.rocketmq.v1.ReportThreadStackTraceResponse;
|
||||
import apache.rocketmq.v1.Resource;
|
||||
import apache.rocketmq.v1.SendMessageRequest;
|
||||
import apache.rocketmq.v1.SendMessageResponse;
|
||||
import com.google.protobuf.util.Timestamps;
|
||||
import com.google.rpc.Code;
|
||||
import io.grpc.Context;
|
||||
import io.netty.channel.Channel;
|
||||
@@ -76,6 +79,7 @@ import org.apache.rocketmq.common.protocol.header.ChangeInvisibleTimeResponseHea
|
||||
import org.apache.rocketmq.common.protocol.header.ConsumerSendMsgBackRequestHeader;
|
||||
import org.apache.rocketmq.common.protocol.header.EndTransactionRequestHeader;
|
||||
import org.apache.rocketmq.common.protocol.header.PopMessageRequestHeader;
|
||||
import org.apache.rocketmq.common.protocol.header.PullMessageRequestHeader;
|
||||
import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader;
|
||||
import org.apache.rocketmq.common.protocol.header.UnregisterClientRequestHeader;
|
||||
import org.apache.rocketmq.common.protocol.heartbeat.HeartbeatData;
|
||||
@@ -88,6 +92,8 @@ import org.apache.rocketmq.proxy.grpc.adapter.InvocationContext;
|
||||
import org.apache.rocketmq.proxy.grpc.adapter.channel.GrpcClientChannel;
|
||||
import org.apache.rocketmq.proxy.grpc.adapter.channel.ReceiveMessageChannel;
|
||||
import org.apache.rocketmq.proxy.grpc.adapter.channel.SendMessageChannel;
|
||||
import org.apache.rocketmq.proxy.grpc.adapter.channel.PullMessageChannel;
|
||||
import org.apache.rocketmq.proxy.grpc.adapter.handler.PullMessageResponseHandler;
|
||||
import org.apache.rocketmq.proxy.grpc.adapter.handler.ReceiveMessageResponseHandler;
|
||||
import org.apache.rocketmq.proxy.grpc.adapter.handler.SendMessageResponseHandler;
|
||||
import org.apache.rocketmq.proxy.grpc.common.Converter;
|
||||
@@ -352,11 +358,58 @@ public class LocalGrpcService implements GrpcForwardService {
|
||||
}
|
||||
|
||||
@Override public CompletableFuture<QueryOffsetResponse> queryOffset(Context ctx, QueryOffsetRequest request) {
|
||||
return null;
|
||||
Partition partition = request.getPartition();
|
||||
String topicName = Converter.getResourceNameWithNamespace(partition.getTopic());
|
||||
int queueId = partition.getId();
|
||||
|
||||
long offset;
|
||||
if (request.getPolicy() == QueryOffsetPolicy.BEGINNING) {
|
||||
offset = 0L;
|
||||
} else if (request.getPolicy() == QueryOffsetPolicy.END) {
|
||||
offset = brokerController.getMessageStore()
|
||||
.getMaxOffsetInQueue(topicName, queueId);
|
||||
} else {
|
||||
long timestamp = Timestamps.toMillis(request.getTimePoint());
|
||||
offset = brokerController.getMessageStore()
|
||||
.getOffsetInQueueByTime(topicName, queueId, timestamp);
|
||||
}
|
||||
return CompletableFuture.completedFuture(QueryOffsetResponse.newBuilder()
|
||||
.setCommon(ResponseBuilder.buildCommon(Code.OK, "ok"))
|
||||
.setOffset(offset)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override public CompletableFuture<PullMessageResponse> pullMessage(Context ctx, PullMessageRequest request) {
|
||||
return null;
|
||||
long timeRemaining = Context.current()
|
||||
.getDeadline()
|
||||
.timeRemaining(TimeUnit.MILLISECONDS);
|
||||
long pollTime = timeRemaining - ConfigurationManager.getProxyConfig().getLongPollingReserveTimeInMillis();
|
||||
if (pollTime <= 0) {
|
||||
pollTime = timeRemaining;
|
||||
}
|
||||
PullMessageRequestHeader requestHeader = Converter.buildPullMessageRequestHeader(request, pollTime);
|
||||
RemotingCommand command = RemotingCommand.createRequestCommand(RequestCode.PULL_MESSAGE, requestHeader);
|
||||
command.makeCustomHeaderToNet();
|
||||
|
||||
PullMessageResponseHandler handler = new PullMessageResponseHandler();
|
||||
PullMessageChannel channel = channelManager.createChannel(() -> new PullMessageChannel(handler), PullMessageChannel.class);
|
||||
SimpleChannelHandlerContext channelHandlerContext = new SimpleChannelHandlerContext(channel);
|
||||
CompletableFuture<PullMessageResponse> future = new CompletableFuture<>();
|
||||
InvocationContext<PullMessageRequest, PullMessageResponse> context = new InvocationContext<>(request, future);
|
||||
channel.registerInvocationContext(command.getOpaque(), context);
|
||||
try {
|
||||
RemotingCommand response = brokerController.getPullMessageProcessor()
|
||||
.processRequest(channelHandlerContext, command);
|
||||
if (response != null) {
|
||||
handler.handle(response, context);
|
||||
channel.eraseInvocationContext(command.getOpaque());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Failed to process pull message command", e);
|
||||
channel.eraseInvocationContext(command.getOpaque());
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
@Override public CompletableFuture<PollCommandResponse> pollCommand(Context ctx, PollCommandRequest request) {
|
||||
|
||||
Reference in New Issue
Block a user