Create a spring session in amqp rpc client












0















I developped spring remoting amqp rpc applications.



That's works well for methods that don't use bean with Scope SESSION.



For the other methods, the client can't use spring session, and I get this exception



org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.userSession': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:362) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) ~[spring-aop-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673) ~[spring-aop-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at io.kzreactive.akwtype.akwtypeback.common.service.UserSession$$EnhancerBySpringCGLIB$$55d53e95.setUser(<generated>) ~[classes/:na]
at io.kzreactive.akwtype.akwtypeback.engine.service.AppService.login(AppService.kt:30) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.remoting.support.RemoteInvocation.invoke(RemoteInvocation.java:215) ~[spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.remoting.support.DefaultRemoteInvocationExecutor.invoke(DefaultRemoteInvocationExecutor.java:39) ~[spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at io.kzreactive.akwtype.akwtypeback.gateway.rabbitmq.SessionDefaultRemoteInvocationExecutor.invoke(RabbitMQSession.kt:48) ~[classes/:na]
at org.springframework.remoting.support.RemoteInvocationBasedExporter.invoke(RemoteInvocationBasedExporter.java:78) [spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.remoting.support.RemoteInvocationBasedExporter.invokeAndCreateResult(RemoteInvocationBasedExporter.java:114) [spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.amqp.remoting.service.AmqpInvokerServiceExporter.onMessage(AmqpInvokerServiceExporter.java:80) [spring-amqp-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1457) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1348) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1324) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1303) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:785) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:769) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:77) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1010) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at java.base/java.lang.Thread.run(Thread.java:844) ~[na:na]
Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.context.request.SessionScope.get(SessionScope.java:55) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:350) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
... 24 common frames omitted


So I would create and use a spring session over rabbit mq



First, I managed to pass the sessionId in RPC call



on the server I add an attribute



class SessionDefaultRemoteInvocationFactory : DefaultRemoteInvocationFactory() {

override fun createRemoteInvocation(methodInvocation: MethodInvocation?): RemoteInvocation {
return super.createRemoteInvocation(methodInvocation)
.apply { addAttribute("sessionId", RequestContextHolder.currentRequestAttributes().sessionId) }
}
}


on the client I can read it



class SessionDefaultRemoteInvocationExecutor : DefaultRemoteInvocationExecutor() {

override fun invoke(invocation: RemoteInvocation?, targetObject: Any?): Any {

if (invocation is RemoteInvocation) {
invocation.getAttribute("sessionId")?.let {

val sessionId = it.toString()

SecurityContextHolder.getContext().authentication = AnonymousAuthenticationToken(sessionId,
"anonymousUser", listOf(SimpleGrantedAuthority("ROLE_ANONYMOUS")))

val attr = RequestContextHolder.currentRequestAttributes() as ServletRequestAttributes // <= ERROR here
attr.request.getSession(true)
}
}

return super.invoke(invocation, targetObject)
}
}


but I don't manage to use it to create a spring session



How can I create a spring session in this NON http context



I tried to create a request context listener



@Configuration
@WebListener
class MyRequestContextListener : RequestContextListener()


but same error










share|improve this question























  • I think you need to take a look into Spring Session project and try to restore HTTP session somehow using the shared store. Although I'm fully not sure that it is going to be possible since you don't have any HTTP context on the client at all: spring.io/projects/spring-session

    – Artem Bilan
    Nov 26 '18 at 15:26
















0















I developped spring remoting amqp rpc applications.



That's works well for methods that don't use bean with Scope SESSION.



For the other methods, the client can't use spring session, and I get this exception



