...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
public interface ServiceInterceptorContext extends ServiceCallContext { public String method(); public @Nullable Object[] arguments(); public void attribute(String name, String val); public void binaryAttribute(String name, byte[] val); } |
draw.io Diagram border true diagramName middleware simpleViewer false width links auto tbstyle top lbox true diagramWidth 1001 revision 13
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
ServiceCallInterceptor security = new ServiceCallInterceptor() { @Override public void onInvoke(ServiceInterceptorContext ctx) throws ServiceInterceptException { // Check permission before execution of the method. if (!CustomSecurityProvider.get().access(ctx.method(), ctx.attribute("sessionId"))) throw new SecurityException("Method invocation is not permitted"); } } ServiceCallInterceptor audit = new ServiceCallInterceptor() { @Override public void onInvoke(ServiceInterceptorContext ctx) { // Record an event before execution of the method. AuditProvider.get().recordStartEvent(ctx.method(), ctx.attribute("sessionId")); } @Override public void onComplete(@Nullable Object res, ServiceInterceptorContext ctx) { AuditProvider.get().recordFinishEvent(ctx.method(), ctx.attribute("sessionId")); } @Override public void onError(Throwable err, ServiceInterceptorContext ctx) { AuditProvider.get().recordError(ctx.method(), ctx.attribute("sessionId"), err.getMessage()); } } // Set context parameters for service proxy. ServiceCallContext ctx = ServiceCallContext.builder().put("sessionId", sessionId).build(); ServiceConfiguration svcCfg = new ServiceConfiguration() .setName("service") .setService(new MyServiceImpl()) .setMaxPerNodeCount(1) .setInterceptors(Arrays.asList(security, audit)); // Deploy service. ignite.services().deploy(svcCfg); MyService proxy = ignite.services().serviceProxy("service", MyService.class, false, ctx, 0); // A business method call to be intercepted. proxy.placeOrder(order1); proxy.placeOrder(order2); |
The service interceptor is bound to the service during deployment.
One service can have several interceptors.
Interceptor is executed where the service is implemented (for Java service - on Java side, for .NET-service on .NET side without any additional serialization).
Interceptor only applies to user-defined business methods - it does not apply to initialize/execute/cancel methods,
Interceptor can modify ServiceCallContext, but Service methods can only read it.
If an interceptor has been specified, but the user has not passed the caller context through the proxy, it will be created dynamically.
Interceptor must support ignite instance resource injection.
Interceptor should be LifeCycleAware
// todo ServiceInterceptException
If an interceptor throws an exception, then processing is aborted, but the exception is passed to all listed interceptors (onError)
// todo explain forwardCallerContext
...