Skip to content

Commit 9432934

Browse files
committed
Added filter for sql commenter
1 parent 3018fe7 commit 9432934

File tree

4 files changed

+145
-0
lines changed

4 files changed

+145
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.google.cloud.sqlcommenter.filter;
2+
3+
import org.springframework.web.method.HandlerMethod;
4+
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
5+
import org.springframework.web.server.ServerWebExchange;
6+
import org.springframework.web.server.WebFilter;
7+
import org.springframework.web.server.WebFilterChain;
8+
9+
import com.google.cloud.sqlcommenter.threadlocalstorage.State;
10+
11+
import reactor.core.publisher.Mono;
12+
13+
public class SpringSQLCommenterWebFilter implements WebFilter {
14+
15+
private final RequestMappingHandlerMapping handlerMapping;
16+
17+
public SpringSQLCommenterWebFilter(RequestMappingHandlerMapping handlerMapping) {
18+
this.handlerMapping = handlerMapping;
19+
}
20+
21+
@Override
22+
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
23+
HandlerMethod handlerMethod = (HandlerMethod) this.handlerMapping.getHandler(exchange).toFuture().getNow(null);
24+
25+
State state = State.newBuilder()
26+
.withActionName(handlerMethod.getMethod().getName())
27+
.withFramework("spring")
28+
.withControllerName(handlerMethod.getBeanType().getSimpleName().replace("Controller",""))
29+
.build();
30+
31+
return chain
32+
.filter(exchange)
33+
.contextWrite(ctx -> ctx.put("state", state));
34+
}
35+
36+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.google.cloud.sqlcommenter.r2dbc;
2+
3+
import java.lang.reflect.Proxy;
4+
5+
import org.reactivestreams.Subscription;
6+
7+
import io.r2dbc.spi.Connection;
8+
import reactor.core.CoreSubscriber;
9+
10+
public class ConnectionDecorator implements CoreSubscriber<Object> {
11+
12+
private final CoreSubscriber<Object> delegate;
13+
14+
public ConnectionDecorator(CoreSubscriber<Object> delegate) {
15+
this.delegate = delegate;
16+
}
17+
18+
@Override
19+
public void onSubscribe(Subscription s) {
20+
this.delegate.onSubscribe(s);
21+
}
22+
23+
@Override
24+
public void onNext(Object o) {
25+
assert o instanceof Connection;
26+
Connection connection = (Connection) o;
27+
28+
Object proxied = Proxy.newProxyInstance(Connection.class.getClassLoader(),
29+
new Class[] {Connection.class},
30+
new ConnectionInvocationHandler(connection,delegate.currentContext()));
31+
this.delegate.onNext(proxied);
32+
}
33+
34+
@Override
35+
public void onError(Throwable t) {
36+
this.delegate.onError(t);
37+
}
38+
39+
@Override
40+
public void onComplete() {
41+
this.delegate.onComplete();
42+
}
43+
44+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.google.cloud.sqlcommenter.r2dbc;
2+
3+
4+
5+
import org.aspectj.lang.ProceedingJoinPoint;
6+
import org.aspectj.lang.annotation.Around;
7+
import org.aspectj.lang.annotation.Aspect;
8+
import org.reactivestreams.Publisher;
9+
10+
import io.r2dbc.spi.Connection;
11+
import reactor.core.publisher.Mono;
12+
import reactor.core.publisher.Operators;
13+
14+
@Aspect
15+
public class ConnectionFactoryAspect {
16+
17+
@Around("execution(* io.r2dbc.spi.ConnectionFactory.create(..)) ")
18+
public Object beforeSampleCreation(ProceedingJoinPoint joinPoint) throws Throwable {
19+
Publisher<? extends Connection> publisher = (Publisher<? extends Connection>) joinPoint.proceed();
20+
21+
22+
return Mono.from(publisher)
23+
.cast(Object.class)
24+
.transform(Operators.liftPublisher((publisher1, coreSubscriber) -> new ConnectionDecorator(coreSubscriber)));
25+
}
26+
27+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.google.cloud.sqlcommenter.r2dbc;
2+
3+
import java.lang.reflect.InvocationHandler;
4+
import java.lang.reflect.Method;
5+
6+
import com.google.cloud.sqlcommenter.threadlocalstorage.State;
7+
8+
import io.r2dbc.spi.Connection;
9+
import reactor.util.context.ContextView;
10+
11+
public class ConnectionInvocationHandler implements InvocationHandler {
12+
13+
private final Connection connection;
14+
private final ContextView contextView;
15+
16+
public ConnectionInvocationHandler(Connection connection, ContextView contextView) {
17+
this.connection = connection;
18+
this.contextView = contextView;
19+
}
20+
21+
@Override
22+
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
23+
String methodName = method.getName();
24+
25+
if ("createStatement".equals(methodName)) {
26+
String query = (String) args[0];
27+
if(contextView!=null) {
28+
State state = contextView.get("state");
29+
query = state.formatAndAppendToSQL(query);
30+
}
31+
32+
return method.invoke(connection, query);
33+
} else {
34+
return method.invoke(connection, args);
35+
}
36+
}
37+
38+
}

0 commit comments

Comments
 (0)