org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.userSession': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:362) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) ~[spring-aop-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673) ~[spring-aop-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at io.kzreactive.akwtype.akwtypeback.common.service.UserSession$$EnhancerBySpringCGLIB$$55d53e95.setUser(<generated>) ~[classes/:na]
at io.kzreactive.akwtype.akwtypeback.engine.service.AppService.login(AppService.kt:30) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.remoting.support.RemoteInvocation.invoke(RemoteInvocation.java:215) ~[spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.remoting.support.DefaultRemoteInvocationExecutor.invoke(DefaultRemoteInvocationExecutor.java:39) ~[spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at io.kzreactive.akwtype.akwtypeback.gateway.rabbitmq.SessionDefaultRemoteInvocationExecutor.invoke(RabbitMQSession.kt:48) ~[classes/:na]
at org.springframework.remoting.support.RemoteInvocationBasedExporter.invoke(RemoteInvocationBasedExporter.java:78) [spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.remoting.support.RemoteInvocationBasedExporter.invokeAndCreateResult(RemoteInvocationBasedExporter.java:114) [spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.amqp.remoting.service.AmqpInvokerServiceExporter.onMessage(AmqpInvokerServiceExporter.java:80) [spring-amqp-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1457) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1348) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1324) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1303) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:785) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:769) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:77) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1010) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at java.base/java.lang.Thread.run(Thread.java:844) ~[na:na]
Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.context.request.SessionScope.get(SessionScope.java:55) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:350) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
... 24 common frames omitted


So I would create and use a spring session over rabbit mq



First, I managed to pass the sessionId in RPC call



on the server I add an attribute



class SessionDefaultRemoteInvocationFactory : DefaultRemoteInvocationFactory() {

override fun createRemoteInvocation(methodInvocation: MethodInvocation?): RemoteInvocation {
return super.createRemoteInvocation(methodInvocation)
.apply { addAttribute("sessionId", RequestContextHolder.currentRequestAttributes().sessionId) }
}
}


on the client I can read it



class SessionDefaultRemoteInvocationExecutor : DefaultRemoteInvocationExecutor() {

override fun invoke(invocation: RemoteInvocation?, targetObject: Any?): Any {

if (invocation is RemoteInvocation) {
invocation.getAttribute("sessionId")?.let {

val sessionId = it.toString()

SecurityContextHolder.getContext().authentication = AnonymousAuthenticationToken(sessionId,
"anonymousUser", listOf(SimpleGrantedAuthority("ROLE_ANONYMOUS")))

val attr = RequestContextHolder.currentRequestAttributes() as ServletRequestAttributes // <= ERROR here
attr.request.getSession(true)
}
}

return super.invoke(invocation, targetObject)
}
}


but I don't manage to use it to create a spring session



How can I create a spring session in this NON http context



I tried to create a request context listener



@Configuration
@WebListener
class MyRequestContextListener : RequestContextListener()


but same error










share|improve this question























  • I think you need to take a look into Spring Session project and try to restore HTTP session somehow using the shared store. Although I'm fully not sure that it is going to be possible since you don't have any HTTP context on the client at all: spring.io/projects/spring-session

    – Artem Bilan
    Nov 26 '18 at 15:26














0












0








0








I developped spring remoting amqp rpc applications.



That's works well for methods that don't use bean with Scope SESSION.



For the other methods, the client can't use spring session, and I get this exception



org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.userSession': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:362) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) ~[spring-aop-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673) ~[spring-aop-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at io.kzreactive.akwtype.akwtypeback.common.service.UserSession$$EnhancerBySpringCGLIB$$55d53e95.setUser(<generated>) ~[classes/:na]
at io.kzreactive.akwtype.akwtypeback.engine.service.AppService.login(AppService.kt:30) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.remoting.support.RemoteInvocation.invoke(RemoteInvocation.java:215) ~[spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.remoting.support.DefaultRemoteInvocationExecutor.invoke(DefaultRemoteInvocationExecutor.java:39) ~[spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at io.kzreactive.akwtype.akwtypeback.gateway.rabbitmq.SessionDefaultRemoteInvocationExecutor.invoke(RabbitMQSession.kt:48) ~[classes/:na]
at org.springframework.remoting.support.RemoteInvocationBasedExporter.invoke(RemoteInvocationBasedExporter.java:78) [spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.remoting.support.RemoteInvocationBasedExporter.invokeAndCreateResult(RemoteInvocationBasedExporter.java:114) [spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.amqp.remoting.service.AmqpInvokerServiceExporter.onMessage(AmqpInvokerServiceExporter.java:80) [spring-amqp-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1457) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1348) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1324) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1303) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:785) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:769) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:77) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1010) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at java.base/java.lang.Thread.run(Thread.java:844) ~[na:na]
Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.context.request.SessionScope.get(SessionScope.java:55) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:350) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
... 24 common frames omitted


So I would create and use a spring session over rabbit mq



First, I managed to pass the sessionId in RPC call



on the server I add an attribute



