Pavel,

My vote is for option (1). Simple and clear.

As you noted, with (2) it is not clear which methods are affected.
Also, we don't provide methods like withTimeout, withSticky, so adding
withContext will introduce another inconsistency.

(3) seems to be too complicated.

On Thu, Dec 16, 2021 at 3:34 PM Pavel Pereslegin <xxt...@gmail.com> wrote:

> Hi folks!
>
> The discussed feature is currently under development and recently
> there was a proposal for an API improvement, which I want to discuss.
>
> It is about how the user can specify a service call context when
> getting a proxy.
>
> I see the following options:
>
> 1. Passing the context as an argument to the proxy getter method.
>
>    Ignite.services().serviceProxy(name,..., callCtx)
>
>    The disadvantage is that for ease of use, we add several
>    overloads of this method with different combinations of parameters.
>
> 2. Adding a new method "withCallContext(callCtx)" (returns
> IgniteServices) to the IgniteServices interface.
>
>    Ignite.services().withCallContext(callCtx).serviceProxy(name,...)
>
>    The disadvantage is that most of the IgniteServices methods
>    are not related to the service call context (deploy, cancel
>    of the service, etc.).
>
> 3. (extension of the 2nd option) Adding a new
> "withCallContext(callCtx)" method which returns a new interface.
>
>    Ignite.service().withCallContext(callCtx).serviceProxy(name,...)
>
>    Unlike the 2nd option, the "withCallContext()" method returns a new
> interface
>    (for example, IgniteServiceProxies or IgniteContextAwareServices), which
>    contains only methods that use the service call context.
>
> WDYT?
>
> пт, 22 окт. 2021 г. в 14:36, Pavel Pereslegin <xxt...@gmail.com>:
> >
> > > 1. Add init/execute/cancel methods without parameters.
> > > 2. Add default no-op implementations for the new methods (this is
> required
> > > to preserve compatibility).
> > > 3. For old methods that take ServiceContext as a parameter, add default
> > > implementations that delegate to new methods.
> > > 4. Deprecate the old methods on the API.
> > > 5. On the implementation level, still use the old methods (again - for
> > > compatibility).
> > > 6. Finally, add a @ServiceContextResource annotation to inject
> > > ServiceContext.
> >
> > I like this idea and I have filed a ticket for this change [1].
> > If there is no objection, I plan to implement this shortly.
> >
> > [1] https://issues.apache.org/jira/browse/IGNITE-15801
> >
> > ср, 20 окт. 2021 г. в 08:54, Nikolay Izhikov <nizhi...@apache.org>:
> > >
> > > > and it fully switches to annotation-based injection.
> > >
> > > +1 to do it.
> > >
> > > > 19 окт. 2021 г., в 22:14, Valentin Kulichenko <
> valentin.kuliche...@gmail.com> написал(а):
> > > >
> > > > That's actually a good point. In Java, we can do the following:
> > > > 1. Add init/execute/cancel methods without parameters.
> > > > 2. Add default no-op implementations for the new methods (this is
> required
> > > > to preserve compatibility).
> > > > 3. For old methods that take ServiceContext as a parameter, add
> default
> > > > implementations that delegate to new methods.
> > > > 4. Deprecate the old methods on the API.
> > > > 5. On the implementation level, still use the old methods (again -
> for
> > > > compatibility).
> > > > 6. Finally, add a @ServiceContextResource annotation to inject
> > > > ServiceContext.
> > > >
> > > > If I haven't missed anything, this is not a breaking change, and it
> fully
> > > > switches to annotation-based injection.
> > > >
> > > > I'm not sure this is possible in .NET though.
> > > >
> > > > -Val
> > > >
> > > > On Tue, Oct 19, 2021 at 11:47 AM Pavel Pereslegin <xxt...@gmail.com>
> wrote:
> > > >
> > > >>> Removing parameters from a public interface method is a breaking
> change,
> > > >>> or do you mean something else?
> > > >>
> > > >> Sorry, I meant that we can inject the service context, but leave it
> > > >> available in the init/execute/cancel methods and add a default
> "no-op"
> > > >> implementation in the interface for them. Can we do this?
> > > >>
> > > >>> Regarding .NET - let's have a separate ticket for that?
> > > >> If we decide to "inject" a service context - this should be done in
> a
> > > >> separate ticket.
> > > >> If you are talking about "proxy service context" - I can split it
> into
> > > >> 3 parts (java, Net, and thin clients)
> > > >>
> > > >> вт, 19 окт. 2021 г. в 21:23, Pavel Tupitsyn <ptupit...@apache.org>:
> > > >>>
> > > >>> Pavel,
> > > >>>
> > > >>>> From my point of view, this should not break anything
> > > >>> Removing parameters from a public interface method is a breaking
> change,
> > > >>> or do you mean something else?
> > > >>>
> > > >>> Regarding .NET - let's have a separate ticket for that?
> > > >>> We can discuss and implement Java changes first.
> > > >>>
> > > >>> On Tue, Oct 19, 2021 at 8:27 PM Pavel Pereslegin <xxt...@gmail.com
> >
> > > >> wrote:
> > > >>>
> > > >>>> Thanks a lot for your suggestions.
> > > >>>>
> > > >>>>> We might consider injecting the ServiceContext instead of
> passing it
> > > >> to
> > > >>>>> IgniteService methods, but I believe this will be a breaking
> change?
> > > >>>>
> > > >>>> From my point of view, this should not break anything. We can
> inject a
> > > >>>> service context when initializing a service and keep it
> accessible in
> > > >>>> state transition methods (init/execute/cancel).
> > > >>>> Currently, in .Net ServiceContext doesn't share the same
> instance, but
> > > >>>> this can be reworked - for example, we can store the service
> context
> > > >>>> (with a reference to the service) in the resource registry
> instead of
> > > >>>> the service itself.
> > > >>>>
> > > >>>> But I don't see much usability improvement with such a feature if
> the
> > > >>>> user still needs to implement state transition methods. I think it
> > > >>>> would be nice to add default "no-op" implementations for them.
> > > >>>> Unfortunately, we are currently unable to do the same in .Net
> because
> > > >>>> such a feature is not supported in C# 4.0 (it's available in C#
> 8.0).
> > > >>>>
> > > >>>> Can we add default "no-op" implementations for init/execute/cancel
> > > >>>> methods in Java and leave them unchanged in .Net?
> > > >>>>
> > > >>>> вт, 19 окт. 2021 г. в 18:51, Valentin Kulichenko
> > > >>>> <valentin.kuliche...@gmail.com>:
> > > >>>>>
> > > >>>>> I support #2, because we already have the ServiceContext. Having
> > > >>>>> both ServiceContext and @ServiceRequestContextResource that
> injects
> > > >> some
> > > >>>>> function (or any other mechanism for that matter) will be VERY
> > > >> confusing.
> > > >>>>> Let's keep it simple.
> > > >>>>>
> > > >>>>> At the same time, I do agree with Nikolay that injection is the
> > > >> approach
> > > >>>>> taken across the platform, so I'm not sure why we are not using
> it
> > > >> here.
> > > >>>> We
> > > >>>>> might consider injecting the ServiceContext instead of passing
> it to
> > > >>>>> IgniteService methods, but I believe this will be a breaking
> change?
> > > >>>>>
> > > >>>>> -Val
> > > >>>>>
> > > >>>>> On Tue, Oct 19, 2021 at 4:49 AM Ivan Daschinsky <
> ivanda...@gmail.com
> > > >>>
> > > >>>> wrote:
> > > >>>>>
> > > >>>>>> I am for limiting types of attributes values only to UTF-8
> strings
> > > >> and
> > > >>>>>> bytearrays.
> > > >>>>>> Also, I agree with Pavel, (2) is clear and without any
> reflection.
> > > >>>>>>
> > > >>>>>> вт, 19 окт. 2021 г. в 14:18, Nikolay Izhikov <
> nizhi...@apache.org
> > > >>> :
> > > >>>>>>
> > > >>>>>>> I like (1) options.
> > > >>>>>>>
> > > >>>>>>>   @ServiceRequestContextResource
> > > >>>>>>>   private Function<String, Object> ctxFunc;
> > > >>>>>>>
> > > >>>>>>> Because, we use this style of API for injection of other
> > > >> resources -
> > > >>>>>>> logger, ignite instance, etc.
> > > >>>>>>> It may be confusing for the user to use several API styles for
> > > >>>> solving
> > > >>>>>>> similar tasks.
> > > >>>>>>>
> > > >>>>>>>
> > > >>>>>>>> 19 окт. 2021 г., в 11:04, Pavel Tupitsyn <
> ptupit...@apache.org
> > > >>>
> > > >>>>>>> написал(а):
> > > >>>>>>>>
> > > >>>>>>>> (2) seems to be the cleanest and most discoverable to me,
> > > >>>>>>>> also simpler to implement (no reflection necessary).
> > > >>>>>>>>
> > > >>>>>>>> But existing ServiceContext properties are for the entire
> > > >>>> instance, not
> > > >>>>>>> for
> > > >>>>>>>> the current call.
> > > >>>>>>>> So, to make it clear and obvious, let's do
> > > >>>>>>>> ServiceContext.currentCallContext().attribute(...).
> > > >>>>>>>>
> > > >>>>>>>> On Mon, Oct 18, 2021 at 7:20 PM Pavel Pereslegin <
> > > >> xxt...@gmail.com
> > > >>>>>
> > > >>>>>>> wrote:
> > > >>>>>>>>
> > > >>>>>>>>> Folks,
> > > >>>>>>>>>
> > > >>>>>>>>> I agree with Ivan that we can improve the user experience in
> > > >>>> Ignite
> > > >>>>>>>>> services by adding support for "middleware".
> > > >>>>>>>>> And as a first step, we need to pass the "caller context" to
> > > >> the
> > > >>>>>>> service.
> > > >>>>>>>>>
> > > >>>>>>>>> I see the following API options for reading this "context"
> > > >> inside
> > > >>>> a
> > > >>>>>>>>> service:
> > > >>>>>>>>> (please see "API proposal" section in Jira [1] for full
> > > >> formatted
> > > >>>>>>> examples)
> > > >>>>>>>>>
> > > >>>>>>>>> 1. Using a custom annotation (ServiceRequestContextResource)
> > > >> and
> > > >>>>>>>>> reading context attributes with a function.
> > > >>>>>>>>>
> > > >>>>>>>>>   @ServiceRequestContextResource
> > > >>>>>>>>>   private Function<String, Object> ctxFunc;
> > > >>>>>>>>>
> > > >>>>>>>>>   public void serviceMethod() {
> > > >>>>>>>>>       String login = (String)ctxFunc.apply("login");
> > > >>>>>>>>>   }
> > > >>>>>>>>>
> > > >>>>>>>>> 2. Using a new method of the existing ServiceContext.
> > > >>>>>>>>>
> > > >>>>>>>>>   private ServiceContext svcCtx;
> > > >>>>>>>>>
> > > >>>>>>>>>   public void init(ServiceContext svcCtx) {
> > > >>>>>>>>>       this.svcCtx = svcCtx;
> > > >>>>>>>>>   }
> > > >>>>>>>>>
> > > >>>>>>>>>   public void serviceMethod() {
> > > >>>>>>>>>       String login = svcCtx.attribute("login");
> > > >>>>>>>>>       // and/or
> > > >>>>>>>>>       String login =
> > > >> (String)svcCtx.attributes().get("login");
> > > >>>>>>>>>   }
> > > >>>>>>>>>
> > > >>>>>>>>>
> > > >>>>>>>>> The next two options require wrapping Map<String, Object>
> > > >> into a
> > > >>>> new
> > > >>>>>>>>> ServiceRequestContext class.
> > > >>>>>>>>>
> > > >>>>>>>>> 3. Read context "wrapper" using special annotation and
> > > >> supplier.
> > > >>>>>>>>>
> > > >>>>>>>>>   @ServiceRequestContextResource
> > > >>>>>>>>>   private Supplier<ServiceRequestContext> ctxSupplier;
> > > >>>>>>>>>
> > > >>>>>>>>>   public void serviceMethod() {
> > > >>>>>>>>>       String login = ctxSupplier.get().attribute("login");
> > > >>>>>>>>>   }
> > > >>>>>>>>>
> > > >>>>>>>>> 4. Using the special static method of the "wrapper" class.
> > > >>>>>>>>>
> > > >>>>>>>>>   public void serviceMethod() {
> > > >>>>>>>>>       String login =
> > > >>>>>>> ServiceRequestContext.current().attribute("login");
> > > >>>>>>>>>   }
> > > >>>>>>>>>
> > > >>>>>>>>> Let's discuss which one is the way to go.
> > > >>>>>>>>>
> > > >>>>>>>>> [1] https://issues.apache.org/jira/browse/IGNITE-15572
> > > >>>>>>>>>
> > > >>>>>>>>> вт, 12 окт. 2021 г. в 13:51, Ivan Daschinsky <
> > > >> ivanda...@gmail.com
> > > >>>>> :
> > > >>>>>>>>>>
> > > >>>>>>>>>> Hi, Val
> > > >>>>>>>>>>
> > > >>>>>>>>>>>> The examples you mentioned are more related to internal
> > > >>>> activities
> > > >>>>>>>>> (e.g.,
> > > >>>>>>>>>>>> if authentication is handled by an Ignite server node, it
> > > >> can
> > > >>>>>> create
> > > >>>>>>>>> its
> > > >>>>>>>>>>>> internal context for a connection - this is certainly
> > > >>>> reasonable).
> > > >>>>>>> I'm
> > > >>>>>>>>>> only
> > > >>>>>>>>>>>> worried about exposing this to the end user.
> > > >>>>>>>>>>
> > > >>>>>>>>>> I'm talking about not Ignite auth, but external auth. Here I
> > > >> am
> > > >>>>>>>>> considering
> > > >>>>>>>>>> Ignite Service Grid as a microservice platform.
> > > >>>>>>>>>> Authentication microservice can be not related to Ignite at
> > > >> all,
> > > >>>> but
> > > >>>>>>>>> author
> > > >>>>>>>>>> of service may want to retrieve or authenticate user by
> > > >> user_id,
> > > >>>> that
> > > >>>>>>> is
> > > >>>>>>>>>> provided in request headers or context in jwt token, for
> > > >> example.
> > > >>>>>>>>>>
> > > >>>>>>>>>> The same is for tracing or metrics. Ignite internal
> > > >> mechanisms
> > > >>>> here
> > > >>>>>>>>> cannot
> > > >>>>>>>>>> help at all, because there is no context related to user's
> > > >> code.
> > > >>>>>>>>>>
> > > >>>>>>>>>> If we want to leave Ignite Service Grid as dump as possible,
> > > >> it
> > > >>>> is
> > > >>>>>> ok.
> > > >>>>>>>>> But
> > > >>>>>>>>>> therefore it cannot compete with more functional variants.
> > > >>>>>>>>>>
> > > >>>>>>>>>> But just adding request headers at first step and custom
> > > >>>> interceptors
> > > >>>>>>>>>> (client and server side)  we can give to user's of Ignite
> > > >> Service
> > > >>>>>> Grid
> > > >>>>>>> a
> > > >>>>>>>>>> lot of opportunities.
> > > >>>>>>>>>>
> > > >>>>>>>>>> There is an example of golang grpc middlewares -- see how
> > > >> many
> > > >>>>>>>>> interesting
> > > >>>>>>>>>> use cases here:
> > > >>>>>>>>>> https://github.com/grpc-ecosystem/go-grpc-middleware
> > > >>>>>>>>>>
> > > >>>>>>>>>> вт, 12 окт. 2021 г. в 07:31, Valentin Kulichenko <
> > > >>>>>>>>>> valentin.kuliche...@gmail.com>:
> > > >>>>>>>>>>
> > > >>>>>>>>>>> Ivan,
> > > >>>>>>>>>>>
> > > >>>>>>>>>>> I'm a bit confused :) Unless I misread the initial
> > > >> suggestion,
> > > >>>> the
> > > >>>>>>>>> idea is
> > > >>>>>>>>>>> to provide a public API to create the context. In other
> > > >> words,
> > > >>>> it
> > > >>>>>> will
> > > >>>>>>>>> be
> > > >>>>>>>>>>> up to the end user to create this context properly, which
> > > >>>> affects
> > > >>>>>> the
> > > >>>>>>>>>>> business code - and that's exactly where I see an issue.
> > > >>>>>>>>>>>
> > > >>>>>>>>>>> The examples you mentioned are more related to internal
> > > >>>> activities
> > > >>>>>>>>> (e.g.,
> > > >>>>>>>>>>> if authentication is handled by an Ignite server node, it
> > > >> can
> > > >>>> create
> > > >>>>>>>>> its
> > > >>>>>>>>>>> internal context for a connection - this is certainly
> > > >>>> reasonable).
> > > >>>>>> I'm
> > > >>>>>>>>> only
> > > >>>>>>>>>>> worried about exposing this to the end user.
> > > >>>>>>>>>>>
> > > >>>>>>>>>>> Maybe you can pick one of the use cases that you think
> would
> > > >>>> benefit
> > > >>>>>>>>> from
> > > >>>>>>>>>>> this feature the most, and provide a little more detail?
> How
> > > >>>> would
> > > >>>>>> you
> > > >>>>>>>>> like
> > > >>>>>>>>>>> to see the use case to be addressed and what is currently
> > > >>>> missing?
> > > >>>>>>>>>>>
> > > >>>>>>>>>>> Also, just to be clear: I'm not necessarily against the
> > > >>>> suggestion,
> > > >>>>>>> and
> > > >>>>>>>>>>> it's highly unlikely that I will want to veto it if you or
> > > >>>> someone
> > > >>>>>>> else
> > > >>>>>>>>>>> will decide to implement it. Just expressing my concerns.
> > > >>>>>>>>>>>
> > > >>>>>>>>>>> -Val
> > > >>>>>>>>>>>
> > > >>>>>>>>>>> On Sun, Oct 10, 2021 at 11:52 PM Nikolay Izhikov <
> > > >>>>>> nizhi...@apache.org
> > > >>>>>>>>
> > > >>>>>>>>>>> wrote:
> > > >>>>>>>>>>>
> > > >>>>>>>>>>>> +1 to have service proxy context.
> > > >>>>>>>>>>>>
> > > >>>>>>>>>>>>> 11 окт. 2021 г., в 09:43, Ivan Daschinsky <
> > > >>>> ivanda...@gmail.com>
> > > >>>>>>>>>>>> написал(а):
> > > >>>>>>>>>>>>>
> > > >>>>>>>>>>>>> Val, Pavel both of you are right, but on the other hand
> > > >> there
> > > >>>> are
> > > >>>>>>>>> some
> > > >>>>>>>>>>>>> other tasks
> > > >>>>>>>>>>>>>
> > > >>>>>>>>>>>>> 1. Distributed tracing.
> > > >>>>>>>>>>>>> 2. Custom metrics/measurements
> > > >>>>>>>>>>>>> 3. Auth and some related tasks (i.e. ingests full User
> > > >> info by
> > > >>>>>>>>> calling
> > > >>>>>>>>>>>> some
> > > >>>>>>>>>>>>> auth service in middleware).
> > > >>>>>>>>>>>>>
> > > >>>>>>>>>>>>> Do you both think that this is a good idea in business
> > > >> code?
> > > >>>>>>>>>>>>>
> > > >>>>>>>>>>>>> Without this functionality, our service grid cannot
> > > >> compete
> > > >>>> with
> > > >>>>>>>>> grpc
> > > >>>>>>>>>>> and
> > > >>>>>>>>>>>>> others as microservice framework, unfortunately.
> > > >>>>>>>>>>>>>
> > > >>>>>>>>>>>>> But if we introduce limited support for this "request
> > > >>>> headers", it
> > > >>>>>>>>> can
> > > >>>>>>>>>>>>> drastically improves this aspects of our service grid
> > > >>>> framework.
> > > >>>>>>>>>>>>>
> > > >>>>>>>>>>>>>
> > > >>>>>>>>>>>>> пн, 11 окт. 2021 г. в 00:48, Valentin Kulichenko <
> > > >>>>>>>>>>>>> valentin.kuliche...@gmail.com>:
> > > >>>>>>>>>>>>>
> > > >>>>>>>>>>>>>> I agree with Pavel. The suggested approach is indeed
> > > >> utilized
> > > >>>>>>>>> quite
> > > >>>>>>>>>>>>>> frequently, but it's inherently error-prone.
> > > >>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>> The main issue is that it creates implicit assumptions
> > > >> about
> > > >>>> the
> > > >>>>>>>>>>>> behavior
> > > >>>>>>>>>>>>>> of both the service and the user's code. For example, if
> > > >> the
> > > >>>>>>>>> user's
> > > >>>>>>>>>>> code
> > > >>>>>>>>>>>>>> must provide a username, what if it doesn't? I assume it
> > > >>>> will get
> > > >>>>>>>>> an
> > > >>>>>>>>>>>> error,
> > > >>>>>>>>>>>>>> which is very counterintuitive. Even more importantly,
> > > >> how
> > > >>>> should
> > > >>>>>>>>> one
> > > >>>>>>>>>>>> learn
> > > >>>>>>>>>>>>>> about this requirement in the first place? It is not
> > > >>>> reflected in
> > > >>>>>>>>> the
> > > >>>>>>>>>>>> API
> > > >>>>>>>>>>>>>> in any way - and that's a big problem.
> > > >>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>> The fact that the service implementor needs to update
> > > >> the API
> > > >>>>>>>>> methods
> > > >>>>>>>>>>>> when
> > > >>>>>>>>>>>>>> such requirements are introduced is actually a good
> > > >> thing,
> > > >>>> in my
> > > >>>>>>>>>>>> opinion.
> > > >>>>>>>>>>>>>> This forces the developer to stop and think about how
> the
> > > >>>> updated
> > > >>>>>>>>> API
> > > >>>>>>>>>>>>>> should look like and how to make sure it's
> > > >>>> backward-compatible
> > > >>>>>> (or
> > > >>>>>>>>>>> not,
> > > >>>>>>>>>>>> in
> > > >>>>>>>>>>>>>> case the new requirements are mandatory). Doing this
> > > >> through
> > > >>>> an
> > > >>>>>>>>>>> external
> > > >>>>>>>>>>>>>> context is basically the equivalent of saying "let the
> > > >> end
> > > >>>> user
> > > >>>>>>>>> deal
> > > >>>>>>>>>>>> with
> > > >>>>>>>>>>>>>> this". Not a good practice, in my view.
> > > >>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>> Conversely, passing everything exclusively via method
> > > >>>> arguments
> > > >>>>>>>>>>>> guarantees
> > > >>>>>>>>>>>>>> that:
> > > >>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>> - The user's code is always compliant with the service
> > > >>>>>>>>> contract. You
> > > >>>>>>>>>>>>>> can't "forget" to pass something to the service.
> > > >>>>>>>>>>>>>> - Any changes in the service contract
> > > >> (backward-compatible
> > > >>>> or
> > > >>>>>>>>>>>> otherwise)
> > > >>>>>>>>>>>>>> are explicitly reflected in the API.
> > > >>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>> -Val
> > > >>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>> On Sun, Oct 10, 2021 at 6:21 AM Pavel Tupitsyn <
> > > >>>>>>>>> ptupit...@apache.org>
> > > >>>>>>>>>>>>>> wrote:
> > > >>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>> Ivan,
> > > >>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>> Yes, this approach is used by some other systems, and
> > > >>>> still, I
> > > >>>>>>>>> don't
> > > >>>>>>>>>>>> like
> > > >>>>>>>>>>>>>>> it very much.
> > > >>>>>>>>>>>>>>> Let's hear more opinions.
> > > >>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>> On Sat, Oct 9, 2021 at 9:00 PM Ivan Daschinsky <
> > > >>>>>>>>> ivanda...@gmail.com>
> > > >>>>>>>>>>>>>>> wrote:
> > > >>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>> Hi.
> > > >>>>>>>>>>>>>>>> Pavel T., Ok, http rest dosn't have the clean design,
> > > >> in
> > > >>>> your
> > > >>>>>>>>>>> opinion.
> > > >>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>> But what about grpc? The same?
> > > >>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>> As for me, it is ok to pass additional parameters as
> > > >> list
> > > >>>> of
> > > >>>>>>>>>>> key-value
> > > >>>>>>>>>>>>>>>> pairs with keys as strings and values as bytearrays or
> > > >>>> strings.
> > > >>>>>>>>> It
> > > >>>>>>>>>>> is
> > > >>>>>>>>>>>>>> ok
> > > >>>>>>>>>>>>>>> to
> > > >>>>>>>>>>>>>>>> allow user to set up middlewares for services and
> > > >> allow to
> > > >>>>>>>>> enrich
> > > >>>>>>>>>>>>>> request
> > > >>>>>>>>>>>>>>>> context in this middlewares. It is very common
> approach
> > > >>>>>>>>> everywhere
> > > >>>>>>>>>>> and
> > > >>>>>>>>>>>>>> is
> > > >>>>>>>>>>>>>>>> very useful in distributed systems. The use cases are
> > > >> so
> > > >>>>>>>>> obvious,
> > > >>>>>>>>>>>>>> aren't
> > > >>>>>>>>>>>>>>>> they?
> > > >>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>> сб, 9 окт. 2021 г., 20:14 Pavel Tupitsyn <
> > > >>>> ptupit...@apache.org
> > > >>>>>>>>>> :
> > > >>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>> Pavel,
> > > >>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>> Thanks for the explanation, I understand the use
> > > >> cases.
> > > >>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>> in REST service, he can set such parameters in
> > > >> request
> > > >>>>>> headers
> > > >>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>> I don't consider HTTP-based services as a good
> > > >> example of
> > > >>>> a
> > > >>>>>>>>>>>>>>>>> clean architecture.
> > > >>>>>>>>>>>>>>>>> Data can be passed in URL parameters, in headers, and
> > > >> in
> > > >>>> body,
> > > >>>>>>>>> and
> > > >>>>>>>>>>>>>> each
> > > >>>>>>>>>>>>>>>> of
> > > >>>>>>>>>>>>>>>>> those ways has its own limitations.
> > > >>>>>>>>>>>>>>>>> There is no obvious correct way to do things.
> > > >>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>> Ambient state is not obvious and the API looks
> > > >> confusing
> > > >>>>>> even
> > > >>>>>>>>>>>>>>> though I
> > > >>>>>>>>>>>>>>>>> understand our services stack quite well both in Java
> > > >> and
> > > >>>> .NET
> > > >>>>>>>>>>>>>>>>>> Can you clarify please?
> > > >>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>> The proposed API adds a "side channel" for the data.
> > > >>>>>>>>>>>>>>>>> Some is passed as arguments, which is obvious, and
> > > >> some
> > > >>>>>> becomes
> > > >>>>>>>>>>>>>>> magically
> > > >>>>>>>>>>>>>>>>> available on the server side through some external
> > > >>>> context.
> > > >>>>>>>>>>>>>>>>> - You have to know about the context
> > > >>>>>>>>>>>>>>>>> - You have to understand that the context is only
> > > >>>> available
> > > >>>>>>>>> during
> > > >>>>>>>>>>>>>> the
> > > >>>>>>>>>>>>>>>>> method call (can't use it in some background logic)
> > > >>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>> In my opinion, this is a bit too clever. I'm a fan of
> > > >> the
> > > >>>>>>>>>>> functional
> > > >>>>>>>>>>>>>>>>> programming approach where everything you need is
> > > >> passed
> > > >>>> as
> > > >>>>>>>>>>>>>> arguments.
> > > >>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>> On Fri, Oct 8, 2021 at 4:29 PM Pavel Pereslegin <
> > > >>>>>>>>> xxt...@gmail.com>
> > > >>>>>>>>>>>>>>>> wrote:
> > > >>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>> Igor, Pavel.
> > > >>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>> Why can not a user implement such context on
> > > >> application
> > > >>>>>>>>> level? I
> > > >>>>>>>>>>>>>>>>>> believe Ignite provides all necessary tools for
> that.
> > > >>>>>>>>>>>>>>>>>> The user wants to trace the source of the service
> > > >> call.
> > > >>>> For
> > > >>>>>>>>>>>>>> example,
> > > >>>>>>>>>>>>>>> a
> > > >>>>>>>>>>>>>>>>>> service must log the name of the user who made the
> > > >> calls
> > > >>>> of
> > > >>>>>>>>> the
> > > >>>>>>>>>>>>>>>>>> service. For now, there's no possibility to do that
> > > >>>> without
> > > >>>>>>>>>>>>>> modifying
> > > >>>>>>>>>>>>>>>>>> the service interface and implementation. Moreover,
> > > >> the
> > > >>>> user
> > > >>>>>>>>> must
> > > >>>>>>>>>>>>>>>>>> modify all methods of service to pass this
> > > >> parameter. For
> > > >>>>>>>>> example,
> > > >>>>>>>>>>>>>> in
> > > >>>>>>>>>>>>>>>>>> REST service, he can set such parameters in request
> > > >>>> headers,
> > > >>>>>>>>> why
> > > >>>>>>>>>>> we
> > > >>>>>>>>>>>>>>>>>> can't provide such usability in Ignite.
> > > >>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>> This will reduce the performance of all calls
> > > >>>>>>>>>>>>>>>>>> This feature is optional, if the context is not
> > > >> passed -
> > > >>>> then
> > > >>>>>>>>>>>>>> there's
> > > >>>>>>>>>>>>>>>>>> shouldn't be any performance difference.
> > > >>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>> Ambient state is not obvious and the API looks
> > > >> confusing
> > > >>>>>> even
> > > >>>>>>>>>>>>>>> though
> > > >>>>>>>>>>>>>>>> I
> > > >>>>>>>>>>>>>>>>>> understand our services stack quite well both in
> > > >> Java and
> > > >>>>>> .NET
> > > >>>>>>>>>>>>>>>>>> Can you clarify please?
> > > >>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>> пт, 8 окт. 2021 г. в 15:46, Pavel Tupitsyn <
> > > >>>>>>>>> ptupit...@apache.org
> > > >>>>>>>>>>>> :
> > > >>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>> Agree with Igor.
> > > >>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>> I'm not sure this feature is a good fit for Ignite.
> > > >>>>>>>>>>>>>>>>>>> Ignite should not be responsible for such a
> > > >> high-level
> > > >>>>>>>>> concept,
> > > >>>>>>>>>>>>>>> this
> > > >>>>>>>>>>>>>>>>>> should
> > > >>>>>>>>>>>>>>>>>>> be on the application side instead.
> > > >>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>> - As Eduard noted, it is hard to make this
> type-safe
> > > >>>>>>>>>>>>>>>>>>> - Ambient state is not obvious and the API looks
> > > >>>> confusing
> > > >>>>>>>>> even
> > > >>>>>>>>>>>>>>>> though
> > > >>>>>>>>>>>>>>>>> I
> > > >>>>>>>>>>>>>>>>>>> understand our services stack quite well both in
> > > >> Java
> > > >>>> and
> > > >>>>>>>>> .NET
> > > >>>>>>>>>>>>>>>>>>> - This will reduce the performance of all calls
> > > >>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>> On Fri, Oct 8, 2021 at 3:44 PM Igor Sapego <
> > > >>>>>>>>> isap...@apache.org>
> > > >>>>>>>>>>>>>>>> wrote:
> > > >>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>> Hi guys,
> > > >>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>> Why can not a user implement such context on
> > > >>>> application
> > > >>>>>>>>> level?
> > > >>>>>>>>>>>>>>>>>>>> I believe Ignite provides all necessary tools for
> > > >> that.
> > > >>>>>> User
> > > >>>>>>>>>>>>>> can
> > > >>>>>>>>>>>>>>>> just
> > > >>>>>>>>>>>>>>>>>>>> implement such a context as user type and pass it
> > > >> to
> > > >>>>>>>>> services
> > > >>>>>>>>>>>>>>> they
> > > >>>>>>>>>>>>>>>>>>>> need. Are the arguments why would Ignite need a
> > > >>>> separate
> > > >>>>>>>>>>>>>> feature
> > > >>>>>>>>>>>>>>>>>>>> for such a use case?
> > > >>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>> Best Regards,
> > > >>>>>>>>>>>>>>>>>>>> Igor
> > > >>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>> On Fri, Oct 8, 2021 at 2:17 PM Eduard Rakhmankulov
> > > >> <
> > > >>>>>>>>>>>>>>>>>> erixon...@gmail.com>
> > > >>>>>>>>>>>>>>>>>>>> wrote:
> > > >>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>> I am not aware .NET capabilities, but as I can
> see
> > > >>>> service
> > > >>>>>>>>>>>>>> must
> > > >>>>>>>>>>>>>>>> be
> > > >>>>>>>>>>>>>>>>>>>>> implemented in *java* and even if can't serialize
> > > >>>> other
> > > >>>>>>>>> that
> > > >>>>>>>>>>>>>>> Map
> > > >>>>>>>>>>>>>>>> on
> > > >>>>>>>>>>>>>>>>>> .NET
> > > >>>>>>>>>>>>>>>>>>>>> side, on java side we can wrap this map with
> > > >> provided
> > > >>>>>>>>>>>>>>>> TypedContext
> > > >>>>>>>>>>>>>>>>>>>> (context
> > > >>>>>>>>>>>>>>>>>>>>> should be convertible from map in this case).
> > > >>>>>>>>>>>>>>>>>>>>> That leads to a situation when Java can use
> > > >>>> TypedContext
> > > >>>>>>>>> but
> > > >>>>>>>>>>>>>>>> other
> > > >>>>>>>>>>>>>>>>>>>> clients
> > > >>>>>>>>>>>>>>>>>>>>> can't. I believe that the majority of services
> > > >> users
> > > >>>> are
> > > >>>>>>>>>>>>>> using
> > > >>>>>>>>>>>>>>>> Java
> > > >>>>>>>>>>>>>>>>>> and
> > > >>>>>>>>>>>>>>>>>>>> it
> > > >>>>>>>>>>>>>>>>>>>>> should be taken in accordance.
> > > >>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>> P.S. I think it is possible to send plain objects
> > > >> from
> > > >>>>>> .NET
> > > >>>>>>>>>>>>>>>> context
> > > >>>>>>>>>>>>>>>>>> to
> > > >>>>>>>>>>>>>>>>>>>>> cluster.
> > > >>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>> Best regards, Ed
> > > >>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>> On Fri, 8 Oct 2021 at 14:40, Pavel Pereslegin <
> > > >>>>>>>>>>>>>>> xxt...@gmail.com>
> > > >>>>>>>>>>>>>>>>>> wrote:
> > > >>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>> Hi, Eduard!
> > > >>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>> Thanks for your feedback.
> > > >>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>> The idea sounds very good, but don't forget
> > > >> about the
> > > >>>>>>>>>>>>>>> platform
> > > >>>>>>>>>>>>>>>>>>>> services.
> > > >>>>>>>>>>>>>>>>>>>>>> For example, we may call Java service from .Net
> > > >> and
> > > >>>>>>>>>>>>>>> vice-versa.
> > > >>>>>>>>>>>>>>>>> I'm
> > > >>>>>>>>>>>>>>>>>>>>>> not sure if the context can be implemented as a
> > > >>>> custom
> > > >>>>>>>>>>>>>> class
> > > >>>>>>>>>>>>>>>>>> (instead
> > > >>>>>>>>>>>>>>>>>>>>>> of Map/Dictionary) in this case.
> > > >>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>> пт, 8 окт. 2021 г. в 14:21, Eduard Rakhmankulov
> <
> > > >>>>>>>>>>>>>>>>>> erixon...@gmail.com>:
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> Hi, Pavel
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> Is it possible to provide type-safe API for
> > > >>>>>>>>>>>>>>>>> ServiceProxyContext ?
> > > >>>>>>>>>>>>>>>>>>>>>>> I think constructions like int arg1 =
> > > >>>>>>>>>>>>>>> ctx.attribute("arg1");
> > > >>>>>>>>>>>>>>>>> are
> > > >>>>>>>>>>>>>>>>>>>> error
> > > >>>>>>>>>>>>>>>>>>>>>>> prone.
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> Can we make something like this :
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> //Signature with two generic params which allow
> > > >> the
> > > >>>>>>>>>>>>>>> compiler
> > > >>>>>>>>>>>>>>>> to
> > > >>>>>>>>>>>>>>>>>> check
> > > >>>>>>>>>>>>>>>>>>>>>>> if the service will be called with the wrong
> > > >> type
> > > >>>>>>>>>>>>>> context.
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> public <T extends ContextedWith<CtxType>,
> > > >> CtxType> T
> > > >>>>>>>>>>>>>>>>>>>>>>> serviceProxyTyped(ClusterGroup prj, String
> name,
> > > >>>> Class<?
> > > >>>>>>>>>>>>>>>> super
> > > >>>>>>>>>>>>>>>>> T
> > > >>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> srvcCls, CtxType optCtx, boolean sticky, long
> > > >>>> timeout)
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> //new interface which services with scoped
> > > >> context
> > > >>>>>> should
> > > >>>>>>>>>>>>>>>>>> implement
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> public interface ContextedWith<T> {
> > > >>>>>>>>>>>>>>>>>>>>>>> T getCtx();
> > > >>>>>>>>>>>>>>>>>>>>>>> }
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> // implementation can delegate to Map-like
> > > >> context
> > > >>>> or be
> > > >>>>>>>>>>>>>>>> POJO.
> > > >>>>>>>>>>>>>>>>>>>>>>> interface MyServiceContext {
> > > >>>>>>>>>>>>>>>>>>>>>>> int getArg1();
> > > >>>>>>>>>>>>>>>>>>>>>>> String getUserId();
> > > >>>>>>>>>>>>>>>>>>>>>>> }
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> class MyService implements
> > > >>>>>>>>>>>>>> ContextedWith<MyServiceContext>
> > > >>>>>>>>>>>>>>> {
> > > >>>>>>>>>>>>>>>>>>>>>>> void doThings() {
> > > >>>>>>>>>>>>>>>>>>>>>>> MyServiceContext ctx = getCtx();
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> System.out.println("ctx.getArg1() = " +
> > > >>>> ctx.getArg1());
> > > >>>>>>>>>>>>>>>>>>>>>>> }
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> @Override public MyServiceContext getCtx() {
> > > >>>>>>>>>>>>>>>>>>>>>>> return ServiceProxyContext.current();
> > > >>>>>>>>>>>>>>>>>>>>>>> }
> > > >>>>>>>>>>>>>>>>>>>>>>> }
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> WDYT?
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> Best regards, Ed.
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>> On Fri, 8 Oct 2021 at 13:26, Pavel Pereslegin <
> > > >>>>>>>>>>>>>>>>> xxt...@gmail.com>
> > > >>>>>>>>>>>>>>>>>>>>> wrote:
> > > >>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>>> Hello Igniters!
> > > >>>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>>> I want to implement a feature to support a
> > > >> custom
> > > >>>>>>>>>>>>>>> "caller"
> > > >>>>>>>>>>>>>>>>>> context
> > > >>>>>>>>>>>>>>>>>>>> in
> > > >>>>>>>>>>>>>>>>>>>>>>>> ignite services (see example in ticket
> > > >> description
> > > >>>>>>>>>>>>>> [1]).
> > > >>>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>>> Sometimes, when using Ignite services, it
> > > >> becomes
> > > >>>>>>>>>>>>>>> necessary
> > > >>>>>>>>>>>>>>>>> to
> > > >>>>>>>>>>>>>>>>>> pass
> > > >>>>>>>>>>>>>>>>>>>>>>>> custom parameters from the "request source" to
> > > >> the
> > > >>>>>>>>>>>>>>> service.
> > > >>>>>>>>>>>>>>>>>> This is
> > > >>>>>>>>>>>>>>>>>>>>>>>> most commonly used to track the origin of a
> > > >> service
> > > >>>>>>>>>>>>>> call
> > > >>>>>>>>>>>>>>>>> (user
> > > >>>>>>>>>>>>>>>>>> id,
> > > >>>>>>>>>>>>>>>>>>>>>>>> request id, session id eg see this user
> > > >> question
> > > >>>> [2]).
> > > >>>>>>>>>>>>>>>>>>>>>>>> At the moment, the only way to pass such
> > > >>>> parameters to
> > > >>>>>>>>>>>>>> a
> > > >>>>>>>>>>>>>>>>>> service is
> > > >>>>>>>>>>>>>>>>>>>>> by
> > > >>>>>>>>>>>>>>>>>>>>>>>> adding argument(s) to all called methods of
> the
> > > >>>>>>>>>>>>>> service,
> > > >>>>>>>>>>>>>>>>> which
> > > >>>>>>>>>>>>>>>>>>>> makes
> > > >>>>>>>>>>>>>>>>>>>>>>>> the code messy and also complicates
> > > >> development and
> > > >>>>>>>>>>>>>>>>>> maintenance.
> > > >>>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>>> I propose letting the user set a custom
> context
> > > >>>> for the
> > > >>>>>>>>>>>>>>>>> service
> > > >>>>>>>>>>>>>>>>>>>> proxy
> > > >>>>>>>>>>>>>>>>>>>>>>>> and implicitly pass that context to the
> methods
> > > >>>> being
> > > >>>>>>>>>>>>>>>> called.
> > > >>>>>>>>>>>>>>>>>> This
> > > >>>>>>>>>>>>>>>>>>>>>>>> function should not affect the execution of
> > > >> service
> > > >>>>>>>>>>>>>>> methods
> > > >>>>>>>>>>>>>>>>> in
> > > >>>>>>>>>>>>>>>>>> any
> > > >>>>>>>>>>>>>>>>>>>>> way
> > > >>>>>>>>>>>>>>>>>>>>>>>> unless the user has specified a context.
> > > >>>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>>> An example of using the proposed API [1].
> > > >>>>>>>>>>>>>>>>>>>>>>>> PoC (except thin clients) [3].
> > > >>>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>>> WDYT?
> > > >>>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>>> [1]
> > > >>>> https://issues.apache.org/jira/browse/IGNITE-15572
> > > >>>>>>>>>>>>>>>>>>>>>>>> [2]
> > > >>>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>
> > > >>>>>>>>>>>>
> > > >>>>>>>>>>>
> > > >>>>>>>>>
> > > >>>>>>>
> > > >>>>>>
> > > >>>>
> > > >>
> https://stackoverflow.com/questions/57459071/apache-ignite-service-grid-service-call-context
> > > >>>>>>>>>>>>>>>>>>>>>>>> [3]
> https://github.com/apache/ignite/pull/9440
> > > >>>>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>>
> > > >>>>>>>>>>>>>
> > > >>>>>>>>>>>>>
> > > >>>>>>>>>>>>> --
> > > >>>>>>>>>>>>> Sincerely yours, Ivan Daschinskiy
> > > >>>>>>>>>>>>
> > > >>>>>>>>>>>>
> > > >>>>>>>>>>>
> > > >>>>>>>>>>
> > > >>>>>>>>>>
> > > >>>>>>>>>> --
> > > >>>>>>>>>> Sincerely yours, Ivan Daschinskiy
> > > >>>>>>>>>
> > > >>>>>>>
> > > >>>>>>>
> > > >>>>>>
> > > >>>>>> --
> > > >>>>>> Sincerely yours, Ivan Daschinskiy
> > > >>>>>>
> > > >>>>
> > > >>
> > >
>
>

Reply via email to