[ 
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.
h3. API proposal.
h4. 1. Using a custom annotation (ServiceRequestContextResource) and reading 
context attributes with a function.
{code:java}
MyService proxy = ignite.services().serviceProxy("svc", ... 
Collections.singletonMap("login", "user1"));

public class MyServiceImpl implements MyService {
    @ServiceRequestContextResource
    private Function<String, Object> ctxFunc;

    @Override public void serviceMethod() {
        String login = (String)ctxFunc.apply("login");
    }
    ...
}{code}
h4. 2. Using a new method of the existing ServiceContext.
{code:java}
MyService proxy = ignite.services().serviceProxy("svc", ... 
Collections.singletonMap("login", "user1"));

public class MyServiceImpl implements MyService {
    private ServiceContext svcCtx;

    @Override public void init(ServiceContext svcCtx) {
        this.svcCtx = svcCtx;
    }

    @Override public void serviceMethod() {
        String user = svcCtx.attribute("login");
        // and/or
        String user = (String)svcCtx.attributes().get("login");
    }
    ... 
}{code}
h4. The next two options require wrapping Map<String, Object> into a new 
ServiceRequestContext class.
h4. 3. Read context "wrapper" using special annotation and supplier.
{code:java}
MyService proxy = ignite.services().serviceProxy("svc", ... new 
ServiceRequestContext("login", "user1"), 0);

public class MyServiceImpl implements MyService {
    @ServiceRequestContextResource
    Supplier<ServiceRequestContext> ctxSupplier;
        
    @Override public void serviceMethod() {
        String login = ctxSupplier.get().attribute("login");
    }
    ...
}
{code}
h4. 4. Using the special static method of the "wrapper" class.
{code:java}
MyService proxy = ignite.services().serviceProxy("svc", ... new 
ServiceRequestContext("login", "user1"), 0);

public class MyServiceImpl implements MyService {
    @Override public void serviceMethod() {             
        String login = ServiceRequestContext.current().attribute("login");
    }
    ...
}
{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.
h3. API proposal.
h4. 1. Using a custom annotation (ServiceRequestContextResource) and reading 
context attributes with a function.
{code:java}
MyService proxy = ignite.services().serviceProxy("svc", ... 
Collections.singletonMap("login", "user1"));

public class MyServiceImpl implements MyService {
    @ServiceRequestContextResource
    private Function<String, Object> ctxFunc;

    public void serviceMethod() {
        String login = (String)ctxFunc.apply("login");
    }
    ...
}{code}
h4. 2. Using a new method of the existing ServiceContext.
{code:java}
MyService proxy = ignite.services().serviceProxy("svc", ... 
Collections.singletonMap("login", "user1"));

public class MyServiceImpl implements MyService {
    private ServiceContext svcCtx;

    @Override public void init(ServiceContext svcCtx) {
        this.svcCtx = svcCtx;
    }

    @Override public void businessMethod() {
        String user = svcCtx.attribute("login");
        // and/or
        String user = (String)svcCtx.attributes().get("login");
    }
    ... 
}{code}
h4. The next two options require wrapping Map<String, Object> into a new 
ServiceRequestContext class.
h4. 3. Read context "wrapper" using special annotation and supplier.
{code:java}
MyService proxy = ignite.services().serviceProxy("svc", ... new 
ServiceRequestContext("login", "user1"), 0);

public class MyServiceImpl implements MyService {
    @ServiceRequestContextResource
    Supplier<ServiceRequestContext> ctxSupplier;
        
    @Override public void businessMethod() {
        String login = ctxSupplier.get().attribute("login");
    }
    ...
}
{code}
h4. 4. Using the special static method of the "wrapper" class.
{code:java}
MyService proxy = ignite.services().serviceProxy("svc", ... new 
ServiceRequestContext("login", "user1"), 0);

public class MyServiceImpl implements MyService {
    @Override public void businessMethod() {            
        String login = ServiceRequestContext.current().attribute("login");
    }
    ...
}
{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.
> h3. API proposal.
> h4. 1. Using a custom annotation (ServiceRequestContextResource) and reading 
> context attributes with a function.
> {code:java}
> MyService proxy = ignite.services().serviceProxy("svc", ... 
> Collections.singletonMap("login", "user1"));
> public class MyServiceImpl implements MyService {
>     @ServiceRequestContextResource
>     private Function<String, Object> ctxFunc;
>     @Override public void serviceMethod() {
>         String login = (String)ctxFunc.apply("login");
>     }
>     ...
> }{code}
> h4. 2. Using a new method of the existing ServiceContext.
> {code:java}
> MyService proxy = ignite.services().serviceProxy("svc", ... 
> Collections.singletonMap("login", "user1"));
> public class MyServiceImpl implements MyService {
>     private ServiceContext svcCtx;
>     @Override public void init(ServiceContext svcCtx) {
>         this.svcCtx = svcCtx;
>     }
>     @Override public void serviceMethod() {
>         String user = svcCtx.attribute("login");
>         // and/or
>         String user = (String)svcCtx.attributes().get("login");
>     }
>     ... 
> }{code}
> h4. The next two options require wrapping Map<String, Object> into a new 
> ServiceRequestContext class.
> h4. 3. Read context "wrapper" using special annotation and supplier.
> {code:java}
> MyService proxy = ignite.services().serviceProxy("svc", ... new 
> ServiceRequestContext("login", "user1"), 0);
> public class MyServiceImpl implements MyService {
>     @ServiceRequestContextResource
>     Supplier<ServiceRequestContext> ctxSupplier;
>       
>     @Override public void serviceMethod() {
>         String login = ctxSupplier.get().attribute("login");
>     }
>     ...
> }
> {code}
> h4. 4. Using the special static method of the "wrapper" class.
> {code:java}
> MyService proxy = ignite.services().serviceProxy("svc", ... new 
> ServiceRequestContext("login", "user1"), 0);
> public class MyServiceImpl implements MyService {
>     @Override public void serviceMethod() {           
>         String login = ServiceRequestContext.current().attribute("login");
>     }
>     ...
> }
> {code}



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

Reply via email to