HTTP request failing with EOFException - java

Using Jetty 9.4.10.v20180503, occasionally my HTTP client fails with the following error.
java.io.EOFException: HttpConnectionOverHTTP#571103e6(l:/192.168.1.100:27497 <-> r:api.kucoin.com/13.113.121.24:443,closed=false)=>HttpChannelOverHTTP#a423e61(exchange=HttpExchange#e7dbbf1 req=TERMINATED/null#null res=PENDING/null#null)[send=HttpSenderOverHTTP#4b7f345a(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator#61d4e46c{s=START}],recv=HttpReceiverOverHTTP#7a7e7f01(rsp=IDLE,failure=null)[HttpParser{s=CLOSED,0 of -1}]]<-DecryptedEndPoint#193ff18c{api.kucoin.com/13.113.121.24:443<->/192.168.1.100:27497,OPEN,fill=-,flush=-,to=22604/0}->HttpConnectionOverHTTP#571103e6(l:/192.168.1.100:27497 <-> r:api.kucoin.com/13.113.121.24:443,closed=false)=>HttpChannelOverHTTP#a423e61(exchange=HttpExchange#e7dbbf1 req=TERMINATED/null#null res=PENDING/null#null)[send=HttpSenderOverHTTP#4b7f345a(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator#61d4e46c{s=START}],recv=HttpReceiverOverHTTP#7a7e7f01(rsp=IDLE,failure=null)[HttpParser{s=CLOSED,0 of -1}]]->SocketChannelEndPoint#2b50cb15{api.kucoin.com/13.113.121.24:443<->/192.168.1.100:27497,ISHUT,fill=-,flush=-,to=21603/0}{io=0/0,kio=0,kro=1}->SslConnection#6de1ad97{NEED_WRAP,eio=-1/-1,di=-1}=>HttpConnectionOverHTTP#571103e6(l:/192.168.1.100:27497 <-> r:api.kucoin.com/13.113.121.24:443,closed=false)=>HttpChannelOverHTTP#a423e61(exchange=HttpExchange#e7dbbf1 req=TERMINATED/null#null res=PENDING/null#null)[send=HttpSenderOverHTTP#4b7f345a(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator#61d4e46c{s=START}],recv=HttpReceiverOverHTTP#7a7e7f01(rsp=IDLE,failure=null)[HttpParser{s=CLOSED,0 of -1}]]
at java.util.concurrent.CompletableFuture.encodeRelay(CompletableFuture.java:326)
at java.util.concurrent.CompletableFuture.completeRelay(CompletableFuture.java:338)
at java.util.concurrent.CompletableFuture.uniRelay(CompletableFuture.java:911)
at java.util.concurrent.CompletableFuture$UniRelay.tryFire(CompletableFuture.java:899)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474)
at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1977)
at com.myapplication.ResponseListener.onComplete(ResponseListener.java:45)
at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:193)
at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:185)
at org.eclipse.jetty.client.HttpReceiver.terminateResponse(HttpReceiver.java:464)
at org.eclipse.jetty.client.HttpReceiver.abort(HttpReceiver.java:545)
at org.eclipse.jetty.client.HttpReceiver.responseFailure(HttpReceiver.java:436)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.failAndClose(HttpReceiverOverHTTP.java:369)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.earlyEOF(HttpReceiverOverHTTP.java:338)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1476)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.shutdown(HttpReceiverOverHTTP.java:209)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.process(HttpReceiverOverHTTP.java:147)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.receive(HttpReceiverOverHTTP.java:73)
at org.eclipse.jetty.client.http.HttpChannelOverHTTP.receive(HttpChannelOverHTTP.java:133)
at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.onFillable(HttpConnectionOverHTTP.java:155)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:291)
at org.eclipse.jetty.io.ssl.SslConnection$3.succeeded(SslConnection.java:151)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:760)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:678)
... 1 common frames omitted
Caused by: java.io.EOFException: HttpConnectionOverHTTP#571103e6(l:/192.168.1.100:27497 <-> r:api.kucoin.com/13.113.121.24:443,closed=false)=>HttpChannelOverHTTP#a423e61(exchange=HttpExchange#e7dbbf1 req=TERMINATED/null#null res=PENDING/null#null)[send=HttpSenderOverHTTP#4b7f345a(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator#61d4e46c{s=START}],recv=HttpReceiverOverHTTP#7a7e7f01(rsp=IDLE,failure=null)[HttpParser{s=CLOSED,0 of -1}]]<-DecryptedEndPoint#193ff18c{api.kucoin.com/13.113.121.24:443<->/192.168.1.100:27497,OPEN,fill=-,flush=-,to=22604/0}->HttpConnectionOverHTTP#571103e6(l:/192.168.1.100:27497 <-> r:api.kucoin.com/13.113.121.24:443,closed=false)=>HttpChannelOverHTTP#a423e61(exchange=HttpExchange#e7dbbf1 req=TERMINATED/null#null res=PENDING/null#null)[send=HttpSenderOverHTTP#4b7f345a(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator#61d4e46c{s=START}],recv=HttpReceiverOverHTTP#7a7e7f01(rsp=IDLE,failure=null)[HttpParser{s=CLOSED,0 of -1}]]->SocketChannelEndPoint#2b50cb15{api.kucoin.com/13.113.121.24:443<->/192.168.1.100:27497,ISHUT,fill=-,flush=-,to=21603/0}{io=0/0,kio=0,kro=1}->SslConnection#6de1ad97{NEED_WRAP,eio=-1/-1,di=-1}=>HttpConnectionOverHTTP#571103e6(l:/192.168.1.100:27497 <-> r:api.kucoin.com/13.113.121.24:443,closed=false)=>HttpChannelOverHTTP#a423e61(exchange=HttpExchange#e7dbbf1 req=TERMINATED/null#null res=PENDING/null#null)[send=HttpSenderOverHTTP#4b7f345a(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator#61d4e46c{s=START}],recv=HttpReceiverOverHTTP#7a7e7f01(rsp=IDLE,failure=null)[HttpParser{s=CLOSED,0 of -1}]]
I'm trying to understand how to interpret this error, specifically the EOFException which seems to list the steps of the transaction.
What is happening at each step?
At what step of the HTTP request does the error occur?
Did the client trigger a disconnect or the server?
Is it safe to automatically retry these kind of failures?