class SessionDefaultRemoteInvocationFactory : DefaultRemoteInvocationFactory() {

override fun createRemoteInvocation(methodInvocation: MethodInvocation?): RemoteInvocation {
return super.createRemoteInvocation(methodInvocation)
.apply { addAttribute("sessionId", RequestContextHolder.currentRequestAttributes().sessionId) }
}
}


on the client I can read it



class SessionDefaultRemoteInvocationExecutor : DefaultRemoteInvocationExecutor() {

override fun invoke(invocation: RemoteInvocation?, targetObject: Any?): Any {

if (invocation is RemoteInvocation) {
invocation.getAttribute("sessionId")?.let {

val sessionId = it.toString()

SecurityContextHolder.getContext().authentication = AnonymousAuthenticationToken(sessionId,
"anonymousUser", listOf(SimpleGrantedAuthority("ROLE_ANONYMOUS")))

val attr = RequestContextHolder.currentRequestAttributes() as ServletRequestAttributes // <= ERROR here
attr.request.getSession(true)
}
}

return super.invoke(invocation, targetObject)
}
}


but I don't manage to use it to create a spring session



How can I create a spring session in this NON http context



I tried to create a request context listener



@Configuration
@WebListener
class MyRequestContextListener : RequestContextListener()


but same error










share|improve this question














I developped spring remoting amqp rpc applications.



That's works well for methods that don't use bean with Scope SESSION.



For the other methods, the client can't use spring session, and I get this exception



org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.userSession': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:362) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) ~[spring-aop-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673) ~[spring-aop-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at io.kzreactive.akwtype.akwtypeback.common.service.UserSession$$EnhancerBySpringCGLIB$$55d53e95.setUser(<generated>) ~[classes/:na]
at io.kzreactive.akwtype.akwtypeback.engine.service.AppService.login(AppService.kt:30) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.remoting.support.RemoteInvocation.invoke(RemoteInvocation.java:215) ~[spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.remoting.support.DefaultRemoteInvocationExecutor.invoke(DefaultRemoteInvocationExecutor.java:39) ~[spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at io.kzreactive.akwtype.akwtypeback.gateway.rabbitmq.SessionDefaultRemoteInvocationExecutor.invoke(RabbitMQSession.kt:48) ~[classes/:na]
at org.springframework.remoting.support.RemoteInvocationBasedExporter.invoke(RemoteInvocationBasedExporter.java:78) [spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.remoting.support.RemoteInvocationBasedExporter.invokeAndCreateResult(RemoteInvocationBasedExporter.java:114) [spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.amqp.remoting.service.AmqpInvokerServiceExporter.onMessage(AmqpInvokerServiceExporter.java:80) [spring-amqp-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1457) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1348) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1324) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1303) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:785) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:769) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:77) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1010) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at java.base/java.lang.Thread.run(Thread.java:844) ~[na:na]
Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.context.request.SessionScope.get(SessionScope.java:55) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:350) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
... 24 common frames omitted


So I would create and use a spring session over rabbit mq



First, I managed to pass the sessionId in RPC call



on the server I add an attribute



class SessionDefaultRemoteInvocationFactory : DefaultRemoteInvocationFactory() {

override fun createRemoteInvocation(methodInvocation: MethodInvocation?): RemoteInvocation {
return super.createRemoteInvocation(methodInvocation)
.apply { addAttribute("sessionId", RequestContextHolder.currentRequestAttributes().sessionId) }
}
}


on the client I can read it



class SessionDefaultRemoteInvocationExecutor : DefaultRemoteInvocationExecutor() {

override fun invoke(invocation: RemoteInvocation?, targetObject: Any?): Any {

if (invocation is RemoteInvocation) {
invocation.getAttribute("sessionId")?.let {

val sessionId = it.toString()

SecurityContextHolder.getContext().authentication = AnonymousAuthenticationToken(sessionId,
"anonymousUser", listOf(SimpleGrantedAuthority("ROLE_ANONYMOUS")))

val attr = RequestContextHolder.currentRequestAttributes() as ServletRequestAttributes // <= ERROR here
attr.request.getSession(true)
}
}

return super.invoke(invocation, targetObject)
}
}


but I don't manage to use it to create a spring session



How can I create a spring session in this NON http context



I tried to create a request context listener



