[ 
https://issues.apache.org/jira/browse/IGNITE-15572?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Pavel Pereslegin updated IGNITE-15572:
--------------------------------------
    Description: 
In traditional microservices, we have the ability to set a custom execution 
context.
For example, a REST service may obtain the session ID from the request. We can 
say that each client request, in this case, has a set of explicit and implicit 
parameters.  One of the implicit parameters is a session identifier that can be 
passed to the service using request headers.

It would be nice to have a similar feature in Ignite services.

The basic idea behind the implementation:
1. Allow the user to bind the "execution context" to the service proxy object.
2. Pass this context as an additional implicit parameter each time the user 
service method is called.

Sample code for using "execution context".
{code:java}
        // Creating service proxy invocation context with two attributes.
        ServiceProxyContext ctx1 = new ServiceProxyContextBuilder("arg1", 
10).put("usr", "X").build();
        ServiceProxyContext ctx2 = new ServiceProxyContextBuilder("arg1", 
6).put("usr", "X").build();

        // Binding "execution context" to proxy invocation handler.
        MyService proxy1 = ignite.services().serviceProxy("svc", 
MyService.class, false, ctx1, 0);
        MyService proxy2 = ignite.services().serviceProxy("svc", 
MyService.class, false, ctx2, 0);

        // Invoke service methods with argument "10".
        assert proxy1.multiply(2) == 10 * 2;
        assert proxy1.divide(2) == 10 / 2;

        // Invoke service methods with argument "6".
        assert proxy2.multiply(2) == 6 * 2;
        assert proxy2.divide(2) == 6 / 2;
...
{code}

Sample code for reading "execution context".
{code:java}
class MyServiceImpl implements MyService {
    @LoggerResource
    private IgniteLogger log;

    private ServiceContext ctx;

    @Override public void init(ServiceContext ctx) throws Exception {
        this.ctx = (ServiceContextImpl)ctx;
    }

    @Override public int multiply(int arg2) {
        ServiceProxyContext ctx = ServiceProxyContext.current();

        int arg1 = ctx.attribute("arg1");
        String userId = ctx.attribute("usr");

        log.info(String.format("user=%s, oper=%s, a=%d, b=%d", userId, 
"multiply", arg1, arg2));

        return arg1 * arg2;
    }

    @Override public int divide(int arg2) {
        ServiceProxyContext ctx = ServiceProxyContext.current();

        int arg1 = ctx.attribute("arg1");
        String userId = ctx.attribute("usr");

        log.info(String.format("user=%s, oper=%s, a=%d, b=%d", userId, 
"divide", arg1, arg2));

        return arg1 / arg2;
    }

    ...
}
{code}


  was:
In traditional microservices, we have the ability to set a custom execution 
context.
For example, a REST service may obtain the session ID from the request. We can 
say that each client request, in this case, has a set of explicit and implicit 
parameters.  One of the implicit parameters is a session identifier that can be 
passed to the service using request headers.

It would be nice to have a similar feature in Ignite services.

The basic idea behind the implementation:
1. Allow the user to bind the "execution context" to the service proxy object.
2. Pass this context as an additional implicit parameter each time the user 
service method is called.

Sample code for using "execution context".
{code:java}
    // Creating "execution context".
    Map<String, Object> execCtx1 = new HashMap<String, Object>() {{
        put("user.id", 1);
        put("arg1", 10);
    }};

    Map<String, Object> execCtx2 = new HashMap<String, Object>() {{
        putAll(execCtx1);
        put("arg1", 6);
    }};

    // Binding "execution context" to proxy invocation handler.
    MyService svcProxy1 = ignite.services().serviceProxy("svc", 
MyService.class, false, execCtx1, 0);
    MyService svcProxy2 = ignite.services().serviceProxy("svc", 
MyService.class, false, execCtx2, 0);

    assert svcProxy1.multiply(2) == 20;
    assert svcProxy2.multiply(2) == 12;
    assert svcProxy1.divide(2) == 5;
    assert svcProxy2.divide(2) == 3;
...
{code}

Sample code for reading "execution context".
{code:java}
class MyServiceImpl implements MyService {
    @LoggerResource
    private IgniteLogger log;

    private ServiceContext ctx;

    @Override public void init(ServiceContext ctx) throws Exception {
        this.ctx = (ServiceContextImpl)ctx;
    }

    @Override public int multiply(int arg2) {
        int arg1 = ctx.attribute("arg1");
        int userId = ctx.attribute("user.id");

        log.info(String.format("user=%d, oper=%s, a=%d, b=%d", userId, 
"multiply", arg1, arg2));

        return arg1 * arg2;
    }

    @Override public int divide(int arg2) {
        int arg1 = ctx.attribute("arg1");
        int userId = ctx.attribute("user.id");

        log.info(String.format("user=%d, oper=%s, a=%d, b=%d", userId, 
"divide", arg1, arg2));

        return arg1 / arg2;
    }

    ...
}
{code}



> Ability to set custom execution context for Ignite service.
> -----------------------------------------------------------
>
>                 Key: IGNITE-15572
>                 URL: https://issues.apache.org/jira/browse/IGNITE-15572
>             Project: Ignite
>          Issue Type: New Feature
>          Components: managed services
>            Reporter: Pavel Pereslegin
>            Assignee: Pavel Pereslegin
>            Priority: Major
>              Labels: ise
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> In traditional microservices, we have the ability to set a custom execution 
> context.
> For example, a REST service may obtain the session ID from the request. We 
> can say that each client request, in this case, has a set of explicit and 
> implicit parameters.  One of the implicit parameters is a session identifier 
> that can be passed to the service using request headers.
> It would be nice to have a similar feature in Ignite services.
> The basic idea behind the implementation:
> 1. Allow the user to bind the "execution context" to the service proxy object.
> 2. Pass this context as an additional implicit parameter each time the user 
> service method is called.
> Sample code for using "execution context".
> {code:java}
>         // Creating service proxy invocation context with two attributes.
>         ServiceProxyContext ctx1 = new ServiceProxyContextBuilder("arg1", 
> 10).put("usr", "X").build();
>         ServiceProxyContext ctx2 = new ServiceProxyContextBuilder("arg1", 
> 6).put("usr", "X").build();
>         // Binding "execution context" to proxy invocation handler.
>         MyService proxy1 = ignite.services().serviceProxy("svc", 
> MyService.class, false, ctx1, 0);
>         MyService proxy2 = ignite.services().serviceProxy("svc", 
> MyService.class, false, ctx2, 0);
>         // Invoke service methods with argument "10".
>         assert proxy1.multiply(2) == 10 * 2;
>         assert proxy1.divide(2) == 10 / 2;
>         // Invoke service methods with argument "6".
>         assert proxy2.multiply(2) == 6 * 2;
>         assert proxy2.divide(2) == 6 / 2;
> ...
> {code}
> Sample code for reading "execution context".
> {code:java}
> class MyServiceImpl implements MyService {
>     @LoggerResource
>     private IgniteLogger log;
>     private ServiceContext ctx;
>     @Override public void init(ServiceContext ctx) throws Exception {
>         this.ctx = (ServiceContextImpl)ctx;
>     }
>     @Override public int multiply(int arg2) {
>         ServiceProxyContext ctx = ServiceProxyContext.current();
>         int arg1 = ctx.attribute("arg1");
>         String userId = ctx.attribute("usr");
>         log.info(String.format("user=%s, oper=%s, a=%d, b=%d", userId, 
> "multiply", arg1, arg2));
>         return arg1 * arg2;
>     }
>     @Override public int divide(int arg2) {
>         ServiceProxyContext ctx = ServiceProxyContext.current();
>         int arg1 = ctx.attribute("arg1");
>         String userId = ctx.attribute("usr");
>         log.info(String.format("user=%s, oper=%s, a=%d, b=%d", userId, 
> "divide", arg1, arg2));
>         return arg1 / arg2;
>     }
>     ...
> }
> {code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to