Context
I'm implementing an integration application based on Apache Camel, which must interface to Google Pub/Sub infrastructure. For this purpose, I'm using the dedicated Camel PubSub component , which is based on the Google PubSub HTTP Service API
For development and test phases, I would like to use the PubSub Emulator, and make it available on a shared DEV environment so that the whole DEV team can access it.
Issue
When running the emulator on localhost, everything works fine: the REST HTTP API is available (e.g. to create topics and subscriptions), and Camel route is consuming messages properly.
gcloud beta emulators pubsub start --host-port=localhost:8085
API Call result ( topic creation):
$ curl -X PUT -v http://localhost:8085/v1/projects/test-project/topics/topic-data
HTTP/1.1 200 OK
content-type: application/json
{ "name": "projects/test-project/topics/topic-data"}
But as soon as I start Emulator with -host
parameter different than localhost
(e.g. using my main IP address), the REST API does not work anymore and always return 503 UNAVAILABLE
:
gcloud beta emulators pubsub start --host-port=[MY_IP_ADDRESS]:8085
Result when trying to create topic :
$ curl -X PUT -v http://[MY_IP_ADDRESS]:8085/v1/projects/test-project/topics/topic-data
HTTP/1.1 503 Service Unavailable
content-type: application/json
{"error":{"code":503,"message":"io exception","status":"UNAVAILABLE"}}
I have changed the emulator log level to FINEST, but nothing in logs can explain this behavior:
INFOS: Server started, listening on 8085
aout 16, 2019 11:43:51 AM io.netty.buffer.AbstractByteBuf <clinit>
PRECIS: -Dio.netty.buffer.checkAccessible: true
aout 16, 2019 11:43:51 AM io.netty.buffer.AbstractByteBuf <clinit>
PRECIS: -Dio.netty.buffer.checkBounds: true
aout 16, 2019 11:43:51 AM io.netty.util.ResourceLeakDetectorFactory$DefaultResourceLeakDetectorFactory newResourceLeakDetector
PRECIS: Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@280b84c6
aout 16, 2019 11:43:51 AM io.gapi.emulators.grpc.GrpcServer$3 operationComplete
INFOS: Adding handler(s) to newly registered Channel.
aout 16, 2019 11:43:51 AM io.netty.handler.logging.LoggingHandler channelRegistered
PRECIS: [id: 0x369f8b68, L:/a.b.c.d:8085 - R:/a.b.c.d:49246] REGISTERED
aout 16, 2019 11:43:51 AM io.netty.handler.logging.LoggingHandler channelActive
PRECIS: [id: 0x369f8b68, L:/a.b.c.d:8085 - R:/a.b.c.d:49246] ACTIVE
aout 16, 2019 11:43:51 AM io.netty.util.Recycler <clinit>
PRECIS: -Dio.netty.recycler.maxCapacityPerThread: 4096
aout 16, 2019 11:43:51 AM io.netty.util.Recycler <clinit>
PRECIS: -Dio.netty.recycler.maxSharedCapacityFactor: 2
aout 16, 2019 11:43:51 AM io.netty.util.Recycler <clinit>
PRECIS: -Dio.netty.recycler.linkCapacity: 16
aout 16, 2019 11:43:51 AM io.netty.util.Recycler <clinit>
PRECIS: -Dio.netty.recycler.ratio: 8
aout 16, 2019 11:43:51 AM io.netty.handler.logging.LoggingHandler channelRead
PRECIS: [id: 0x369f8b68, L:/a.b.c.d:8085 - R:/a.b.c.d:49246] READ: 285B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 50 55 54 20 2f 76 31 2f 70 72 6f 6a 65 63 74 73 |PUT /v1/projects|
|00000010| 2f 74 65 73 74 2d 70 72 6f 6a 65 63 74 2f 74 6f |/test-project/to|
|00000020| 70 69 63 73 2f 74 6f 70 69 63 2d 64 61 74 61 20 |pics/topic-data |
|00000030| 48 54 54 50 2f 31 2e 31 0d 0a 55 73 65 72 2d 41 |HTTP/1.1..User-A|
|00000040| 67 65 6e 74 3a 20 50 6f 73 74 6d 61 6e 52 75 6e |gent: PostmanRun|
|00000050| 74 69 6d 65 2f 37 2e 31 35 2e 32 0d 0a 41 63 63 |time/7.15.2..Acc|
|00000060| 65 70 74 3a 20 2a 2f 2a 0d 0a 43 61 63 68 65 2d |ept: */*..Cache-|
|00000070| 43 6f 6e 74 72 6f 6c 3a 20 6e 6f 2d 63 61 63 68 |Control: no-cach|
|00000080| 65 0d 0a 50 6f 73 74 6d 61 6e 2d 54 6f 6b 65 6e |e..Postman-Token|
|00000090| 3a 20 66 31 61 38 33 63 35 36 2d 36 66 38 66 2d |: f1a83c56-6f8f-|
|000000a0| 34 65 35 32 2d 38 64 35 35 2d 64 64 66 66 64 37 |4e52-8d55-ddffd7|
|000000b0| 37 38 66 64 36 65 0d 0a 48 6f 73 74 3a 20 31 30 |78fd6e..Host: a.|
|000000c0| 2e 32 2e 34 31 2e 31 39 32 3a 38 30 38 35 0d 0a |.b.c.d:8085.....|
|000000d0| 41 63 63 65 70 74 2d 45 6e 63 6f 64 69 6e 67 3a |Accept-Encoding:|
|000000e0| 20 67 7a 69 70 2c 20 64 65 66 6c 61 74 65 0d 0a | gzip, deflate..|
|000000f0| 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 |Content-Length: |
|00000100| 30 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 6b |0..Connection: k|
|00000110| 65 65 70 2d 61 6c 69 76 65 0d 0a 0d 0a |eep-alive.... |
+--------+-------------------------------------------------+----------------+
aout 16, 2019 11:43:51 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFOS: Detected non-HTTP/2 connection.
aout 16, 2019 11:43:51 AM io.netty.handler.logging.LoggingHandler channelReadComplete
PRECIS: [id: 0x369f8b68, L:/a.b.c.d:8085 - R:/a.b.c.d:49246] READ COMPLETE
aout 16, 2019 11:43:51 AM io.grpc.Context createStorage
PRECIS: Storage override doesn't exist. Using default
java.lang.ClassNotFoundException: io.grpc.override.ContextStorageOverride
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at io.grpc.Context.createStorage(Context.java:137)
at io.grpc.Context.storage(Context.java:129)
at io.grpc.Context.current(Context.java:181)
at io.grpc.Context$Key.get(Context.java:891)
at io.grpc.internal.CensusTracingModule$TracingClientInterceptor.interceptCall(CensusTracingModule.java:385)
at io.grpc.ClientInterceptors$InterceptorChannel.newCall(ClientInterceptors.java:156)
at io.grpc.internal.CensusStatsModule$StatsClientInterceptor.interceptCall(CensusStatsModule.java:691)
at io.grpc.ClientInterceptors$InterceptorChannel.newCall(ClientInterceptors.java:156)
at io.grpc.internal.ManagedChannelImpl.newCall(ManagedChannelImpl.java:819)
at io.grpc.internal.ForwardingManagedChannel.newCall(ForwardingManagedChannel.java:63)
at io.grpc.stub.MetadataUtils$HeaderAttachingClientInterceptor.interceptCall(MetadataUtils.java:74)
at io.grpc.ClientInterceptors$InterceptorChannel.newCall(ClientInterceptors.java:156)
at com.google.pubsub.v1.PublisherGrpc$PublisherStub.createTopic(PublisherGrpc.java:673)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at io.gapi.emulators.grpc.ProtoReflectionUtil.invoke(ProtoReflectionUtil.java:159)
at io.gapi.emulators.grpc.HttpAdapter$UnaryMethodHandler.handle(HttpAdapter.java:531)
at io.gapi.emulators.grpc.HttpAdapter.handleRequest(HttpAdapter.java:165)
at io.gapi.emulators.netty.HttpHandler.channelRead(HttpHandler.java:52)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:323)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:297)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)
at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:38)
at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:350)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:495)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:905)
at java.lang.Thread.run(Thread.java:748)
aout 16, 2019 11:43:51 AM io.netty.handler.logging.LoggingHandler flush
PRECIS: [id: 0x369f8b68, L:/a.b.c.d:8085 - R:/a.b.c.d:49246] FLUSH
aout 16, 2019 11:43:51 AM io.grpc.internal.DnsNameResolver$Resolve resolveInternal
PRECIS: No TXT records found for localhost
aout 16, 2019 11:43:53 AM io.gapi.emulators.netty.HttpHandler$1 onError
INFOS: Exception when handling request: UNAVAILABLE: io exception
aout 16, 2019 11:43:53 AM io.netty.handler.logging.LoggingHandler write
PRECIS: [id: 0x369f8b68, L:/a.b.c.d:8085 - R:/a.b.c.d:49246] WRITE: 158B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 48 54 54 50 2f 31 2e 31 20 35 30 33 20 53 65 72 |HTTP/1.1 503 Ser|
|00000010| 76 69 63 65 20 55 6e 61 76 61 69 6c 61 62 6c 65 |vice Unavailable|
|00000020| 0d 0a 63 6f 6e 74 65 6e 74 2d 74 79 70 65 3a 20 |..content-type: |
|00000030| 61 70 70 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f 6e |application/json|
|00000040| 0d 0a 63 6f 6e 74 65 6e 74 2d 6c 65 6e 67 74 68 |..content-length|
|00000050| 3a 20 37 30 0d 0a 0d 0a 7b 22 65 72 72 6f 72 22 |: 70....{"error"|
|00000060| 3a 7b 22 63 6f 64 65 22 3a 35 30 33 2c 22 6d 65 |:{"code":503,"me|
|00000070| 73 73 61 67 65 22 3a 22 69 6f 20 65 78 63 65 70 |ssage":"io excep|
|00000080| 74 69 6f 6e 22 2c 22 73 74 61 74 75 73 22 3a 22 |tion","status":"|
|00000090| 55 4e 41 56 41 49 4c 41 42 4c 45 22 7d 7d |UNAVAILABLE"}} |
+--------+-------------------------------------------------+----------------+
aout 16, 2019 11:43:53 AM io.netty.handler.logging.LoggingHandler flush
PRECIS: [id: 0x369f8b68, L:/a.b.c.d:8085 - R:/a.b.c.d:49246] FLUSH
(note that message No TXT records found for localhost
is also present when running emulator on localhost, so I'm not sure if this can be the cause)
Note the gRPC API is working fine in both scenario (localhost and specific IP address) but unfortunately I cannot use this protocole as Camel PubSub component is not supporting it.