Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • ServiceCallContext -  immutable user parameter map that will be implicitly passed to the service (and interceptor) on every method call.

    Code Block
    languagejava
    themeRDark
    titleServiceCallContext.java
    collapsetrue
    public interface ServiceCallContext {
        public String attribute(String name);
    
        public byte[] binaryAttribute(String name);
    }


  • ServiceCallInterceptor  - intercepts service method calls.

    Code Block
    languagejava
    themeRDark
    titleServiceCallInterceptor.java
    collapsetrue
    public interface ServiceCallInterceptor extends Serializable {
        // Called BEFORE the service method is executed.
        public default void onInvoke(String mtd, Object[] args, ServiceContext ctx) throws ServiceInterceptException {
            // No-op.
        }
    
        // Called AFTER the service method is executed.
        public default void onComplete(String mtd, Object[] args, @Nullable Object res, ServiceContext ctx) throws ServiceInterceptException {
            // No-op.
        }
    
        // Called when onInvoke, onComplete or service method throws an exception.
        public default void onError(String mtd, Object[] args, Throwable err, ServiceContext ctx) {
            // No-op.
        }
    }


  • ServiceInterceptException - unchecked exception that is used to highlight the exception that occurred during method interception (not execution).

...

Code Block
languagejava
themeRDark
titleExample.java
collapsetrue
        ServiceCallInterceptor security = new ServiceCallInterceptor() {
            @Override public void onInvoke(String mtd, Object[] args, ServiceContext ctx) {
                // Check permission before execution of the method.
                if (!CustomSecurityProvider.get().access(mtd, ctx.attribute("sessionId")))
                    throw new SecurityException("Method invocation is not permitted");
            }
        }

        ServiceCallInterceptor audit = new ServiceCallInterceptor() {
            @Override public void onInvoke(String mtd, Object[] args, ServiceContext ctx) {
                // Record an event before execution of the method.
                AuditProvider.get().recordStartEvent(mtd, ctx.currentCallContext().attribute("sessionId"));
            }

            @Override public void onComplete(String mtd, Object[] args, @Nullable Object res, ServiceContext ctx) {
                AuditProvider.get().recordFinishEvent(mtd, ctx.currentCallContext().attribute("sessionId"));
            }

            @Override public void onError(String mtd, Object[] args, Throwable err, ServiceContext ctx) {
                AuditProvider.get().recordError(mtd, ctx.currentCallContext().attribute("sessionId"), err.getMessage());
            }
        }

        // Set context parameters for the service proxy.
        ServiceCallContext ctx = ServiceCallContext.builder().put("sessionId", sessionId).build();

        ServiceConfiguration svcCfg = new ServiceConfiguration()
            .setName("service")
            .setService(new MyServiceImpl())
            .setMaxPerNodeCount(1)
            .setInterceptors(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);  

...

To add/remove interceptor service should be redeployed.

Interceptor is located and executed where the service is implemented (for Java service - on Java side, for .NET-service on .NET side). Its execution should not cause additional serialization).

...

If one service calls another, then by default the current call context will not be bound to the created proxy - the user must explicitly bind it. But Java service has a special ServiceResource annotation to inject another service proxy into the current service. If the user wants to redirect the current call context to this (injected) proxy, he can set the forwardCallerContext option of this annotation.

...

Any runtime exception thrown by the onInvoke/onComplete methods will be wrapped in a ServiceInterceptException. This exception will be passed to the initiator (user) and to onError method of the interceptor.

...

The exception thrown by the onError method will be added to the main exception as suppressed.

...