Handshake failed due to invalid Connection header [Keep-Alive] - websocket

I have a websocket project, develop it on Weblogic 12c and Spring MVC 5.1.0.RELEASE
When i running project on local tomcat, its working normally, but when trying to deploy on Weblogic, its gave below error. (Error only occurs with secure domain, when i tried to on http adress with ip its working good.)
Apr 09, 2021 2:28:57 PM org.springframework.web.socket.server.support.AbstractHandshakeHandler handleInvalidConnectHeader
SEVERE: Handshake failed due to invalid Connection header [Keep-Alive]
<Apr 9, 2021 2:28:57 PM GMT+03:00> <Error> <org.springframework.web.socket.server.support.DefaultHandshakeHandler> <BEA-000000> <Handshake failed due to invalid Connection header [Keep-Alive]>
My headers;
- Sec-WebSocket-Version : 13
- Sec-WebSocket-Key : MoTfrW6Iim1noQgYHlkeYQ==
- Upgrade : websocket
- Cookie : jwt=eyJhbGciO....
- Sec-WebSocket-Extensions : permessage-deflate; client_max_window_bits
- Host : infotest.infotech.com.tr
- ECID-Context : 1.005jsZwLhO_EoIWVLynJ8A0001Cy0000i2;kXjE
- Connection : Keep-Alive
- X-WebLogic-KeepAliveSecs : 30
- X-WebLogic-Force-JVMID : -414283189
- X-WebLogic-Request-ClusterInfo : true
My implementation something like;
#Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new EchoHandler(), "/echo").addInterceptors(customHandshakeInterceptor())
.setAllowedOrigins("*");
}
Testing with;
wscat -c ws://localhost:8080/projectName/echo --no-color
any help ?

you need to change the value for Connection header to 'Upgrade';

Related

jHipster Undertow request failed HttpServerExchange

i'm using jHipster for back-end admin dashboard application and i'm getting this error often that brings my server down every time it appears.
2019-12-26 10:30:29,516 ERROR [XNIO-2 task-10] WebsocketConfiguration$2: Handshake failed due to invalid Upgrade header: null
2019-12-26 10:38:46,039 ERROR [XNIO-2 I/O-1] request: UT005071: Undertow request failed HttpServerExchange{ CONNECT check.best-proxies.ru:80 request {Host=[check.best-proxies.ru:80]} response {}}
java.lang.IllegalArgumentException: UT000068: Servlet path match failed
at io.undertow.servlet.handlers.ServletPathMatchesData.getServletHandlerByPath(ServletPathMatchesData.java:83)
at io.undertow.servlet.handlers.ServletPathMatches.getServletHandlerByPath(ServletPathMatches.java:88)
at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:151)
at io.undertow.server.handlers.HttpContinueReadHandler.handleRequest(HttpContinueReadHandler.java:65)
at io.undertow.server.handlers.encoding.EncodingHandler.handleRequest(EncodingHandler.java:66)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:336)
at io.undertow.server.protocol.http.HttpReadListener.handleEventWithNoRunningRequest(HttpReadListener.java:255)
at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:136)
at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:59)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88)
at org.xnio.nio.WorkerThread.run(WorkerThread.java:561)
Since jHipster generates a lot of configuration, the only thing i could find about undertow is this method :
#Override
public void customize(ConfigurableEmbeddedServletContainer container) {
MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
// IE issue, see https://github.com/jhipster/generator-jhipster/pull/711
mappings.add("html", MediaType.TEXT_HTML_VALUE + ";charset=utf-8");
// CloudFoundry issue, see https://github.com/cloudfoundry/gorouter/issues/64
mappings.add("json", MediaType.TEXT_HTML_VALUE + ";charset=utf-8");
container.setMimeMappings(mappings);
// When running in an IDE or with ./mvnw spring-boot:run, set location of the static web assets.
setLocationForStaticAssets(container);
/*
* Enable HTTP/2 for Undertow - https://twitter.com/ankinson/status/829256167700492288
* HTTP/2 requires HTTPS, so HTTP requests will fallback to HTTP/1.1.
* See the JHipsterProperties class and your application-*.yml configuration files
* for more information.
*/
if (jHipsterProperties.getHttp().getVersion().equals(JHipsterProperties.Http.Version.V_2_0) &&
container instanceof UndertowEmbeddedServletContainerFactory) {
((UndertowEmbeddedServletContainerFactory) container)
.addBuilderCustomizers(builder ->
builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true));
}
}
Can anyone tell me where is the problem?
Thanks in advance!
It's the search crawler to get url not found,throw the error,you can write robots.txt to prohibit it on the root directory.

