Re: Using Spring proxied Session Beans with the ExecAndWaitInterceptor

2012-05-16 Thread Miguel Almeida
Regarding this issue - and considering any interceptor, not just the
ExecAndWaitInterceptor:

1) My issue was, in fact, that I was accessing the request/session
scoped bean in my init method. The init method was being called at app
startup, where no such context exists
2) If we remove that access, you can use the request/session scoped
bean.
3) You can also get the meaning with Spring's ApplicationContext inside
the intercept() method, with the call context.getBean(myBean);

As me and Lukasz were discussing this, we realised the init() method of
the interceptor is only being called at app startup - even if you define
it with, say, a prototype scope in spring. This means that apparently
Struts disregards spring's scope for interceptors, which has thread
safety implications (and you might be better off using the approach in
3) ).


Miguel

On Tue, 2012-05-15 at 09:00 +0200, Ɓukasz Lenart wrote:

 What I mean is that injecting something in ExecAndWaitInterceptor
 which has brought scope can rise concurrency issue because the same
 bean can be used in two different threads (ExecAndWaitInterceptor
 thread and request thread). I would rather pack whatever is needed by
 ExecAndWaitInterceptor and pass to it as a value object and inject
 just stateless services.
 
 That's what I mean by repackaging - to have my own context (a map of
 values, a value bean, etc) that will be passed to
 ExecAndWaitInterceptor and used by it in separation from other
 threads.
 
 And interceptors are singletons per package (package/ tag in
 struts.xml) and even worst ExecAndWaitInterceptor creates its own
 thread ;-)
 
 
 Regards




Can we use the decorator pattern in Actions?

2012-05-16 Thread Miguel Almeida
Imagine the scenario where you have security implemented at the action
method level with an annotation:

@Secured(someRole) restricts that action to that role (and it is
checked with an interceptor).

Discussing this on the TDD mailing list a while back, a decorator
approach was suggested

To separate concerns and ease up testing, authorization is implemented
as a decorator (a-la GoF decorator pattern) adding authorization to the
underlying (decorated) MVC app. 

The technique to getting there (see pseudo code in [1])
1. Extract an interface from your main class with all the public methods
2. Implement a decorator which adds authorization rules to a decorated
underlying object. The decorator implements the authorization rules
using annotations
3. in your tests, test the decorator providing a mock underlying
decorated object, asserting in each test that given a request with a
user that has certain roles the underlying method should or should not
be called.


As you see, tests would have a simple setup as you wouldn't be calling
the real, possible complicated action code, but the fake decorated
one. 
The problem arises when you have superclasses (and maybe also when you
implement interfaces). I exemplify with both.

Imagine this:
RealAction extends CommonAction implements IAction(){
...}

CommonAction implements ServletRequestAware(){
...
}

AuthorizingDecorator implements IAction(){
//injected decorated IAction, see [1]
...
}

Now, on a regular RealAction implementation, the request object exists:
RealAction extends CommonAction, so the request is injected through its
ServletRequestAware.
If you're using the AuthorizingDecorator, however, the request will be
null: RealAction will be injected, so Struts won't kick in to populate
RealAction's request object.


My question is: how would you go on and solve this? Or is the decorator
approach impractical in Struts? I haven't even consider the necessity to
implement every getter/setter on the IAction, which would also make this
approach a bit cumbersome. The simplicity for testing, however, is
great!

Cheers,

Miguel Almeida


[1] The code might end up like this (semi-pseudo code)

Tests:

test_admin_can_call_method_a()

{
// setup a fake request with admin role:
httpRequest = buildRequestWithRole(admin);

// setup a mock app decorated with an authorzation decorator:
MockApp app = new MockApp();
AuthorizationDecorator authorizer = new
AuthorizationDecorator(app);

// act - try calling method A in the decorator:
authorizer.MethodA(httpRequest);

// assert - underlaying method a should have been called:
Assert(app.MethodA.WasCalled==true);

}

test_regularUser_cannot_call_method_a()
{

// setup a fake request with regular user role:
httpRequest = buildRequestWithRole(regular user);

// setup a mock app decorated with an authorzation decorator:
MockApp app = new MockApp();
AuthorizationDecorator authorizer = new
AuthorizationDecorator(app);

// act - try calling method A in the decorator:
authorizer.MethodA(httpRequest);

// assert - underlaying method a should not have been called:
Assert(app.MethodA.WasCalled==false);

}

In the SUT:

interface IAction
{

String MethodA()
String MethodB()
...

}

// this is the real action implementing methodA, methodB etc
class RealAction: IAction
{

String MethodA()
String MethodB()
...

}

// this is responsible for authorization
class AuthorizingDecoratorAction : IAction
{

private IAction _decorated;
public AuthorizationDecorator(IAction decorated)
{
_decorated = decorated;
}

// each method is implemented using annotations and calling the
underlying decorated object
@SecuredRoles(admin, manager)
public void MethodA()
{
_decorated.MethodA();
}

@SecuredRoles(regular user)
public void MethodB()
{
_decorated.MethodB();
}

}