Related

Using keycloak api for a public client

Working on a project where there is a frontend (React) and a backend (Java/Quarkus). Keycloak is used as the auth tool. It is configured with a realm that has a public client on it. This allows the user to login via the browser and then make api requests to the backend with a bearer token attached to the request.
Running into a problem where we want to add users to our application. This means we also need to add them to keycloak. Doing this programatically, this is in its own mini module and it uses the keycloak-admin-client library.
I initiate the instance with
instance = KeycloakBuilder.builder()
.serverUrl(props.getProperty(PropertyConstants.SERVER_URL))
.realm(props.getProperty(PropertyConstants.REALM))
.grantType(OAuth2Constants.PASSWORD)
.clientId(props.getProperty(PropertyConstants.CLIENT_ID))
.username(props.getProperty(PropertyConstants.USERNAME))
.password(props.getProperty(PropertyConstants.PASSWORD))
.build();
realmResource = instance.realm(props.getProperty(PropertyConstants.REALM));
usersResource = realmResource.users();
UserRepresentation user = createUserRep();
Response response = usersResource.create(user);
The stacktrace is;
org.jboss.resteasy.spi.UnhandledException: javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: javax.ws.rs.ProcessingException: RESTEASY003215: could not find writer for content-type application/x-www-form-urlencoded type: javax.ws.rs.core.Form$1
at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:106)
at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:372)
at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:218)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:519)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)
at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:136)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:40)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:97)
at io.quarkus.runtime.CleanableExecutor$CleaningRunnable.run(CleanableExecutor.java:231)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2046)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1578)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at java.base/java.lang.Thread.run(Thread.java:829)
at org.jboss.threads.JBossThread.run(JBossThread.java:479)
Caused by: javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: javax.ws.rs.ProcessingException: RESTEASY003215: could not find writer for content-type application/x-www-form-urlencoded type: javax.ws.rs.core.Form$1
at org.jboss.resteasy.client.jaxrs.engines.ManualClosingApacheHttpClient43Engine.invoke(ManualClosingApacheHttpClient43Engine.java:287)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:488)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invokeSync(ClientInvoker.java:149)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:112)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
at com.sun.proxy.$Proxy89.grantToken(Unknown Source)
at org.keycloak.admin.client.token.TokenManager.grantToken(TokenManager.java:90)
at org.keycloak.admin.client.token.TokenManager.getAccessToken(TokenManager.java:70)
at org.keycloak.admin.client.token.TokenManager.getAccessTokenString(TokenManager.java:65)
at org.keycloak.admin.client.resource.BearerAuthFilter.filter(BearerAuthFilter.java:52)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.filterRequest(ClientInvocation.java:683)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:485)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invokeSync(ClientInvoker.java:149)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:112)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
at com.sun.proxy.$Proxy96.create(Unknown Source)
at com.demservices.KeycloakWrapper.addUser(KeycloakWrapper.java:56)
at com.demservices.services.UserService.addUser(UserService.java:27)
at com.demservices.services.UserService_Subclass.addUser$$superaccessor2(UserService_Subclass.zig:492)
at com.demservices.services.UserService_Subclass$$function$$2.apply(UserService_Subclass$$function$$2.zig:33)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:127)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:100)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.doIntercept(TransactionalInterceptorRequired.java:32)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.intercept(TransactionalInterceptorBase.java:53)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.intercept(TransactionalInterceptorRequired.java:26)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired_Bean.intercept(TransactionalInterceptorRequired_Bean.zig:340)
at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
at com.demservices.services.UserService_Subclass.addUser(UserService_Subclass.zig:440)
at com.demservices.services.UserService_ClientProxy.addUser(UserService_ClientProxy.zig:251)
at com.demservices.controllers.UserController.createNewUser(UserController.java:35)
at com.demservices.controllers.UserController_Subclass.createNewUser$$superaccessor1(UserController_Subclass.zig:234)
at com.demservices.controllers.UserController_Subclass$$function$$1.apply(UserController_Subclass$$function$$1.zig:33)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
at io.quarkus.hibernate.validator.runtime.interceptor.AbstractMethodValidationInterceptor.validateMethodInvocation(AbstractMethodValidationInterceptor.java:69)
at io.quarkus.hibernate.validator.runtime.jaxrs.JaxrsEndPointValidationInterceptor.validateMethodInvocation(JaxrsEndPointValidationInterceptor.java:35)
at io.quarkus.hibernate.validator.runtime.jaxrs.JaxrsEndPointValidationInterceptor_Bean.intercept(JaxrsEndPointValidationInterceptor_Bean.zig:392)
at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
at com.demservices.controllers.UserController_Subclass.createNewUser(UserController_Subclass.zig:191)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:170)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:643)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:507)
at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:457)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:459)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:419)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:393)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:68)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:492)
... 20 more
Caused by: javax.ws.rs.ProcessingException: RESTEASY003215: could not find writer for content-type application/x-www-form-urlencoded type: javax.ws.rs.core.Form$1
at org.jboss.resteasy.core.interception.jaxrs.ClientWriterInterceptorContext.throwWriterNotFoundException(ClientWriterInterceptorContext.java:50)
at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.getWriter(AbstractWriterInterceptorContext.java:302)
at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.syncProceed(AbstractWriterInterceptorContext.java:240)
at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:224)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.writeRequestBody(ClientInvocation.java:440)
at org.jboss.resteasy.client.jaxrs.engines.ManualClosingApacheHttpClient43Engine.writeRequestBodyToOutputStream(ManualClosingApacheHttpClient43Engine.java:589)
at org.jboss.resteasy.client.jaxrs.engines.ManualClosingApacheHttpClient43Engine.buildEntity(ManualClosingApacheHttpClient43Engine.java:548)
at org.jboss.resteasy.client.jaxrs.engines.ManualClosingApacheHttpClient43Engine.loadHttpMethod(ManualClosingApacheHttpClient43Engine.java:455)
at org.jboss.resteasy.client.jaxrs.engines.ManualClosingApacheHttpClient43Engine.invoke(ManualClosingApacheHttpClient43Engine.java:265)
... 77 more
I see in any example that a clientSecret is required but that is for confidential clients. I don't want this, I need the client to be public.
How can I have a public client while also being able to make API calls to it?