Need Spring Boot to redirect to https behind F5 BigIP SSL Proxy but listen on http

How do I continue to listen on port 80 (http) but send a 302 redirect to port 443 (https) in a Spring Boot app for the login page. I need this because my application is behind a F5 BigIP proxy that terminates the SSL certificate and sends http requests to my application and currently, I am seeing this behaviour:
This is the current flawed flow:
Client requests https://myapp.example.com
F5 BigIP translates to (HTTP)myapp.example.com
my Spring Boot application redirects to (HTTP)myapp.example.com/login as a 302 directive to the client
Client requests (HTTP)myapp.example.com/login
F5 BigIP rejects HTTP request
Wanted flow:
my Spring Boot application sends a redirect to (HTTPS)myapp.example.com/login as a 302 to the client (Location=(HTTPS)myapp.example.com/login)
F5 BigIP translates to (HTTP)myapp.example.com/login
my Spring boot application responds with the login page and everything is Honky Dory
I am using Spring Boot version 1.2.8 and my application is behind a F5 BigIp load balancer. The BigIP terminates the SSL certificate and redirects all HTTPS requests to the Spring Boot application listening ONLY on port 80 (http).
#Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/error", "/js/**", "/css/**", "/img/**", "/help", "/favicon.ico").permitAll()
.anyRequest().hasAuthority("USER")
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login-error")
.permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.logout()
.permitAll();
}
}
I followed the //docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-enable-https documentation adding:
These application.properties:
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
server.tomcat.internal-proxies=x\.x\.x\.x|x\.x\.x\.x (I tested without this parameter as well)
BTW: Forcing HTTPS with http.requiresChannel().anyRequest().requiresSecure(); does not work in this case, because I need the second request coming from the F5 BigIp on HTTP to work, using this setting would loop the whole redirecting dance.
I need to configure my app to redirect a client request https://myApp.example.com that is proxied by BigIP to http://myApp.example.com/
To https://myApp.example.com/login so the F5 BigIP accepts it.
This is the result from a curl request:
curl -L -b -vk --url https://myApp.example.com --verbose -vs > curl-output.txt 2>&1
STATE: INIT => CONNECT handle 0x440f160; line 1392 (connection #-5000)
* Rebuilt URL to: https://myApp.example.com/
* Added connection 0. The cache now contains 1 members
* STATE: CONNECT => WAITRESOLVE handle 0x440f160; line 1428 (connection #0)
* Trying XXX.XX.XX.XXX...
…
* SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x440f160; line 1596 (connection #0)
} [5 bytes data]
> GET / HTTP/1.1
> Host: myApp.example.com
> User-Agent: curl/7.58.0
> Accept: */*
…
< HTTP/1.1 302
…
< X-XSS-Protection: 1; mode=block
* Added cookie JSESSIONID="4CE1A6F2AB684C6E01774E5289AF2AC0" for domain myApp.example.com, path /, expire 0
< Set-Cookie: JSESSIONID=4CE1A6F2AB684C6E01774E5289AF2AC0;path=/;HttpOnly
****< Location: http://myApp.example.com/login <- this needs to be HTTPS****
< Date: Wed, 09 May 2018 22:30:36 GMT
…
* Connection #0 to host myApp.example.com left intact
* Issue another request to this URL: 'http://myApp.example.com/login' <- this needs to be HTTPS
* STATE: PERFORM => CONNECT handle 0x440f160; line 1949 (connection #-5000)
* Added connection 1. The cache now contains 2 members
* STATE: CONNECT => WAITRESOLVE handle 0x440f160; line 1428 (connection #1)
* Trying XXX.XX.XX.XXX...
* TCP_NODELAY set
* STATE: WAITRESOLVE => WAITCONNECT handle 0x440f160; line 1509 (connection #1)
* connect to XXX.XX.XX.XXX port 80 failed: Connection refused
* Failed to connect to myApp.example.com port 80: Connection refused<= Not the result we want
* Closing connection 1
This problem was never solved on the server side. The systems engineer in charge of the BIG IP changed some configuration settings and now, it's working like they want it to work. I have not asked yet how the Big-IP configuration works. I will post something, if possible, when I find out.

Feign Client: How to log the server name which the request was sent to?

I am using a Feign Client to call a REST endpoint with success, and have logging turned on to FULL. This is helpfully shows me the request sent and the response received. However, I cannot see which server the request was sent to. It only shows me that it was POSTed to http://foo-service which is the name of the service, not the name of the server.
How can I log which server name this request was sent to?
This is what I see in the logs:
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar] ---> POST http://foo-service/some-endoint HTTP/1.1
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar] Accept: application/json
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar] Content-Type: application/json
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar] Content-Length: 15
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar]
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar] {"name":"John"}
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar] ---> END HTTP (15-byte body)
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar] <--- HTTP/1.1 200 (8ms)
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar] Transfer-Encoding: chunked
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar] X-Application-Context: fooService:9006
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar] Date: Tue, 10 Oct 2017 09:25:36 GMT
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar] Content-Type: application/json;charset=UTF-8
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar]
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar] {"result":"Hello John"}
c.l.l.r.service.FooFeignClient : [FooFeignClient#bar] <--- END HTTP (23-byte body)
To turn on logging, I declare this bean:
#Bean
public feign.Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
We are using spring-cloud-netflix-core:1.1.0.M4
You will need to provide your own Logger to achieve this. The default Logger is very simple and logs the host before the request is sent. When using Ribbon the information will be available with the Response. If you override the logAndRebufferResponse method, the response.url property will be the entire url submitted, including host name.
protected Response logAndRebufferResponse(
String configKey,
Level logLevel,
Response response,
long elapsedTime) throws IOException {
/* ask the response for the request and log the uri */
log(response.request.url());
}
Enable logging via logback and set log level of debug or these classes
<logger name="com.netflix.loadbalancer.BaseLoadBalancer" level="DEBUG"/>
<logger name="com.netflix.loadbalancer.LoadBalancerContext" level="DEBUG"/>
<logger name="com.netflix.loadbalancer.reactive.LoadBalancerCommand" level="DEBUG"/>
I can see where each request is going (server:port) and request failed on which server
DEBUG [ c.a.m.c.f.CommonProducerClient][72] - [CommonProducerClient#findAllEmployee] ---> GET http://COMMON-PRODUCER/allemployee HTTP/1.1
DEBUG [ c.n.loadbalancer.LoadBalancerContext][492] - COMMON-PRODUCER using LB returned Server: localhost:7001 for request http:///allemployee
DEBUG [ c.n.l.reactive.LoadBalancerCommand][314] - Got error java.net.ConnectException: Connection refused: connect when executed on server localhost:7001
DEBUG [ c.n.l.reactive.LoadBalancerCommand][314] - Got error java.net.ConnectException: Connection refused: connect when executed on server localhost:7001
DEBUG [ c.n.l.reactive.LoadBalancerCommand][314] - Got error java.net.ConnectException: Connection refused: connect when executed on server localhost:7001
DEBUG [ c.n.loadbalancer.LoadBalancerContext][492] - COMMON-PRODUCER using LB returned Server: localhost:7003 for request http:///allemployee
DEBUG [ c.a.m.c.f.CommonProducerClient][72] - [CommonProducerClient#findAllEmployee] <--- HTTP/1.1 200 (4010ms)
From Logs its clear, first request went to port 7001, connection refused there, second request goes to 7003, all good there.

Apache Cayenne ROP Server "No session associated with request." on Tomcat 7

I develop a cayenne project with a java rich client and an remote obejct persistence server. If i the rich cient connects with a Cayenne-ROP-Server that is deployed on the same machine on localhost (on Jetty from maven goal like explained inside the cayenne rop tutorial) everythings fine:
ClientConnection clientConnection = new HessianConnection("http://localhost:8080/rop.server /cayenne-service",
"cayenne-user", "secret", SHARED_CAYENNE_SESSION_NAME);
DataChannel channel = new ClientChannel(clientConnection);
ObjectContext context = new CayenneContext(channel);
List<Object> someEntities = context.performQuery(allMovies);
If i change the url that i want to connect to in the first line to a non local host (Tomcat7 on ubuntu) then everything works till it comes to the 4th line:
List<Object> someEntities = context.performQuery(allMovies);
Then i get the Error "No session associated with request"
Here is the full Output of the Client:
Running de.pss.hdlist.client.dataservice.MovieDataServiceCayenneImplTest
Sep 07, 2012 10:21:37 AM org.apache.cayenne.remote.hessian.HessianConnection connect
INFO: Connecting to [cayenne-user:*******#http://comunity-server.hopto.org:8080 /rop.server-3.0.2/cayenne-service] - shared session 'global-cayenne-session'
Sep 07, 2012 10:21:40 AM org.apache.cayenne.remote.hessian.HessianConnection connect
INFO: === Connected, session: org.apache.cayenne.remote.RemoteSession#12241e[sessionId=C47DD36ACE2A043401C8D0C44D5BD8C3,n ame=global-cayenne-session] - took 3182 ms.
Sep 07, 2012 10:21:53 AM org.apache.cayenne.remote.BaseConnection sendMessage
INFO: --- Message 0: Bootstrap
Sep 07, 2012 10:21:53 AM org.apache.cayenne.remote.BaseConnection sendMessage
INFO: === Message 0: Bootstrap done - took 406 ms.
Sep 07, 2012 10:21:53 AM org.apache.cayenne.remote.BaseConnection sendMessage
INFO: --- Message 1: Query
Sep 07, 2012 10:21:53 AM org.apache.cayenne.remote.BaseConnection sendMessage
INFO: *** Message error for 1: Query - took 187 ms.
Here is the Serverside output of the Apache Tomcat log:
WARNING: org.apache.cayenne.remote.service.MissingSessionException: [v.3.0.2 Jun 19 2011 09:29:50] No session associated with request.
org.apache.cayenne.remote.service.MissingSessionException: [v.3.0.2 Jun 19 2011 09:29:50] No session associated with request.
at org.apache.cayenne.remote.service.BaseRemoteService.processMessage(BaseRemoteService.java:148)
at sun.reflect.GeneratedMethodAccessor39.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:180)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:109)
at com.caucho.hessian.server.HessianServlet.service(HessianServlet.java:396)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:581)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:679)
I use Apache Cayenne 3.0.2, Apache-Tomcat 7.0.29 and Java 7 sdk
THX in advance for every Help
PS. Maybe the local Jetty server handles things in another way as the Tomcat Server on remote unix machine.
Edit:
After the hint given by Andrus in the answer below i added an SessionListern that looks like this:
public class HttpSessionListenerLogImpl implements HttpSessionListener {
private final static Logger LOGGER = Logger.getLogger(HttpSessionListenerLogImpl.class.getName());
#Override
public void sessionCreated(HttpSessionEvent hse) {
LOGGER.log(Level.SEVERE,
"!__Session created with ID: " + hse.getSession().getId());
LOGGER.log(Level.SEVERE, "!__Session created by: " + hse.getSource());
LOGGER.log(Level.SEVERE, "!__Session Attributes: " + hse.getSession().getAttributeNames());
LOGGER.log(Level.SEVERE, "!__Session max inactivity: " + hse.getSession().getMaxInactiveInterval());
LOGGER.log(Level.SEVERE, "!__Session context: " + hse.getSession().getServletContext().getServletContextName());
}
#Override
public void sessionDestroyed(HttpSessionEvent hse) {
LOGGER.log(Level.SEVERE, "!__Session killed with ID: " + hse.getSession().getId());
LOGGER.log(Level.SEVERE, "!__Session killed by: " + hse.getSource());
LOGGER.log(Level.SEVERE, "!__Session Attributes: " + hse.getSession().getAttributeNames());
LOGGER.log(Level.SEVERE, "!__Session max inactivity: " + hse.getSession().getMaxInactiveInterval());
LOGGER.log(Level.SEVERE, "!__Session context: " + hse.getSession().getServletContext().getServletContextName());
}
So this listern gives me the following output when executing the 4 lines of code statet on top of this Question:
Sep 11, 2012 11:06:27 AM de.pss.hdlist.HttpSessionListenerLogImpl sessionCreated
SEVERE: !__Session created with ID: B07648A2A5F0005AF6DF0741D7EF2D21
Sep 11, 2012 11:06:27 AM de.pss.hdlist.HttpSessionListenerLogImpl sessionCreated
SEVERE: !__Session created by: org.apache.catalina.session.StandardSessionFacade#515f9553
Sep 11, 2012 11:06:27 AM de.pss.hdlist.HttpSessionListenerLogImpl sessionCreated
SEVERE: !__Session Attributes: java.util.Collections$2#5a44a5e1
Sep 11, 2012 11:06:27 AM de.pss.hdlist.HttpSessionListenerLogImpl sessionCreated
SEVERE: !__Session max inactivity: 216000
Sep 11, 2012 11:06:27 AM de.pss.hdlist.HttpSessionListenerLogImpl sessionCreated
SEVERE: !__Session context: Cayenne Tutorial
Sep 11, 2012 11:06:27 AM com.caucho.hessian.server.HessianSkeleton invoke
WARNING: org.apache.cayenne.remote.service.MissingSessionException: [v.3.0.2 Jun 19 2011 09:29:50] No session associated with request.
org.apache.cayenne.remote.service.MissingSessionException: [v.3.0.2 Jun 19 2011 09:29:50] No session associated with request.
at org.apache.cayenne.remote.service.BaseRemoteService.processMessage(BaseRemoteService.java:148)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:180)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:109)
at com.caucho.hessian.server.HessianServlet.service(HessianServlet.java:396)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:581)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:679)
Here you can see there is a session that gets created and there is no session that gets killed. So why does the ObjectContext from my line of code
List<Object> someEntities = context.performQuery(allMovies);
does ignore the session. Do i have to set it explicitly before doing a query? What is the standard initializing code on the client side to access an remotly deployed cayenne server. Does it differ from the one given inside the cayenne rop tutorial?
THX in advance.
Edit:
I upgraded to cayenne 3.1B1 hoping to get rid of this error, but same Situation here: "No session..." when trying to send a query.
I also setup a tomcat on localhost and configured it the same as the remote is. Same Problem here "No Session..." when trying to send a query.
So the Jetty on localhost is the only one that takes the 4 line init code from above and holds the session for every following query. So here is my Question. Does anyone on this planet ever tried to deploy a cayenne rop server on a tomcat and succeeded?
THX in advance for every little hint.
Edit:
So i did a litte bit of server side debugging on my local tomcat7.
1.Client executes line 2 of code from above:
DataChannel channel = new ClientChannel(clientConnection);
on the Serverside my session listener gets triggerd and tells me a session has been created with id: B6565298F222294F601B76333DBE4911
2.Client executes line 3 from above:
ObjectContext context = new CayenneContext(channel);
On the server side the method of class org.apache.cayenne.remote.service.HttpRemoteSession gets called:
/**
* Returns a ServerSession object that represents Cayenne-related state associated
* with the current session. If ServerSession hasn't been previously saved, returns
* null.
*/
#Override
protected ServerSession getServerSession() {
HttpSession httpSession = getSession(true);
return (ServerSession) httpSession.getAttribute(SESSION_ATTRIBUTE);
}
a new session gets created by line one of this method. Its ID is: ECC4A81D6240A1D04DA0A646200C4CE6. This new Session contains exactly one attribute: the key is "org.apache.cayenne.remote.service.HttpRemoteService.ServerSession" and the value is (who guessed it?) the session created before in step 1
What makes me wonder is that my serveltListener dont gets triggerd though a new session gets created.
3.Client executes line 4 from above
List<Object> someEntities = context.performQuery(allMovies);
at the serverside now the getServerSession() method is called again. This time also a new session gets created (why?). And this session does not contain any attribute. So the line "return (ServerSession) httpSession.getAttribute(SESSION_ATTRIBUTE);" inside the method getServerSession() returns null and exactly this triggers the exception "No Session associated with request".
So why is the cayenne serverside creating e ne session and doesnt use the old one created befor? Do i have to explicitly send the session within the query?
Edit:
I made screenshots from the netbeans http-monitor while running the four lines of code from above:
This is an issue between Cayenne ROP and newer containers:
https://issues.apache.org/jira/browse/CAY-1739
Here is a Tomcat solution - create context.xml file with the following contents, and place it in META-INF/ of your webapp:
<Context>
<Valve className="org.apache.catalina.authenticator.BasicAuthenticator"
changeSessionIdOnAuthentication="false" />
</Context>

