Pointcut on annotated method - sql

I'm trying to add a custom annotation for JPA repository methods to have a advice on #Query value.
Below is the piece of code I tried
MyFilter class
#Aspect
#Component
public class MyFilter {
#Pointcut("execution(* *(..)) && #within(org.springframework.data.jpa.repository.Query)")
private void createQuery(){}
#Around("createQuery()")
public void invoke(JointPoint jp) {
}
}
The Respository code
#MyFilter
#Query(Select * ...)
MyObject findByNameAndClass(...)
So I keep getting error
createQuery() is never called At MyFilter
I'm trying to update the Query value using the advice.
What am I doing wrong?

To capture the annotation I often use this pattern:
"execution(#AnnotationToCapture * *(..)) && #annotation(annotationParam)"
Then in the proceeding method, you can have the annotation as parameter:
(..., AnnotationToCapture annotationParam, ...)

You should not use the #within annotation for this purpose. Instead, you should use #annotation, as follows:
#Pointcut("execution(* *(..)) && #annotation(org.springframework.data.jpa.repository.Query)")
private void createQuery(){}
Also, you should use JoinPoint to access the method signature and then you can extract the annotation from the signature.

Related

bytecode tools: add method interceptor to classes (not proxy)

Javassist proxyFactory can create proxy at runtime with method interceptor. But how to add method interceptor to a class statically by modifying the class file?
For example, class Foo has 100 methods, before calling any method on an instance of Foo, need to check if the Foo instance is initialized.
public class Foo {
public void methodA() {
...
}
public void methodB() {
...
}
public void methodC() {
...
}
....
}
How to modify the class file to add such method interceptor? One way is to add code at the beginning of each method. Is there a better way?
How about other bytecode tools such as cglib, ....?
There are two options with ByteBuddy to achive this:
use redefine/rebase feature - You can check the details on ByteBuddy tutorial under 'type redefinition'/'type rebasing' tags. Limitation here is that this kind of transformation needs to be done before a target class is loaded.
Java Agent - agents run before class is loaded so they are allowed to modify existing classes. ByteBuddy comes with nice AgentBuilder (tutorial - 'Creating Java agents'). There is also posiblity to install special ByteBuddy agent at runtime (example from mentioned tutorial).
class Foo {
String m() { return "foo"; }
}
class Bar {
String m() { return "bar"; }
}
ByteBuddyAgent.install();
Foo foo = new Foo();
new ByteBuddy()
.redefine(Bar.class)
.name(Foo.class.getName())
.make()
.load(Foo.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
assertThat(foo.m(), is("bar"));

Spring AOP get annotation value

I am using spring AOP, how can I get values from annotation,
Here is my annotation:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
#Inherited
#Documented
public #interface ExecutionMethodProfiler
{
String value() default "defaultValue";;
}
here is my XML:
<aop:aspectj-autoproxy/>
<aop:config>
<aop:aspect ref="methodProfiler">
<aop:pointcut id="serviceMethod"
expression="(execution(* com.old..*(..)) or execution(* com.test..*(..))) and #annotation(com.test.profiler.ExecutionMethodProfiler)" />
<aop:around pointcut-ref="serviceMethod" method="profile"/>
</aop:aspect>
</aop:config>
And this is my serviceMethod:
public void profile(ProceedingJoinPoint jointPoint) throws Throwable {}
as of now I can get the values by using this code:
MethodSignature signature = (MethodSignature) jointPoint.getSignature();
System.out.println(signature.getMethod().getAnnotation(ExecutionMethodProfiler.class).value());
I don't like it, is there a better way?
First change your advice to take your annotation as an additional argument:
public void profile(
ProceedingJoinPoint jointPoint,
ExecutionMethodProfiler methodProfiler
) throws Throwable {}
Then bind the annotation to that argument in your pointcut:
<aop:around
pointcut="(execution(* com.old..*(..)) or execution(* com.test..*(..))) and #annotation(methodProfiler)"
method="profile"
arg-names="methodProfiler"
/>
I did not actually test it because I am a bit busy now, but this is basically how it works.

NSubstitute throws CouldNotSetReturnDueToTypeMismatchException when mocking Query on NHibernate Session

I have a repository offering a GetAll method which again calls the Query extension method on the ISession instance of NHibernate.
public ICollection<Product> GetAll()
{
return _session.Query<Product>().ToList();
}
My unit test looks like this:
[Test]
public void GetAllReturnsCollectionFromSession()
{
IQueryable<Product> productList = new ProductListBuilder().Build().AsQueryable();
_fixture.Session.Query<Product>().Returns(productList);
var sut = _fixture.CreateSut();
var result = sut.GetAll();
Assert.AreSame(productList, result);
_fixture.Session.Received().Query<Product>();
}
In the _fixture.Session.Query().Returns(productList) statement, NSubstitute throws the following exception:
NSubstitute.Exceptions.CouldNotSetReturnDueToTypeMismatchException : Can not return value of type IQueryable`1Proxy for ISession.GetSessionImplementation (expected type ISessionImplementor).
Make sure you called Returns() after calling your substitute (for example: mySub.SomeMethod().Returns(value)),
and that you are not configuring other substitutes within Returns() (for example, avoid this: mySub.SomeMethod().Returns(ConfigOtherSub())).
If you substituted for a class rather than an interface, check that the call to your substitute was on a virtual/abstract member.
Return values cannot be configured for non-virtual/non-abstract members.
Correct use:
mySub.SomeMethod().Returns(returnValue);
Potentially problematic use:
mySub.SomeMethod().Returns(ConfigOtherSub());
Instead try:
var returnValue = ConfigOtherSub();
mySub.SomeMethod().Returns(returnValue);
at NSubstitute.Core.ConfigureCall.CheckResultIsCompatibleWithCall(IReturn valueToReturn, ICallSpecification spec)
at NSubstitute.Core.ConfigureCall.SetResultForLastCall(IReturn valueToReturn, MatchArgs matchArgs)
at NSubstitute.Core.CallRouter.LastCallShouldReturn(IReturn returnValue, MatchArgs matchArgs)
at NSubstitute.Core.SubstitutionContext.LastCallShouldReturn(IReturn value, MatchArgs matchArgs)
at NSubstitute.SubstituteExtensions.Returns[T](MatchArgs matchArgs, T returnThis, T[] returnThese)
at NSubstitute.SubstituteExtensions.ReturnsForAnyArgs[T](T value, T returnThis, T[] returnThese)
at Statoil.Wellcom.DataLayer.Implementation.Oracle.UnitTests.Repositories.DwapplicationRepositoryTests.GetAllReturnsCollectionFromSession() in C:\git\WELLCOM\source\Statoil.Wellcom.DataLayer.Implementation.Oracle.UnitTests\Repositories\DwapplicationRepositoryTests.cs:line 123
It looks like NSubstitute is unable to set the return value due to Query being an extension method. How would I go about mocking the extension method call on the ISession?
The easiest solution is to wrap your ISession in another interface/concrete class so you can stub that out:
public interface ISessionWrapper
{
IQueryable<T> Query<T>();
}
public class SessionWrapper : ISessionWrapper
{
private readonly ISession _session;
public SessionWrapper(ISession session)
{
_session = session;
}
public IQueryable<T> Query<T>()
{
return _session.Query<T>();
}
}
There is no way to mock extension method with NSubstitute, however if you know what extension method is using inside, than you can mock that. Your test will use extension method on mocked object and eventually it will use mocked method. Difficult part is to know what is going on inside.
It worked for me in projects, where I knew all the source code and I could check what's inside.

Inheriting ConstructorArguments in Ninject

I'm trying to find a method of passing a constructor argument to the constructors of child classes.
These objects are immutable so I'd prefer to use constructor arguments.
The issue I have encountered is that ConstructorArgument does not inherit to child instantiations and the following statements are not interchangeable:
_parsingProcessor = _kernel.Get<IParsingProcessor>(new ConstructorArgument("dataFilePath", dataFilePath);
and
_parsingProcessor = _kernel.Get<IParsingProcessor>(new Parameter("dataFilePath", dataFilePath, true);
So, how can get an inheritable ConstructorArgument and when does it makes sense, if ever, to new the Parameter class?
Yes, you can do this, but it's probably not what you really want. If the container is not actually responsible for instantiating its own dependencies, then its dependencies probably shouldn't be sharing its constructor arguments - it just doesn't make sense.
I'm pretty sure I know what you're trying to do, and the recommended approach is to create a unique binding specifically for your one container, and use the WhenInjectedInto conditional binding syntax, as in the example below:
public class Hello : IHello
{
private readonly string name;
public Hello(string name)
{
this.name = name;
}
public void SayHello()
{
Console.WriteLine("Hello, {0}!", name);
}
}
This is the class that takes a constructor argument which we want to modify, depending on who is asking for an IHello. Let's say it's this boring container class:
public class MyApp : IApp
{
private readonly IHello hello;
public MyApp(IHello hello)
{
this.hello = hello;
}
public virtual void Run()
{
hello.SayHello();
Console.ReadLine();
}
}
Now, here's how you do up the bindings:
public class MainModule : NinjectModule
{
public override void Load()
{
Bind<IApp>().To<MyApp>();
Bind<IHello>().To<Hello>()
.WithConstructorArgument("name", "Jim");
Bind<IHello>().To<Hello>()
.WhenInjectedInto<MyApp>()
.WithConstructorArgument("name", "Bob");
}
}
Basically all this binding is doing is saying the name should be "Jim" unless it's being requested by Hello, which in this case it is, so instead it will get the name "Bob".
If you are absolutely certain that you truly want cascading behaviour and understand that this is very dangerous and brittle, you can cheat using a method binding. Assuming that we've now added a name argument to the MyApp class for some unspecified purpose, the binding would be:
Bind<IHello>().ToMethod(ctx =>
ctx.Kernel.Get<Hello>(ctx.Request.ParentContext.Parameters
.OfType<ConstructorArgument>()
.Where(c => c.Name == "name")
.First()));
Please, please, make sure you are positive that this is what you want before doing it. It looks easy but it is also very likely to break during a simple refactoring, and 95% of the "customized dependency" scenarios I've seen can be addressed using the WhenInjectedInto binding instead.

AspectJ expose annotation value using AspectJ annotations

I'm using AspectJ annotations instead of writing actual aspect files. I want to expose an annotation value to my advice.
I currently have this but it it doesn't expose the values inside MyAnnotation
#Before("execution(#MyAnnotation * * (..))")
public void intercept(JoinPoint jp) {
...
}
What I was thinking was something like this:
#Before("execution(#MyAnnotation * * (..)) && #this(MyAnnotation)")
public void intercept(JoinPoint jp, MyAnnotation myAnnotation) {
...
}
This clearly has a syntax error but was wondering if I was close. I can't seem to find an example syntax when using AspectJ annotations to do this.
You are using type, when you should be using an identifier. The correct code is:
#Before("execution(#MyAnnotation * * (..)) && #this(myAnnotation)")
public void intercept(JoinPoint jp, MyAnnotation myAnnotation) {
...
}