sorry for being late with my answer.
* I used a custom IConsumerContainerSelector and i have overriden
the createContainer(..) method to bring my own
RegistrySharedObject implementation in use (I think that is
similar to what you proposed just without using Adapters)
* in my custom RegistrySharedObject I have overridden the
sendCallRequest(..) method and implemented a custom
createRequest(..) method to have a custom Request implementation
which actually adds additional metadata to the request (the
username doing the request in my case)
* I already had a custom IHostContainerSelector with a custom
createContainer(..) method, also to bring my custom
RegistrySharedObject in place
* in that custom RegistrySharedObject I have overridden the
executeRequest(..) method and a custom IProgressRunnable to
process the request
* and because here I get my custom request implementation I was
able to access the additional metadata easily and process the
request with the additional user information (kind of a "switch
user" call at server side)
After all I like this solution. Only small changes to get the
work done.
Hi Peter,
To explain what's happening wrt the adapters, here's the stack
on a client when the RegistrySharedObject is created:
Daemon Thread [RSA EndpointDescriptionLocator Dispatcher]
(Suspended (breakpoint at line 25 in
RemoteServiceContainerAdapterFactory))
owns: RemoteServiceContainerAdapterFactory (id=100)
RemoteServiceContainerAdapterFactory.createAdapter(ISharedObjectContainer,
Class, ID) line: 25
RemoteServiceContainerAdapterFactory(AbstractSharedObjectContainerAdapterFactory).getSharedObjectAdapter(ISharedObjectContainer,
Class) line: 93
RemoteServiceContainerAdapterFactory(AbstractSharedObjectContainerAdapterFactory).getContainerAdapter(IContainer,
Class) line: 51
RemoteServiceContainerAdapterFactory(AbstractContainerAdapterFactory).getAdapter(Object,
Class) line: 32
AdapterManager.getAdapter(Object, String, boolean) line:
340
AdapterManager.loadAdapter(Object, String) line: 367
TCPClientSOContainer(SOContainer).getAdapter(Class) line:
298
ConsumerContainerSelector(AbstractConsumerContainerSelector).createContainer(ContainerTypeDescription,
String, Map) line: 205
<stuff deleted>
You can see at bottom (ConsumerContainerSelector) that it's
creating a container of a particular type (ecf.generic.client)
which is passed in via the EndpointDescription sent from remote
service via discovery.
The ConsumerContainerSelector.createContainer method has this
call to
TCPClientSOContainer.getAdapter(IRemoteServiceContainerAdapter.class);
IRemoteServiceContainerAdapter adapter =
(IRemoteServiceContainerAdapter) container
.getAdapter(IRemoteServiceContainerAdapter.class);
The TCPClientSOContainerAdapter.getAdapter impl has this:
final IAdapterManager adapterManager =
ProviderPlugin.getDefault().getAdapterManager();
if (adapterManager == null)
return null;
return adapterManager.loadAdapter(this,
adapter.getName());
Which as you can see from the stack gets the
RemoteServiceContainerAdapterFactory (from
org.eclipse.ecf.provider.remoteservice plugin) which ends up
calling:
return new RegistrySharedObject();
In
org.eclipse.ecf.provider.remoteservice.generic.RemoteServiceContainerAdapterFactory.createAdapter(ISharedObjectContainer,
Class, ID)
If you were to *replace* or *extend* the TCPClientSOContainer,
you should be able to circumvent the adapter manager and
RemoteServiceContainerAdapterFactory/RegistrySharedObject by
*overriding* the impl of:
<your container class>.getAdapter(Class adapter)
You could modify your impl of getAdapter such that instead of
using the adapterManager to load an instance of
RemoteServiceContainerAdapterFactory (which is associated to
TCPClientSOContainer in
org.eclipse.ecf.provider.remoteservice/plugin.xml) you could
create an instance of your subclass of
RemoteServiceContainerAdapterFactory and return the object
returned from <your RemoteServiceContainerAdapterFacotry
instance>.getAdapter(<your container type>.this,
IRemoteServiceContainerAdapter.class) method. The
RemoteServiceContainerAdapterFactory instance>.getAdapter
ends up calling createAdapter.
Your RemoteServiceContainerAdapterFactory class impl could
override
org.eclipse.ecf.provider.remoteservice.generic.RemoteServiceContainerAdapterFactory.createAdapter(ISharedObjectContainer,
Class, ID to return a subclass of RegistryShareObject().
Does that make sense?
Basically
a) impl <your container type>.getAdapter
b) instead of using adapter manager/plugin.xml, create your own
instance of RemoteServiceContainerAdapterFactory
c) call it's getAdapter method
d) override your
RemoteServiceContainerAdapterFactory.createAdapter method to
return your subclass of RegistrySharedObject
Scott
On 3/23/2020 8:30 AM, Peter Hermsdorf
wrote:
Hi Scott,
On 21.03.2020 05:33, Scott Lewis
wrote:
Not
completely sure I understand what you are wanting to do, but
you could look at overriding these methods:
Sometime it's not that easy to describe the use-case, but in
fact your suggestions were helpful and pointed me in the right
direction.
If
you want to add to what's sent in every rpc, you could add to
the 1 (what client sends) and to 2 (what server received and
how processes it) by adding your meta-data to the Request
instance that's sent (has to be Serializable of course).
Does that help?
That helped. I'm thinking about replacing
SharedObjectMsg.createMsg(CALL_REQUEST, request)
with my own class which extends SharedObjectMsg and adds the
additional meta-data.
Currently I'm looking for the right place to register my own
RegistrySharedObject implementation on client side (on server
side i already have that).
On client side i already have a IConsumerContainerSelector with
an overriden createContainer method, but haven't found a good
point to intercept the object creation of RegistrySharedObject.
There is a lot of Adapter and Factory stuff going on ;)
Maybe you can suggest a good solution.
Thanks,
Peter