@Configuration
@WebListener
class MyRequestContextListener : RequestContextListener()


but same error







spring spring-amqp spring-session






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 26 '18 at 6:22









Benoît VALLETTE d'OSIABenoît VALLETTE d'OSIA

355




355













  • I think you need to take a look into Spring Session project and try to restore HTTP session somehow using the shared store. Although I'm fully not sure that it is going to be possible since you don't have any HTTP context on the client at all: spring.io/projects/spring-session

    – Artem Bilan
    Nov 26 '18 at 15:26



















  • I think you need to take a look into Spring Session project and try to restore HTTP session somehow using the shared store. Although I'm fully not sure that it is going to be possible since you don't have any HTTP context on the client at all: spring.io/projects/spring-session

    – Artem Bilan
    Nov 26 '18 at 15:26

















I think you need to take a look into Spring Session project and try to restore HTTP session somehow using the shared store. Although I'm fully not sure that it is going to be possible since you don't have any HTTP context on the client at all: spring.io/projects/spring-session

– Artem Bilan
Nov 26 '18 at 15:26





I think you need to take a look into Spring Session project and try to restore HTTP session somehow using the shared store. Although I'm fully not sure that it is going to be possible since you don't have any HTTP context on the client at all: spring.io/projects/spring-session

– Artem Bilan
Nov 26 '18 at 15:26












1 Answer
1






active

oldest

votes


















0














For the moment I bypass the spring session and I inject a bean with the same behavior



@Component
@Scope("singleton")
class EngineThread(var engineSession: ThreadLocal<EngineSession> = ThreadLocal()) : IEngineSession by engineSession.getOrSet( { EngineSession() })

@Component
@Profile("engine & !test")
class SessionDefaultRemoteInvocationExecutor(val engineThread: EngineThread) : DefaultRemoteInvocationExecutor() {

val engineSessionStore : MutableMap<String, EngineSession> = mutableMapOf()

override fun invoke(invocation: RemoteInvocation?, targetObject: Any?): Any {

if (invocation is RemoteInvocation) {
invocation.getAttribute(SESSION_ID)?.let {

val sessionId = it.toString()

SecurityContextHolder.getContext().authentication = AnonymousAuthenticationToken(sessionId,
"anonymousUser", listOf(SimpleGrantedAuthority("ROLE_ANONYMOUS")))

if (! engineSessionStore.contains(sessionId)) {
engineSessionStore.put(sessionId, EngineSession())
}
engineThread.engineSession.set(engineSessionStore.getValue(sessionId))

}
}

return super.invoke(invocation, targetObject)
}
}