Why does the SocketTimeoutException error disappear after adding the expect: 100-continue request header

I encountered a SocketTimeoutException error while using the apache http client, but after adding request header expect: 100-continue, the request was successful. I repeat the request many times and the result is the same.
Here are my http request info:
Post method
Content-Type: application/json
Content-Length: 1277
my service type: spring-based web service
their service type: aps.net-based web service
Below is the error log:
java.net.SocketTimeoutException : Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:282)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:165)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
I know that after adding the request header expect: 100-continue, an http request will be sent before the real http request. But I can't understand why this header can solve my SocketTimeoutException error. Help me, thanks.
I've found very interesting your question. First time that I heard about such header Expect ... After read about it, using these links:
Expect Header
Continue-100 Response
Expect Headerpurpose/use
Expect header in ASP net
My conclusion is that aps.net-based web service is expecting such header ... if you don't send it, the service (or in this case, the application server), instead of sending a HTTP Error code, drops the established connection and you end getting a SocketTimeoutException when reading any response (NOTE: this is just speculative. Using other HTTP clients and network sniffers can clarify this more) ...

Problems with Camel DynamicEndpoint toD and Http-Component

I'm using Camel Version 3.7 with Java 11 (AdoptOpenJDK)
I'm trying gto make an http-call with dynamic timeout, passed by header
Map<String,Object> headerMap=new HashMap<>();
headerMap.put(Exchange.HTTP_URI, "http://myserver.example.com");
headerMap.put("timeout", 5000);
main.getCamelTemplate().sendBodyAndHeaders("direct:test_http_dynamic",null,headerMap);
the endpoint looks like this:
from("direct:test_http_dynamic")
.toD("http:test.dyn?socketTimeout=${in.header.timeout}");
This leads to this Stacktrace:
org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: http://http:test.dyn due to: Failed to resolve endpoint: http://http:test.dyn due to: The uri part is not configured correctly. You have duplicated the http(s) protocol.
at org.apache.camel.impl.engine.AbstractCamelContext.doGetEndpoint(AbstractCamelContext.java:912) ~[camel-base-engine-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.AbstractCamelContext.getEndpoint(AbstractCamelContext.java:798) ~[camel-base-engine-3.7.0.jar:3.7.0]
at org.apache.camel.support.CamelContextHelper.getMandatoryEndpoint(CamelContextHelper.java:73) ~[camel-support-3.7.0.jar:3.7.0]
at org.apache.camel.support.ExchangeHelper.resolveEndpoint(ExchangeHelper.java:112) ~[camel-support-3.7.0.jar:3.7.0]
at org.apache.camel.support.ExchangeHelper.resolveEndpoint(ExchangeHelper.java:91) ~[camel-support-3.7.0.jar:3.7.0]
at org.apache.camel.processor.SendDynamicProcessor.resolveEndpoint(SendDynamicProcessor.java:294) ~[camel-core-processor-3.7.0.jar:3.7.0]
at org.apache.camel.processor.SendDynamicProcessor.process(SendDynamicProcessor.java:155) ~[camel-core-processor-3.7.0.jar:3.7.0]
at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.run(RedeliveryErrorHandler.java:395) [camel-core-processor-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:148) [camel-base-engine-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:60) [camel-base-engine-3.7.0.jar:3.7.0]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:147) [camel-core-processor-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:312) [camel-base-engine-3.7.0.jar:3.7.0]
at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:84) [camel-direct-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.SharedCamelInternalProcessor.process(SharedCamelInternalProcessor.java:218) [camel-base-engine-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.SharedCamelInternalProcessor$1.process(SharedCamelInternalProcessor.java:112) [camel-base-engine-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.DefaultAsyncProcessorAwaitManager.process(DefaultAsyncProcessorAwaitManager.java:83) [camel-base-engine-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.SharedCamelInternalProcessor.process(SharedCamelInternalProcessor.java:109) [camel-base-engine-3.7.0.jar:3.7.0]
at org.apache.camel.support.cache.DefaultProducerCache.send(DefaultProducerCache.java:189) [camel-support-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.DefaultProducerTemplate.send(DefaultProducerTemplate.java:176) [camel-base-engine-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.DefaultProducerTemplate.send(DefaultProducerTemplate.java:172) [camel-base-engine-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.DefaultProducerTemplate.send(DefaultProducerTemplate.java:153) [camel-base-engine-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.DefaultProducerTemplate.sendBodyAndHeaders(DefaultProducerTemplate.java:311) [camel-base-engine-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.DefaultProducerTemplate.sendBodyAndHeaders(DefaultProducerTemplate.java:305) [camel-base-engine-3.7.0.jar:3.7.0]
at de.falschefreunde.camelhttptest.App$2.run(App.java:42) [classes/:?]
at java.lang.Thread.run(Thread.java:834) [?:?]
Caused by: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: http://http:test.dyn due to: The uri part is not configured correctly. You have duplicated the http(s) protocol.
at org.apache.camel.component.http.HttpComponent.createEndpoint(HttpComponent.java:298) ~[camel-http-3.7.0.jar:3.7.0]
at org.apache.camel.support.DefaultComponent.createEndpoint(DefaultComponent.java:170) ~[camel-support-3.7.0.jar:3.7.0]
at org.apache.camel.impl.engine.AbstractCamelContext.doGetEndpoint(AbstractCamelContext.java:878) ~[camel-base-engine-3.7.0.jar:3.7.0]
... 24 more``
It runs in Camel-Version 3.4 and 3.5. But not in 3.6 and 3.7
Am I doing something wrong? Did Interface change? I didn't find anything in the documentation.
===
Update 1 / Workaround(?) :
seems that HttpSendDynamicAware mixes something up with the URI. Turning off the Optimizer does the trick:
from("direct:test_http_dynamic")
.toD().allowOptimisedComponents(false).cacheSize(10).uri("http:test.dyn?socketTimeout=${in.header.timeout}");
===
Update 2
Seems to be a bug since Version 3.6.0
Jira-Ticket created
https://issues.apache.org/jira/browse/CAMEL-16216
In discussion I found out the unerlying optimizer is build for dynamic context-path and query-parameters. Not for dynamic timeouts.
(read comments https://issues.apache.org/jira/browse/CAMEL-16216 )
If you want to have dynamic timeouts - you have to turn the optimzer off
from("direct:test_http_dynamic_no_optimzer")
.toD().allowOptimisedComponents(false).cacheSize(10).uri("http:test.dyn?socketTimeout=${in.header.timeout}");
But be aware that each call with different timeout will create a new http-client.

How to avoid "org.apache.http.NoHttpResponseException" when writing to s3

Working in spark (2.11) over s3 (java, spark standalone)
I get org.apache.http.NoHttpResponseException: my-bucket.s3.amazonaws.com:443 failed to respond
when trying to call
the rdd is big (~20m records)
I have the following code -
myRdd.saveAsTextFile(myDir);
and When running it, I have 2 problems -
1) If it works, it's very slow
2) About ~10% of the times I call it, I get the exception
2019-02-18 18:51:42,820 [my-app] [s3a-transfer-shared--pool9-t331] INFO com.amazonaws.http.AmazonHttpClient- Unable to execute HTTP request: my-bucket.s3.amazonaws.com:443 failed to respond
org.apache.http.NoHttpResponseException: my-bucket.s3.amazonaws.com:443 failed to respond
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:143)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:261)
at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:283)
at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:259)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader(ManagedClientConnectionImpl.java:209)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272)
at com.amazonaws.http.protocol.SdkHttpRequestExecutor.doReceiveResponse(SdkHttpRequestExecutor.java:66)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124)
at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:686)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:488)
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:884)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:384)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:232)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3528)
at com.amazonaws.services.s3.AmazonS3Client.copyObject(AmazonS3Client.java:1507)
at com.amazonaws.services.s3.transfer.internal.CopyCallable.copyInOneChunk(CopyCallable.java:143)
at com.amazonaws.services.s3.transfer.internal.CopyCallable.call(CopyCallable.java:131)
at com.amazonaws.services.s3.transfer.internal.CopyMonitor.copy(CopyMonitor.java:189)
at com.amazonaws.services.s3.transfer.internal.CopyMonitor.call(CopyMonitor.java:134)
at com.amazonaws.services.s3.transfer.internal.CopyMonitor.call(CopyMonitor.java:46)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Any idea how can I resolve it?
thanks, nizan

