我需要使用Pub / Sub Emulator测试具有回调功能的pubsub订户。
PullRequest pullRequest = PullRequest.newBuilder()
.setMaxMessages(1)
.setReturnImmediately(true) // return immediately if messages are not available
.setSubscription(subscription.getName())
.build();
但是我需要对 MessageReceiver
进行测试我尝试以下代码
import com.google.api.gax.core.CredentialsProvider;
import com.google.api.gax.core.NoCredentialsProvider;
import com.google.api.gax.grpc.GrpcTransportChannel;
import com.google.api.gax.rpc.FixedTransportChannelProvider;
import com.google.api.gax.rpc.TransportChannelProvider;
import com.google.cloud.pubsub.v1.*;
import com.google.cloud.pubsub.v1.stub.GrpcSubscriberStub;
import com.google.cloud.pubsub.v1.stub.SubscriberStub;
import com.google.cloud.pubsub.v1.stub.SubscriberStubSettings;
import com.google.protobuf.ByteString;
import com.google.pubsub.v1.*;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import org.junit.*;
import org.junit.runners.MethodSorters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.concurrent.Executors;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TTest {
private static final Logger log = LoggerFactory.getLogger(TTest.class);
private static String projectId = "test-project";
private static String topicId = "demo";
private static String subscriptionId = "demo";
private static String testSubscriptionId = "test";
private static final String hostPort = "127.0.0.1:8085";
private static ManagedChannel channel;
private static TransportChannelProvider channelProvider;
private static TopicAdminClient topicAdmin;
private static CredentialsProvider credentialsProvider;
private static Publisher publisher;
private static SubscriptionAdminClient subscriptionAdminClient;
private static ProjectTopicName topicName = ProjectTopicName.of(projectId, topicId);
private static ProjectSubscriptionName subscriptionName = ProjectSubscriptionName.of(projectId, subscriptionId);
private static ProjectSubscriptionName testSubscriptionName = ProjectSubscriptionName.of(projectId, testSubscriptionId);
private static SubscriberStub subscriberStub;
@BeforeClass
public static void create() throws Exception {
channel = ManagedChannelBuilder.forTarget(hostPort).usePlaintext().build();
channelProvider = FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel));
credentialsProvider = NoCredentialsProvider.create();
topicAdmin = TopicAdminClient.create(
TopicAdminSettings.newBuilder()
.setTransportChannelProvider(channelProvider)
.setCredentialsProvider(credentialsProvider)
.build()
);
topicAdmin.createTopic(topicName);
publisher = Publisher.newBuilder(topicName)
.setChannelProvider(channelProvider)
.setCredentialsProvider(credentialsProvider)
.build();
subscriptionAdminClient = SubscriptionAdminClient.create(SubscriptionAdminSettings.newBuilder()
.setCredentialsProvider(credentialsProvider)
.setTransportChannelProvider(channelProvider)
.build());
subscriberStub = GrpcSubscriberStub.create(SubscriberStubSettings.newBuilder()
.setTransportChannelProvider(channelProvider)
.setCredentialsProvider(credentialsProvider)
.build());
subscriptionAdminClient.createSubscription(subscriptionName, topicName,
PushConfig.getDefaultInstance(), 120);
subscriptionAdminClient.createSubscription(ProjectSubscriptionName.of(projectId, "test"), topicName,
PushConfig.getDefaultInstance(), 120);
}
@Test
public void test() {
PubsubMessage pubsubMessage = PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8("Message")).build();
publisher.publish(pubsubMessage);
StringBuilder receivedMessage = new StringBuilder("");
TestPubSubMessageReceiver receiver = new TestPubSubMessageReceiver(receivedMessage);
Thread t = new Thread() {
@Override
public void run() {
Subscriber subscriber = Subscriber.newBuilder(subscriptionName, receiver)
.setChannelProvider(channelProvider).
setCredentialsProvider(credentialsProvider).build();
subscriber.awaitRunning();
}
};
Executors.newSingleThreadExecutor().execute(t);
PullResponse pullResponse = null;
int messageCount = 0;
while (messageCount == 0) {
PullRequest pullRequest = PullRequest.newBuilder()
.setMaxMessages(1)
.setReturnImmediately(true) // return immediately if messages are not available
.setSubscription(testSubscriptionName.toString())
.build();
pullResponse = subscriberStub.pullCallable().call(pullRequest);
messageCount = pullResponse.getReceivedMessagesCount();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String testMessage = pullResponse.getReceivedMessages(0).getMessage().getData().toStringUtf8();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Assert.assertEquals(testMessage, receivedMessage);
}
@AfterClass
public static void delete() throws IOException {
topicAdmin.deleteTopic(topicName);
subscriptionAdminClient.deleteSubscription(subscriptionName);
subscriptionAdminClient.deleteSubscription(testSubscriptionName);
channel.shutdownNow();
}
private class TestPubSubMessageReceiver implements MessageReceiver {
StringBuilder receivedMessage;
public TestPubSubMessageReceiver(StringBuilder receivedMessage) {
this.receivedMessage = receivedMessage;
}
@Override
public void receiveMessage(PubsubMessage pubsubMessage, AckReplyConsumer ackReplyConsumer) {
String message = pubsubMessage.getData().toStringUtf8();
log.info("Received : " + message);
receivedMessage.append(message);
}
}
}
消息已正确发布到主题,但是没有任何消息接收来接收Message方法。 我需要做的。
谢谢。
编辑1
我以调试模式运行程序。然后我有以下日志。
2020-07-08 21:15:29 DEBUG [grpc-nio-worker-ELG-1-3] i.g.n.s.i.g.netty.NettyClientHandler.log():214 - [id: 0x20545e3a, L:/127.0.0.1:10718 - R:/127.0.0.1:8085] OUTBOUND HEADERS: streamId=9 headers=GrpcHttp2OutboundHeaders[:authority: 127.0.0.1:8085, :path: /google.pubsub.v1.Subscriber/Pull, :method: POST, :scheme: http, content-type: application/grpc, te: trailers, user-agent: grpc-java-netty/1.28.1, grpc-accept-encoding: gzip, grpc-timeout: 24999280u] streamDependency=0 weight=16 exclusive=false padding=0 endStream=false
2020-07-08 21:15:29 DEBUG [grpc-nio-worker-ELG-1-3] i.g.n.s.i.g.netty.NettyClientHandler.log():214 - [id: 0x20545e3a, L:/127.0.0.1:10718 - R:/127.0.0.1:8085] OUTBOUND DATA: streamId=9 padding=0 endStream=true length=53 bytes=00000000300a2a70726f6a656374732f73746c2d63617264696f2d6465762f737562736372697074696f6e732f7465737410011801
2020-07-08 21:15:29 DEBUG [grpc-nio-worker-ELG-1-3] i.g.n.s.i.g.netty.NettyClientHandler.log():214 - [id: 0x20545e3a, L:/127.0.0.1:10718 - R:/127.0.0.1:8085] OUTBOUND HEADERS: streamId=11 headers=GrpcHttp2OutboundHeaders[:authority: 127.0.0.1:8085, :path: /google.pubsub.v1.Publisher/Publish, :method: POST, :scheme: http, content-type: application/grpc, te: trailers, user-agent: grpc-java-netty/1.28.1, grpc-accept-encoding: gzip, grpc-timeout: 4999823u] streamDependency=0 weight=16 exclusive=false padding=0 endStream=false
2020-07-08 21:15:29 DEBUG [grpc-nio-worker-ELG-1-3] i.g.n.s.i.g.netty.NettyClientHandler.log():214 - [id: 0x20545e3a, L:/127.0.0.1:10718 - R:/127.0.0.1:8085] OUTBOUND DATA: streamId=11 padding=0 endStream=true length=53
我也将异步订阅者和 PullRequest pullRequest = PullRequest.newBuilder()连接到同一订阅ID PullRequest ,没有收到任何消息。但是当他们连接到与同一主题相关的不同订阅ID时, PullRequest 会收到消息。是异步订阅者侦听消息,但没有收到回叫或其他任何东西吗?
编辑2
经过大量调试后,我发现这是操作系统相关的问题。我对以下操作系统配置进行了测试
经过大量调试,我发现此问题与操作系统有关。我尝试以下操作系统组合。
这意味着测试程序无法在Windows 10中运行,而是使用客户端凭据在GCP上运行。这是客户端库问题吗? Pubsub客户端版本:1.104.1
编辑3
仿真器登录Windows终端
pubsub-emulator.bat --host=localhost --port=8085
[pubsub] This is the Google Pub/Sub fake.
[pubsub] Implementation may be incomplete or differ from the real system.
[pubsub] Jul 09, 2020 11:50:31 PM com.google.cloud.pubsub.testing.v1.Main main
[pubsub] INFO: IAM integration is disabled. IAM policy methods and ACL checks are not supported
[pubsub] Jul 09, 2020 11:50:32 PM io.gapi.emulators.netty.NettyUtil applyJava7LongHostnameWorkaround
[pubsub] INFO: Unable to apply Java 7 long hostname workaround.
[pubsub] Jul 09, 2020 11:50:33 PM com.google.cloud.pubsub.testing.v1.Main main
[pubsub] INFO: Server started, listening on 8085
[pubsub] Jul 09, 2020 11:53:03 PM io.gapi.emulators.grpc.GrpcServer$3 operationComplete
[pubsub] INFO: Adding handler(s) to newly registered Channel.
[pubsub] Jul 09, 2020 11:53:03 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
[pubsub] INFO: Detected HTTP/2 connection.
[pubsub] Jul 09, 2020 11:53:05 PM io.gapi.emulators.grpc.GrpcServer$3 operationComplete
[pubsub] INFO: Adding handler(s) to newly registered Channel.
[pubsub] Jul 09, 2020 11:53:05 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
[pubsub] INFO: Detected HTTP/2 connection.
Linux终端日志也与此相同。
答案 0 :(得分:0)
您开始订阅的电话应该是subscriber.startAsync().awaitRunning()
,而不是subscriber.awaitRunning()
。请参见示例here。