The job is done but I'm not very well with this solution
(I will add clean by softreference… but all this work is reinvent session instead of use spring session)






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53475698%2fcreate-a-spring-session-in-amqp-rpc-client%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    For the moment I bypass the spring session and I inject a bean with the same behavior



    @Component
    @Scope("singleton")
    class EngineThread(var engineSession: ThreadLocal<EngineSession> = ThreadLocal()) : IEngineSession by engineSession.getOrSet( { EngineSession() })

    @Component
    @Profile("engine & !test")
    class SessionDefaultRemoteInvocationExecutor(val engineThread: EngineThread) : DefaultRemoteInvocationExecutor() {

    val engineSessionStore : MutableMap<String, EngineSession> = mutableMapOf()

    override fun invoke(invocation: RemoteInvocation?, targetObject: Any?): Any {

    if (invocation is RemoteInvocation) {
    invocation.getAttribute(SESSION_ID)?.let {

    val sessionId = it.toString()

    SecurityContextHolder.getContext().authentication = AnonymousAuthenticationToken(sessionId,
    "anonymousUser", listOf(SimpleGrantedAuthority("ROLE_ANONYMOUS")))

    if (! engineSessionStore.contains(sessionId)) {
    engineSessionStore.put(sessionId, EngineSession())
    }
    engineThread.engineSession.set(engineSessionStore.getValue(sessionId))

    }
    }

    return super.invoke(invocation, targetObject)
    }
    }


    The job is done but I'm not very well with this solution
    (I will add clean by softreference… but all this work is reinvent session instead of use spring session)






    share|improve this answer




























      0














      For the moment I bypass the spring session and I inject a bean with the same behavior



      @Component
      @Scope("singleton")
      class EngineThread(var engineSession: ThreadLocal<EngineSession> = ThreadLocal()) : IEngineSession by engineSession.getOrSet( { EngineSession() })

      @Component
      @Profile("engine & !test")
      class SessionDefaultRemoteInvocationExecutor(val engineThread: EngineThread) : DefaultRemoteInvocationExecutor() {

      val engineSessionStore : MutableMap<String, EngineSession> = mutableMapOf()

      override fun invoke(invocation: RemoteInvocation?, targetObject: Any?): Any {

      if (invocation is RemoteInvocation) {
      invocation.getAttribute(SESSION_ID)?.let {

      val sessionId = it.toString()

      SecurityContextHolder.getContext().authentication = AnonymousAuthenticationToken(sessionId,
      "anonymousUser", listOf(SimpleGrantedAuthority("ROLE_ANONYMOUS")))

      if (! engineSessionStore.contains(sessionId)) {
      engineSessionStore.put(sessionId, EngineSession())
      }
      engineThread.engineSession.set(engineSessionStore.getValue(sessionId))

      }
      }

      return super.invoke(invocation, targetObject)
      }
      }


      The job is done but I'm not very well with this solution
      (I will add clean by softreference… but all this work is reinvent session instead of use spring session)






      share|improve this answer


























        0












        0








        0







        For the moment I bypass the spring session and I inject a bean with the same behavior



        @Component
        @Scope("singleton")
        class EngineThread(var engineSession: ThreadLocal<EngineSession> = ThreadLocal()) : IEngineSession by engineSession.getOrSet( { EngineSession() })

        @Component
        @Profile("engine & !test")
        class SessionDefaultRemoteInvocationExecutor(val engineThread: EngineThread) : DefaultRemoteInvocationExecutor() {

        val engineSessionStore : MutableMap<String, EngineSession> = mutableMapOf()

        override fun invoke(invocation: RemoteInvocation?, targetObject: Any?): Any {

        if (invocation is RemoteInvocation) {
        invocation.getAttribute(SESSION_ID)?.let {

        val sessionId = it.toString()

        SecurityContextHolder.getContext().authentication = AnonymousAuthenticationToken(sessionId,
        "anonymousUser", listOf(SimpleGrantedAuthority("ROLE_ANONYMOUS")))

        if (! engineSessionStore.contains(sessionId)) {
        engineSessionStore.put(sessionId, EngineSession())
        }
        engineThread.engineSession.set(engineSessionStore.getValue(sessionId))

        }
        }

        return super.invoke(invocation, targetObject)
        }
        }


        The job is done but I'm not very well with this solution
        (I will add clean by softreference… but all this work is reinvent session instead of use spring session)






        share|improve this answer













        For the moment I bypass the spring session and I inject a bean with the same behavior



        @Component
        @Scope("singleton")
        class EngineThread(var engineSession: ThreadLocal<EngineSession> = ThreadLocal()) : IEngineSession by engineSession.getOrSet( { EngineSession() })

        @Component
        @Profile("engine & !test")
        class SessionDefaultRemoteInvocationExecutor(val engineThread: EngineThread) : DefaultRemoteInvocationExecutor() {

        val engineSessionStore : MutableMap<String, EngineSession> = mutableMapOf()

        override fun invoke(invocation: RemoteInvocation?, targetObject: Any?): Any {

        if (invocation is RemoteInvocation) {
        invocation.getAttribute(SESSION_ID)?.let {

        val sessionId = it.toString()

        SecurityContextHolder.getContext().authentication = AnonymousAuthenticationToken(sessionId,
        "anonymousUser", listOf(SimpleGrantedAuthority("ROLE_ANONYMOUS")))

        if (! engineSessionStore.contains(sessionId)) {
        engineSessionStore.put(sessionId, EngineSession())
        }
        engineThread.engineSession.set(engineSessionStore.getValue(sessionId))

        }
        }

        return super.invoke(invocation, targetObject)
        }
        }


        The job is done but I'm not very well with this solution
        (I will add clean by softreference… but all this work is reinvent session instead of use spring session)







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 28 '18 at 11:08









        Benoît VALLETTE d'OSIABenoît VALLETTE d'OSIA

        355




        355
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53475698%2fcreate-a-spring-session-in-amqp-rpc-client%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Costa Masnaga

            Fotorealismo

            Sidney Franklin