SSL Exceptions Seemingly caused by Apache Axis2

So my question is this: does axis2 create / override a global SSL factory that would impact other parts of a project that are communicating without using axis2?
I have a method making http calls out to an external page using org.apache.commons.httpclient.HttpClient (Below). It works. I send things out, and get responses back, everything is awesome.
PostMethod method = new PostMethod(url);
method.addRequestHeader("Content-Type", "application/json");
method.addRequestHeader("Authorization", "Bearer "+accessToken);
method.setRequestEntity(new StringRequestEntity(requestAsString, "application/json", "UTF-8"));
HttpClient client = new HttpClient();
client.getHttpConnectionManager().getParams().setSoTimeout(timeout);
int rCode = client.executeMethod(method);
I also have database connections using com.microsoft.sqlserver.jdbc. It works. Everything is still awesome.
The problems start with another service within the same project that uses axis2 (org.apache.axis2-1.6.2). After I attempt any communication using the axis 2 stub both the jdbc connection and the HttpClient connection both begin failing (The errors are below). Everything works fine up until axis2 gets involved.
I know axis2 is based on commons-httpclient-3.1 so the impact to the HttpClient piece isn't entirely unexpected but I cannot for the life of me figure out why I am seeing this behavior.
My assumption is that axis2 is setting some sort of global variable that is impacting ssl connections but having read the documentation and stepped through the source code, I can't find that happening anywhere.
The HttpClient error:
Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1917)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1874)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1857)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1783)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:128)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at java.io.FilterOutputStream.flush(FilterOutputStream.java:140)
at org.apache.commons.httpclient.methods.StringRequestEntity.writeRequest(StringRequestEntity.java:146)
at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
... 10 more
Caused by: java.lang.RuntimeException: Could not generate DH keypair
at sun.security.ssl.ECDHCrypt.<init>(ECDHCrypt.java:79)
at sun.security.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:696)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:277)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:936)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:871)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1043)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:728)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
... 16 more
Caused by: java.security.InvalidAlgorithmParameterException: parameter object not a ECParameterSpec
at org.bouncycastle.jce.provider.JDKKeyPairGenerator$EC.initialize(JDKKeyPairGenerator.java:345)
at sun.security.ssl.ECDHCrypt.<init>(ECDHCrypt.java:74)
... 24 more
The jdbc error:
ERROR 13:27:33,321 [Thread-24] PID- M- TID- DAConnectionMgr_MSSQL -DB connection unavaliable to [master] as [Dev_User] failed on attempt [2], will automatically retry
com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "SQL Server returned an incomplete response. The connection has been closed. ClientConnectionId:a67d09bf-be47-4910-9d8c-fd040468a1cb".
at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1667)
at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1668)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1323)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:991)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:827)
at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1012)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at com.company.util.da.DAConnectionMgr_MSSQL.getConnection(DAConnectionMgr_MSSQL.java:299)
at com.company.baseserver.da.payments.product.productSSQL.openConnection(Product10DAMSSQL.java:499)
at com.company.baseserver.payments.product.ProductProcessor.process(ProductPaymentProcessor.java:988)
at com.company.baseserver.message.ProjectFunction.process(ProjectFunction.java:108)
at com.company.base.ClientProcessor.run(ClientProcessor.java:93)
at com.company.util.thread.PooledExecutor$Worker.run(PooledExecutor.java:774)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: SQL Server returned an incomplete response. The connection has been closed. ClientConnectionId:a67d09bf-be47-4910-9d8c-fd040468a1cb
at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.ensureSSLPayload(IOBuffer.java:651)
at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.readInternal(IOBuffer.java:708)
at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.read(IOBuffer.java:700)
at com.microsoft.sqlserver.jdbc.TDSChannel$ProxyInputStream.readInternal(IOBuffer.java:895)
at com.microsoft.sqlserver.jdbc.TDSChannel$ProxyInputStream.read(IOBuffer.java:883)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.read(InputRecord.java:503)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1371)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355)
at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1618)
... 13 more

Categories