ID | IEP-79 |
Author | Pavel Pereslegin |
Sponsor | |
Created | 13 Oct 2021 |
Status | DRAFT |
When implementing microservices, users are often faced with the task of separating the business logic from the common "middleware" logic.
An example of a typical “middleware” task is auditing calls to business service methods (the system must understand which user called which methods and with what result).
Modern frameworks such as gRPC and Apache Thrift provide a very flexible API for implementing request interceptors, with which you can solve almost any middleware task.
Apache Ignite does not provide any mechanisms for solving such problems in general. The user needs to implement it himself, which often results in a lot of boilerplate code.
The Ignite Service Grid must support the following capabilities:
/** * Service method call interceptor. */ public interface ServiceCallInterceptor { /** * Executes before service method invocation. * * @param mtdName Method name. * @param args Method arguments. * @param ctx Service request context. * @return Listener of the call result or {@code null}. */ public @Nullable ServiceCallListener intercept(String mtdName, Object[] args, ServiceRequestContext ctx); }
/** * Listener of the service method invocation. */ public interface ServiceCallListener { /** * * @param res Service method call result, if any. * @param t Error, if any. */ public void onComplete(@Nullable Object res, @Nullable Throwable t); }
ServiceCallInterceptor security = (mtd, args, ctx) -> { if (!CustomSecurityProvider.get().checkPermissions(mtd, ctx.value("sessionId"))) throw new SecurityException("Method invocation is not permitted"); return null; } ServiceCallInterceptor audit = (mtd, args, ctx) -> { return (res, err) -> { AuditProvider.get().recordEvent(mtd, ctx.value("sessionId"), err); } } ServiceConfiguration svcCfg = new ServiceConfiguration() .setName("service") .setService(new MyServiceImpl()) .setMaxPerNodeCount(1) .setInterceptors(Arrays.asList(security, audit)); // Deploy service. ignite.services().deploy(svcCfg); ... // Set context paramters for service proxy. ignite.services().serviceProxy("service", MyService.class, false, Collections.singleton("sessionId", sessionId), 0);
// Describe project risks, such as API or binary compatibility issues, major protocol changes, etc.
// Links to various reference documents, if applicable.
// Links or report with relevant JIRA tickets.