I want to introduce effective logging with in my Spring Integration implementation. I already have global wire-tap which logs the payload and headers. However we have lots service activators which has lots of business logic. I want to log important information like user id, request id in every log. We are using SLF4J. The spring integration flow has number of thread pool executors which are managed by Spring integration.
Should I go for AOP where before every method call, I retrieve the userid and request id from message headers and set it in SLF4J MDC? and then clear it once the method execution is over. It would have clearing logic in finally block. Is this a right approach or this would create performance bottle neck? Not sure why this has not been discussed much as in multithreaded SI flow, it would become very difficult to debug logs without user information.
If there is a better approach, please suggest.
See the SecurityContextPropagationChannelInterceptor introduced in 4.2.
Notice that it is a subclass of ThreadStatePropagationChannelInterceptor.
You could use a similar technique to propagate/clean up the MDC when a message is passed off to another thread. It would be less overhead than doing it on every call made by that thread.
Notice how the information to be propagated is wrapped in a lightweight message wrapper, along with the message. You could also store the information in message headers.
If you come up with a generic implementation, consider contributing it to the framework.
Related
Can anyone provide a clear explanation of when to use nullChannel() vs. when to use get() when configuring a SI Flow with the DSL ?
The nullChannel() is a shortcut of the .channel(“nullChannel”).get(). But it still has that logical purpose to give a clue for target developer that this is the end of the flow and we can’t continue processing after nullChannel since this channel cannot be subscribed for consuming messages sent to it.
If your confuse is why would one specify a nullChannel if there probably would be enough just have that get(), then the answer is: it is possible and a valid use-case when you rely on the replyChannel header to produce the result from your endpoint. But if you fully want to void that result, the nullChannel must be configured explicitly.
I am looking at developing a solution with Dialogflow, where the User Interface events (e.g. Typed user input) are going to arrive as http REST events.
The problem with this is that the Dialogflow Client API (Note: This is NOT THE SAME THING as the fulfilment API), looks like it is stateful: https://github.com/googleapis/nodejs-dialogflow
(... But I could be wrong on that...)
And stateful is hard in most (all?) modern serverless paradigms that any sane person is probably using. Mainly - There is no gaurantee that subsequent events will arrive at the same run-time instance.
It's a bit infuriating that although many examples are supplied at the repo above, none of them look like realistic (but small) applications, handling multi-session, multi-turn (even 2-3 turns) user input.
Is the idea that any run-time instance could/would call new dialogflow.SessionsClient(); just once PER RUNTIME initialisation (NOT per session) to initialise the API, and then everything else is done via like await sessionClient.detectIntent(request); ???
Now that I've typed this, I am pretty confident that is right. But if anyone could confirm it would be great!
The underlying Dialogflow Session API itself is stateless - any statefull decisions that are made must be included in your call to detectIntent. The JavaScript library reflects this stateless scenario as well.
The SessionsClient constructor sets up the connection and authentication information, but does not maintain any other conversational state. So you can use the same object to manage multiple conversations.
Note that this still means you need to maintain conversational state (the session id, the values and lifespans returned in contexts, etc) in order to pass it to detectIntent as part of the request.
I developing a stateless REST API that makes use of token based authentication, where I'm manually adding an Authentication object to the security context by calling SecurityContextHolder.getContext().setAuthentication(authentication) from within a custom security filter. I've been experiencing problems with the context not being set correctly which I believe is due to this :
Storing the SecurityContext between requests
In an application which receives concurrent requests in a single session, the same SecurityContext instance will be shared between threads. Even though a ThreadLocal is being used, it is the same instance that is retrieved from the HttpSession for each thread. This has implications if you wish to temporarily change the context under which a thread is running. If you just use SecurityContextHolder.getContext(), and call setAuthentication(anAuthentication) on the returned context object, then the Authentication object will change in all concurrent threads which share the same SecurityContext instance. ...
You can customize the behaviour of SecurityContextPersistenceFilter to create a completely new SecurityContext for each request, preventing changes in one thread from affecting another.
So the question is - how do you change the behaviour of the SecurityContextPersistenceFilter?
I'd like the security context to not be associated with the http session, but don't want to set the session creation policy to stateless, because I still want to implement CSRF protection etc.
I had this exact question this afternoon, and this open question matched my search exactly, so I thought I would add the little I learned.
We had threads that were accessing the same SecurityContext. I was unable to figure out how to customize the behavior of the SecurityContextPersistenceFilter directly (and in the pattern of the framework), however there were two ways that I could get it to be thread safe.
The first solution was to ensure that an empty context was created in our main authentication filter. This covered all of our authenticated requests, so it would work for our solution.
SecurityContextHolder.createEmptyContext();
The second thing that worked for me was to change our WebSecurityConfig to be stateless, which I know doesn't work for the OP, but added here for completeness.
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
...
Both these solutions work independently for our particular configuration. I'm certain there is a 3rd solution that would read better, but I don't know what it is but would like to.
This is my first time posting. I welcome any feedback.
Dear Spring Cache project community,
currently I'm implementing an Apache CXF-based Spring (version 4.1.5) web service endpoint using the contract 1st approach. Here, I observe when annotating a public method within my web service class, the Spring cache annotations "#Cachable" are ignored each time I call this method in a self-invoked way within the same bean. This could be proven when taking a look on the cache repository (via JMX) of the underlying cache provider (here: EhCache). There, no filling of the cache takes place.
After taking a look on the current Spring documentation below
Enable caching annotations and
The dispatcher servlet I assume it might be due to the fact that:
<cache:annotation-driven/> only looks for #Cacheable/#CachePut/#CacheEvict/#Caching on beans in the same application context it is defined in. This means that, if you put in a WebApplicationContext for a DispatcherServlet, it only checks for beans in your controllers, and not your services. See Section 17.2, “The DispatcherServlet” for more information.
Currently, an Apache CXF "CXFServlet" registered within the "web.xml" deployment descriptor is starting a Spring WebApplicationContext using the "cxf-servlet.xml" Spring application context file by default. There, the <cache:annotation-driven/> is located.
Or is it maybe due to the fact that I'm calling the #Cacheable annotated method from within the same Spring bean so that the generated Spring proxy is bypassed? Details can be found in the "Proxy mechanisms" chapter (9.6) of the Spring documentation as well.
But I do not know how to change the behaviour so that my method results are being cached. Do you have any ideas? Or are my assumptions I posted above incorrect?
Dear Spring community,
I found the important comment within the Spring documentation that approves my assumption:
In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual caching at runtime even if the invoked method is marked with #Cacheable - considering using the aspectj mode in this case. Also, the proxy must be fully initialized to provide the expected behaviour so you should not rely on this feature in your initialization code, i.e. #PostConstruct.
In consequence this means refactoring the code when relying on Spring AOP and its proxy mode technique or switching the mode from "proxy" to "aspectj" <cache:annotation-driven mode="aspectj"/>. This allows using self-invoking methods within the same class as AOP does static respectively dynamic weaving and so manipulates the byte code directly.
Shiro documentation says,
"Shiro acquires Subject data based on the currently executing Thread via its own framework integration code, and this is the preferred way to use Shiro"
If Shiro is getting subject from currently executing thread and Netty handles more than 1 requests using 1 thread. So, how get subject method will return subject information for a given request? And if Shiro is not handling this situation, do I need to add extra mechanism to achieve this?
Thanks.
I don't know how netty works, but if you can configure it using Filters, shiro will make sure the threadlocal info is cleaned at the end of a request.
If you cannot use filters, you can probably hook in your own handling of putting/remove the subject on/from the thread.
Shiro uses the class ThreadContext for this:
http://shiro.apache.org/static/1.2.3/apidocs/org/apache/shiro/util/ThreadContext.html
The methods ThreadContext.bind(securityManager) and ThreadContext.bind(subject) are the key methods. When a thread is done, call ThreadCOntext.remove().
If you check out this page, you'll see the thread stuff in action during a unit test: http://shiro.apache.org/testing.html