Disconnecting Atmosphere sockets in Grails

I'm writing a Grails application which uses Atmosphere plugin. The connection works but every time I update the page in a browser I see that my web server adds a new Daemon thread which is never released afterwards.
After the thread count reaches 200 the web server freezes.
There seems to be no documentation explaining what is exactly the right way to handle the resources (disconnect) with the Atmosphere plugin?
My client code does this:
var connectedEndpoint = null;
$(function()
{
function callback(response)
{
if (response.transport != 'polling' && response.state != 'connected' && response.state != 'closed') {
if (response.status == 200) {
eval(response.responseBody);
}
}
}
$.atmosphere.subscribe('${resource(dir: '/atmosphere/channel')}', callback, $.atmosphere.request = {transport: 'streaming'});
connectedEndpoint = $.atmosphere.response;
});
$(window).unload( function ()
{
$.atmosphere.unsubscribe();
connectedEndpoint = null;
});
I use an atmosphere handler on the server side;
package demo
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import org.atmosphere.cpr.AtmosphereHandler
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResourceEvent;
class DemoController implements AtmosphereHandler<HttpServletRequest, HttpServletResponse> {
#Override
public void destroy() {
println "destroy"
}
#Override
public void onRequest( AtmosphereResource<HttpServletRequest, HttpServletResponse> event) throws IOException
{
event.suspend()
}
#Override
public void onStateChange( AtmosphereResourceEvent<HttpServletRequest, HttpServletResponse> event) throws IOException
{
if (event.isSuspended())
{
event.resource.response.writer.with {
def message = event.message
write "set${message.paramName}(\"${message.id}\",\"${message.value}\");"
flush()
}
}
}
}
The destroy function of the handler is never called!
The next picture shows that I have 23 threads running. When I start my application there are about 6 of them and they are added every time I press F5! If I disable atmosphere new threads are not added so this problem is related to the Atmosphere. (I am using SpringSource Tools Suite on Windows7).
If the solution is not trivial I would appreciate detailed step-by step instructions or an example.
UPDATE: After deployment in Tomcat I have the following errors each 20 seconds:
Apr 02, 2012 2:35:15 PM org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deploying configuration descriptor host-manager.xml
Apr 02, 2012 2:35:16 PM org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deploying configuration descriptor manager.xml
Apr 02, 2012 2:35:16 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory docs
Apr 02, 2012 2:35:16 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory examples
Apr 02, 2012 2:35:17 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory ROOT
Apr 02, 2012 2:35:17 PM org.apache.coyote.http11.Http11AprProtocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Apr 02, 2012 2:35:17 PM org.apache.coyote.ajp.AjpAprProtocol start
INFO: Starting Coyote AJP/1.3 on ajp-8009
Apr 02, 2012 2:35:17 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 11401 ms
2012-04-02 14:41:17,122 [http-8080-39] ERROR cpr.AsynchronousProcessor - failed
to timeout resource AtmosphereResourceImpl{, hasCode-1035775543,
action=org.atmosphere.cpr.AtmosphereServlet$Action#f2718e,
broadcaster=org.atmosphere.cpr.DefaultBroadcaster,
cometSupport=org.atmosphere.container.TomcatCometSupport#107fff7,
serializer=null,
isInScope=true,
useWriter=true,
listeners=[]}
2012-04-02 14:42:15,034 [http-8080-69] ERROR cpr.AsynchronousProcessor - failed
to timeout resource AtmosphereResourceImpl{, hasCode-58082012,
action=org.atmosphere.cpr.AtmosphereServlet$Action#ae4dd4,
broadcaster=org.atmosphere.cpr.DefaultBroadcaster,
cometSupport=org.atmosphere.container.TomcatCometSupport#107fff7,
serializer=null,
isInScope=true,
useWriter=true,
listeners=[]}
2012-04-02 14:44:41,159 [http-8080-13] ERROR cpr.AsynchronousProcessor - failed
to timeout resource AtmosphereResourceImpl{, hasCode648226529,
action=org.atmosphere.cpr.AtmosphereServlet$Action#507e61,
broadcaster=org.atmosphere.cpr.DefaultBroadcaster,
cometSupport=org.atmosphere.container.TomcatCometSupport#107fff7,
serializer=null,
isInScope=true,
useWriter=true,
listeners=[]}
....
Which web server are you using? Sound like the web server isn't detecting when the browser close the connection. You can add, in web.xml, the following timeout detector
org.atmosphere.cpr.CometSupport.maxInactiveActivity=30000 //30 seconds
I believe your issue is in your unload event. "$(window).unload". I know at least in chrome, you can't do much in the unload or beforeunload events. therefore, your browser is probably never firing the unsubscribe().
if u look at Atmospheres jquery pubsub sample, u can see the unsubscribing before connecting,
function connect() {
unsubscribe();
...
you can code a loop to check broadcasters by pushing insignificant data to validate the broadcasters periodically if they arent getting cleaned up. i need to research atmosphere more and hope for a better solution. hopefully you can clean up threads when the new connection is created from a refresh and let old ones expire with the session when the user leaves.

Resources