I am looking for something (no aspects) from Dropwizard which can help to surround resource method (POST, GET) and execute that particular method in a transaction. I checked interceptors but I can reach URI.
I want to surround resource method kind of transactions
// pre - start transaction
#Post/#GET
public Response doSomething() { }
// post - close transaction
Related
Motivation: I need to set the threadKey for a DelegatingSessionFactory before I route to an Sftp outbound gateway and unset the threadKey afterwards.
Depending on a tenant I need to use a different Sftp user account. The user accounts are a matter of configuration in my application.yml, I do not want to write separate routes for each new tenant.
public IntegrationFlow aDynamicSftpFlow() {
f -> f
.handle(tenantSessionDefine()) // how can I use a lambda instead?
.handle(Sftp.outboundGateway(delegatingSessionFactory, ...))
.handle(...) // undefine sftp session
}
Setting the threadKey requires a Message<?>, not just payload and headers. So I use a bean because it takes a message:
public class TenantSessionDefine {
private DelegatingSessionFactory delegatingSessionFactory;
public TenantSessionDefine(DelegatingSessionFactory delegatingSessionFactory) {
this.delegatingSessionFactory = delegatingSessionFactory;
}
public Message<?> defineSession(Message<?> message) {
return delegatingSessionFactory.setThreadKey(message, message.getHeaders()
.get("tenantId", String.class));
// used by SessionFactoryLocator
}
}
I would like to write that as a lambda, as in
.handle(message -> delegatingSessionFactory.setThreadKey(message,
message.getPayload().getTenant())
but that is not so easy. The lambda that can be used with handle() which takes a Message<T> ends the flow because it is a void function (MessageHandler functional interface). The other lambda is a GenericHandler, which does not end the flow, but it takes payload and headers, not a message.
This is just an example, every now and then I wish I could use handle() with a message in a lambda without ending the flow. How can I do that?
Update
The DelegatingSessionFactory is not a particularly well suited example. Since setting and clearing the thread key should happen before and after the sftp invocation, an advice fits better than defining a handler before and after the call.
Got it. The javadoc for handle() says
Use handle(Class, GenericHandler) if you need to access the entire message.
The Class parameter must be Message.class:
.handle(Message.class,
(message, headers) -> sftpSessionFactory
.setThreadKey(message, headers.get("tenantId")))
I'm trying to create a middleware in Shelf that will inspect the request, and if certain values are found the request will be handled, otherwise it should be sent to the inner handler. Eg. I would like to inspect the Request.method.
Handler middleware(Handler innerHandler) {
return (Request req) async {
if(req.method == "GET" && req.headers["xxx"] == yyy) {
// Handle the request
...
}
else {
// This gives exception:
// Bad state: The 'read' method can only be called once on a shelf.Request/shelf.Response object.
return innerHandler(req);
}
}
The problem is that it is not possible to call the inner handler after the Request has been inspected. How do I go about inspecting it but still being able to send it along to the inner handler?
I haven't used it myself this way yet but I think you need to call change on the request, then you should be able to read and forward it. See also How to create/add middleware that adds default headers to each request
i am using jsf 2.0
i have question accoring to PreRenderView.
in my Bean i have method like
public void init() throws Exception
{
FacesContext.getCurrentInstance().getExternalContext().redirect("/To My Page");
if(!FacesContext.getCurrentInstance().isPostback())
{
System.out.println("Kshitij");
}
}
when this method is executing it is also printing "Kshitij" in servler log.
then redirecting to page.
why? i think it has to redirect to page first.
Why do you think that the actual redirect is performed first? The method has to finish running first before the server can ever continue the control over the request/response. It's impossible to pause code execution halfway and then continue code execution at exactly the same location in a brand new request and thread.
The redirect() call basically sets the Location response header. Only when the method has returned, the server will send the response and then the browser will send a new request on that location.
Add a return statement or an if/else if you want to skip the printing when you need to redirect.
if (youNeedToRedirect) {
FacesContext.getCurrentInstance().getExternalContext().redirect("/To My Page");
}
else {
if (!FacesContext.getCurrentInstance().isPostback()) {
System.out.println("Kshitij");
}
}
This all has got nothing to do with JSF or preRenderView. It's all just basic Java and HTTP.
Related:
java.lang.IllegalStateException: Cannot (forward | sendRedirect | create session) after response has been committed
In my grails application, failed login attemps get logged using spring security events as shown here http://grails-plugins.github.com/grails-spring-security-core/docs/manual/guide/single.html#7.3%20Registering%20Callback%20Closures
My issue has to do with client ip retrieval. Normally, calling getRemoteAddress from details object of the event should do the job, but my case is that my application is behind a reverse proxy therefore i should get the ip from request header X-Forwarded-For.
Neither event object nor application context parameters of the closuse provide access to the request object. The global request object isn't available either.
Any ideas how to get access to headers or any other way to implement this functionality?
You can get it from RequestContextHolder, if it exists:
GrailsWebRequest request = RequestContextHolder.currentRequestAttributes()
request.getHeader("X-Forwarded-For")
Generally, as you probably know, it isn't considered a very good idea to access the web session from within Services. First of all, you break the abstraction and separation of service logic, and requests might not always be available or associated with the current thread. One way to access the session from a service is to encapsulate the HTTP session in the following manner:
class WebUtilService {
void withSession (Closure closure) {
try {
GrailsWebRequest request = RequestContextHolder.currentRequestAttributes()
GrailsHttpSession session = request.session
closure.call(session)
}
catch (IllegalStateException ise) {
log.warn ("No WebRequest available!")
}
}
}
and you would use it like this:
class MyService {
WebUtilService webUtilService
void doSomething() {
webUtilService.withSession { HttpSession session ->
log.info(session.myValue)
session.newValue = 'Possible, but should be exceptional'
}
}
}
where you could have access to the getHeader() method.
Disclaimer: the code is from Marc-Oliver Scheele's blog.
I am trying to make kind of a polling service towards a activemq queue using camel routes.
I am using routing and routing-jsm plugins for grails.
I have my route configuration set like this.
class QueueRoute {
def configure = {
from("activemq:daemon").routeId("daemonRoute")
.noAutoStartup()
.shutdownRunningTask(ShutdownRunningTask.CompleteCurrentTaskOnly)
.to('bean:daemonCamelService?method=receive')
.end()
}
}
and I am basically trying to do .suspendRoute("daemonRoute") and .resumeRoute("daemonRoute") with some time inbetween. Though after issuing suspendRoute the route is not stopped.
Anyone have tried this?, I have read something about needing to kill the exchange in progress or something similar.
if you are just trying to periodically process all messages in a queue, then another option (instead of starting and stopping the route) is to use a timer and a polling consumer bean to do retrieve all the messages in the queue...
from("timer://processQueueTimer?fixedRate=true&period=30000")
.to("bean:myBean?method=poll");
public class MyBean {
public void poll() {
// loop to empty queue
while (true) {
// receive the message from the queue, wait at most 3 sec
Object msg = consumer.receiveBody("activemq:queue:daemon", 3000);
if (msg == null) {
// no more messages in queue
break;
}
// send it to the next endpoint
producer.sendBody("bean:daemonCamelService?method=receive", msg);
}
}
}
See this FAQ how to stop/suspend a route from a route
http://camel.apache.org/how-can-i-stop-a-route-from-a-route.html
An alternative is to use a route policy
http://camel.apache.org/routepolicy
For example as we do with the throttling route policy that is provided out of the box, take a look at how its implemented, you can do similar for your route as well.