Home » Eclipse Projects » Riena » Client to Server remote access in a many to many topology
Client to Server remote access in a many to many topology [message #13291] |
Mon, 06 October 2008 13:01 ![Go to next message Go to next message](theme/Solstice/images/down.png) |
|
Hi,
In ORMF we support clients registering with multiple servers and any
given server of course will have many clients. I am considering how to
best achieve this with Riena remote services. Of course your Injection
service is not useful in this instance, because a given client will
have to define many remote services of the same type; one for each
server it is interested in.
I have been looking through the Riena code and it appears to me that my
client can create multiple RemoteServiceDescription, one for each
service on every server it is having a dialogue with. Is this the best
way to go about it? Can I cache these or is it better to create them on
demand and release after each service call?
Thanks,
Joel
--
Joel Rosi-Schwartz
Etish Limited [http://www.etish.org]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^...^
/ o,o \ The proud parents of Useme & ORMF
|) ::: (| Open Requirements Management Framework
====w=w==== [http://www.eclipse.org/ormf/]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
Re: Client to Server remote access in a many to many topology [message #13319 is a reply to message #13291] |
Tue, 07 October 2008 11:40 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
|
I've been doing some investigating and experimenting, and have come up
with the following that works:
void sendPing2() {
RemoteServiceFactory rsf = new RemoteServiceFactory();
Class<?> serviceInterface = IPingPong.class;
String url = "http://localhost:8080/hessian/PingPongWS"; //$NON-NLS-1$
String protocol = "hessian"; //$NON-NLS-1$
IRemoteServiceReference pingPongRef =
rsf.createProxy(serviceInterface, url, protocol,
"de.compeople.pingpong.config"); //$NON-NLS-1$
IPingPong pingPong = (IPingPong) pingPongRef.getServiceInstance();
Ping ping = new Ping();
ping.setText("AGAIN I ping you and you pong me"); //$NON-NLS-1$
Pong pong = pingPong.ping(ping);
System.out.println("PingPong::Client:: " + pong); //$NON-NLS-1$
}
I have several questions:
1. Is this pattern okay for production code?
2. Should I be caching the the IRemoteServiceReference or the service
instance between calls?
3. What is the the purpose of the config string, e.g.
"de.compeople.pingpong.config"?
Cheers,
Joel
--
Joel Rosi-Schwartz
Etish Limited [http://www.etish.org]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^...^
/ o,o \ The proud parents of Useme & ORMF
|) ::: (| Open Requirements Management Framework
====w=w==== [http://www.eclipse.org/ormf/]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
Re: Client to Server remote access in a many to many topology [message #13345 is a reply to message #13291] |
Tue, 07 October 2008 12:18 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Christian Campo![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=christian.campo%40compeople.de) Messages: 597 Registered: July 2009 |
Senior Member |
|
|
Joel,
I discussed your posting with Stefan Liebig and we were a little unsure what you concern and issues are. It seemed you
condensed all your ORMF knowledge into not so many lines of posting. So we are not sure what you are doing, and what you
like to achieve here. So a lot of guessing from our side but I try my best :-).
Yes you have multiple servers and I believe what you are saying is that each server has a list of services and they are
all the same. All servers run the same services.
Now in my world that is true but you wouldnt connect each client to each service wouldnt you ? Since the remote services
are accessed using HTTP and the remote service itself runs in Tomcat or whatever webcontainer, you would loadbalance
them using Apache. The client then calls the loadbalancer and the call gets routed to any of the services but only to
one. At least the way we use it, that remote service calls or webservice calls are stateless. So even if call 1 goes to
server A with service xx then call 2 that goes to server B with service xx will work because the server keeps no state
of the client. If you use security in Riena you can bring a session ticket with each call and the server will restore a
user context for each call but the server does not and I believe should not keep a state.
So the way we use it, is in other words that you have a loadbalancer in front of all your servers, the client call
http://localbalancer/hessian/CustomerSearch and the loadbalancer decides whether that mean
http://serverA/hessian/CustomerSearch or http://serverB/hessian/CustomerSearch. The result should and must be the same.
Maybe however (and remember we are guessing) your world is different and you have say split your customer database over
several servers and you need the client to call the CustomerSearch on each service and aggregate the result on the
client (reconsider your architecture here :-) ) then the client had to call each service one by one.
The good news is that you can use the Injector for all these cases. I didnt quit get why you couldnt. The Injector can
be used if a service for a specific type is singleton or if you have 100 of the same type. BTW the Injector has nothing
to do with remote services per se, the Injector gets also used for remoting when it injects the local proxies.
The Injector can inject only local OSGi Services into an instance. If you have multiple instances of one type, guess
what, it calls the bind method multiple times.
The remoting is NOT done by creating Remote Service Descriptions (that is an internal metadata format for the remote
services) but by calling the RemoteServiceFactory. The method createProxyAndRegister(...) can and will create a proxy
for a specific remote service and register it as a local OSGI service. The RemoteServiceFactory is called on the client,
you specify the URL, protocol and interface and it generate a protocol specific proxy and registers it as a local OSGi
Service. Then you call the Injector. You can also call just createProxy and register the proxy yourself and add some
metadata (i.e. the server where the service is located or else).
The Injector can not only inject single services or many many services (by multiple calls to bind) it can also filter by
looking at the metadata. So if your local proxy has an attribute saying "oh this service is in germany", "oh this
service is in italy", the injector can be told to only give you german services (because say they are closer).
The Injector can also use Ranking, a standard OSGi property, to give services priority. So the Injector can always
inject the service with the highest rank into your component.
Does this list give you some ideas ? Dont hesitate to ask more specific questions. We are trying to help but dont really
understand the problem as good as you do.
regards
christian campo
Joel Rosi-Schwartz schrieb:
> Hi,
>
> In ORMF we support clients registering with multiple servers and any
> given server of course will have many clients. I am considering how to
> best achieve this with Riena remote services. Of course your Injection
> service is not useful in this instance, because a given client will have
> to define many remote services of the same type; one for each server it
> is interested in.
>
> I have been looking through the Riena code and it appears to me that my
> client can create multiple RemoteServiceDescription, one for each
> service on every server it is having a dialogue with. Is this the best
> way to go about it? Can I cache these or is it better to create them on
> demand and release after each service call?
>
> Thanks,
> Joel
|
|
|
Re: Client to Server remote access in a many to many topology [message #13366 is a reply to message #13319] |
Tue, 07 October 2008 12:26 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Christian Campo![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=christian.campo%40compeople.de) Messages: 597 Registered: July 2009 |
Senior Member |
|
|
Hi Joel,
this looks like our communication pingpong example. Not sure what you modified. It works yes. You could now also use the
Injector after you called the RemoteServiceFactory to get the proxy injected like
Inject.service(IPingPong.class.getName()).into(this).andStar t(context);
It then requires a local method for bind and unbind
public void bind(IPingPong pingPong) {
Ping ping = new Ping();
ping.setText("AGAIN I ping you and you pong me"); //$NON-NLS-1$
Pong pong = pingPong.ping(ping);
System.out.println("PingPong::Client:: " + pong); //$NON-NLS-1$
}
When creating the proxy you should use a variable for the hostname to easily switch between different environments look at
org.eclipse.riena.communcation.sample.pingpong.client.config
2. If you inject Service you just keep the reference to the instance that you get injected, nothing else is required
3. forget the config id, it will go away
christian campo
Joel Rosi-Schwartz schrieb:
> I've been doing some investigating and experimenting, and have come up
> with the following that works:
>
> void sendPing2() {
> RemoteServiceFactory rsf = new RemoteServiceFactory();
> Class<?> serviceInterface = IPingPong.class;
> String url = "http://localhost:8080/hessian/PingPongWS";
> //$NON-NLS-1$
> String protocol = "hessian"; //$NON-NLS-1$
>
> IRemoteServiceReference pingPongRef =
> rsf.createProxy(serviceInterface, url, protocol,
> "de.compeople.pingpong.config"); //$NON-NLS-1$
> IPingPong pingPong = (IPingPong)
> pingPongRef.getServiceInstance();
>
> Ping ping = new Ping();
> ping.setText("AGAIN I ping you and you pong me"); //$NON-NLS-1$
>
> Pong pong = pingPong.ping(ping);
> System.out.println("PingPong::Client:: " + pong); //$NON-NLS-1$
>
> }
>
> I have several questions:
> 1. Is this pattern okay for production code?
> 2. Should I be caching the the IRemoteServiceReference or the
> service instance between calls?
> 3. What is the the purpose of the config string, e.g.
> "de.compeople.pingpong.config"?
>
> Cheers,
> Joel
|
|
|
Re: Client to Server remote access in a many to many topology [message #13386 is a reply to message #13345] |
Tue, 07 October 2008 13:03 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
|
Hi Christian,
Ah you are so right, I assumed a common "background of consciousness"
that obviously is not there :-) So lets try again!
This is not a load balance situation. Our situation is analogous to CVS
and SVN. We will have are millions of ORMF users (everyone loves
requirements;-) all over the world. There will be thousands of ORMF
servers, each serving up a different set of projects, all over the
world. Each server, however, has the same set of services, the
difference being that each has a unique set of projects it services.
Any user can (with appropriate authentication and authorisation)
connect to a server and open one or more projects to work on. At any
time a user may be connected to 0..n servers. This happens dynamically,
just as in CVS, by creating a new repository connection.
Is that a bit clearer? If you want me to expound further, I would be
very happy to tell you the whole story :-)
Your explanations below and your reply to my other message clarify
much. Thanks!
What I am pondering is why in THIS situation injection is superior to
simply obtaining the RemoteServiceReference (or the service instance)
directly. I love DI but in this case where the consumer is the creator
I miss the benefit. I am new to OSGi so if I am missing something about
the "OSGi way of doing things" please let me know.
Many thanks,
Joel
On 2008-10-07 13:18:11 +0100, Christian Campo
<christian.campo@compeople.de> said:
> Joel,
>
> I discussed your posting with Stefan Liebig and we were a little unsure
> what you concern and issues are. It seemed you condensed all your ORMF
> knowledge into not so many lines of posting. So we are not sure what
> you are doing, and what you like to achieve here. So a lot of guessing
> from our side but I try my best :-).
>
> Yes you have multiple servers and I believe what you are saying is that
> each server has a list of services and they are all the same. All
> servers run the same services.
>
> Now in my world that is true but you wouldnt connect each client to
> each service wouldnt you ? Since the remote services are accessed using
> HTTP and the remote service itself runs in Tomcat or whatever
> webcontainer, you would loadbalance them using Apache. The client then
> calls the loadbalancer and the call gets routed to any of the services
> but only to one. At least the way we use it, that remote service calls
> or webservice calls are stateless. So even if call 1 goes to server A
> with service xx then call 2 that goes to server B with service xx will
> work because the server keeps no state of the client. If you use
> security in Riena you can bring a session ticket with each call and the
> server will restore a user context for each call but the server does
> not and I believe should not keep a state.
>
> So the way we use it, is in other words that you have a loadbalancer in
> front of all your servers, the client call
> http://localbalancer/hessian/CustomerSearch and the loadbalancer
> decides whether that mean http://serverA/hessian/CustomerSearch or
> http://serverB/hessian/CustomerSearch. The result should and must be
> the same.
>
> Maybe however (and remember we are guessing) your world is different
> and you have say split your customer database over several servers and
> you need the client to call the CustomerSearch on each service and
> aggregate the result on the client (reconsider your architecture here
> :-) ) then the client had to call each service one by one.
>
> The good news is that you can use the Injector for all these cases. I
> didnt quit get why you couldnt. The Injector can be used if a service
> for a specific type is singleton or if you have 100 of the same type.
> BTW the Injector has nothing to do with remote services per se, the
> Injector gets also used for remoting when it injects the local proxies.
> The Injector can inject only local OSGi Services into an instance. If
> you have multiple instances of one type, guess what, it calls the bind
> method multiple times.
>
> The remoting is NOT done by creating Remote Service Descriptions (that
> is an internal metadata format for the remote services) but by calling
> the RemoteServiceFactory. The method createProxyAndRegister(...) can
> and will create a proxy for a specific remote service and register it
> as a local OSGI service. The RemoteServiceFactory is called on the
> client, you specify the URL, protocol and interface and it generate a
> protocol specific proxy and registers it as a local OSGi Service. Then
> you call the Injector. You can also call just createProxy and register
> the proxy yourself and add some metadata (i.e. the server where the
> service is located or else).
>
> The Injector can not only inject single services or many many services
> (by multiple calls to bind) it can also filter by looking at the
> metadata. So if your local proxy has an attribute saying "oh this
> service is in germany", "oh this service is in italy", the injector can
> be told to only give you german services (because say they are closer).
> The Injector can also use Ranking, a standard OSGi property, to give
> services priority. So the Injector can always inject the service with
> the highest rank into your component.
>
> Does this list give you some ideas ? Dont hesitate to ask more specific
> questions. We are trying to help but dont really understand the problem
> as good as you do.
>
> regards
> christian campo
>
>
> Joel Rosi-Schwartz schrieb:
>> Hi,
>>
>> In ORMF we support clients registering with multiple servers and any
>> given server of course will have many clients. I am considering how to
>> best achieve this with Riena remote services. Of course your Injection
>> service is not useful in this instance, because a given client will
>> have to define many remote services of the same type; one for each
>> server it is interested in.
>>
>> I have been looking through the Riena code and it appears to me that my
>> client can create multiple RemoteServiceDescription, one for each
>> service on every server it is having a dialogue with. Is this the best
>> way to go about it? Can I cache these or is it better to create them on
>> demand and release after each service call?
>>
>> Thanks,
>> Joel
|
|
|
Re: Client to Server remote access in a many to many topology [message #13405 is a reply to message #13386] |
Tue, 07 October 2008 13:28 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Christian Campo![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=christian.campo%40compeople.de) Messages: 597 Registered: July 2009 |
Senior Member |
|
|
Hi Joel,
so why on earth do people use Dependency Injection :-). So I guess you dont want me to point you at the various sources
of explanation for DI.
So here are some thoughts on DI:
While your client (your enduser) might know about the availability of a service, not necessaryly every component in your
client app has the same knowledge.
Say you create a service proxy and registers that as local service with the additional property ("ormf.server=true") in
your equinox, many components get automatically notified about the existence of yet another ORMF server to know about.
The get notified because started an Injector like this
Inject.service(IProjectService.class.getName()).filter("(ormf.server=true) ").into(this).andStart(context);
Even better the components get created by a factory or an Activator and the Activator starts the Injector. Now the
components gets all these bind calls everytime a ORMF server is added without doing anything.
How cool is that for Unit testing, when you actually mock an IProjectService so that you can test your component without
being dependendant on an external service. For Unittests you rather call the bind method yourself and inject a mock object.
Also the code has less dependency on the container and can concentrate on its business funcationality. So it does not
deal with contexts and ServiceReferences, it only deal with instances that implement your own business interfaces. The
rest is magic (= infrastructure) and still a fairly loose coupling.
I personally prefer Dependency Injection because so many things can go wrong when you get a service "by hand" and you
have to check for each one of them.
getServiceReference (can be null, better check)
getService (can be null even for a valid service Reference)
call the service
dont forget to unget the service.
I think its easier to just call the service (check that the instance is not null) and be done.
Just my personal taste.
christian campo
Joel Rosi-Schwartz schrieb:
> Hi Christian,
>
> Ah you are so right, I assumed a common "background of consciousness"
> that obviously is not there :-) So lets try again!
>
> This is not a load balance situation. Our situation is analogous to CVS
> and SVN. We will have are millions of ORMF users (everyone loves
> requirements;-) all over the world. There will be thousands of ORMF
> servers, each serving up a different set of projects, all over the
> world. Each server, however, has the same set of services, the
> difference being that each has a unique set of projects it services. Any
> user can (with appropriate authentication and authorisation) connect to
> a server and open one or more projects to work on. At any time a user
> may be connected to 0..n servers. This happens dynamically, just as in
> CVS, by creating a new repository connection.
>
> Is that a bit clearer? If you want me to expound further, I would be
> very happy to tell you the whole story :-)
>
> Your explanations below and your reply to my other message clarify much.
> Thanks!
>
> What I am pondering is why in THIS situation injection is superior to
> simply obtaining the RemoteServiceReference (or the service instance)
> directly. I love DI but in this case where the consumer is the creator I
> miss the benefit. I am new to OSGi so if I am missing something about
> the "OSGi way of doing things" please let me know.
>
> Many thanks,
> Joel
>
>
> On 2008-10-07 13:18:11 +0100, Christian Campo
> <christian.campo@compeople.de> said:
>
>> Joel,
>>
>> I discussed your posting with Stefan Liebig and we were a little
>> unsure what you concern and issues are. It seemed you condensed all
>> your ORMF knowledge into not so many lines of posting. So we are not
>> sure what you are doing, and what you like to achieve here. So a lot
>> of guessing from our side but I try my best :-).
>>
>> Yes you have multiple servers and I believe what you are saying is
>> that each server has a list of services and they are all the same. All
>> servers run the same services.
>>
>> Now in my world that is true but you wouldnt connect each client to
>> each service wouldnt you ? Since the remote services are accessed
>> using HTTP and the remote service itself runs in Tomcat or whatever
>> webcontainer, you would loadbalance them using Apache. The client then
>> calls the loadbalancer and the call gets routed to any of the services
>> but only to one. At least the way we use it, that remote service calls
>> or webservice calls are stateless. So even if call 1 goes to server A
>> with service xx then call 2 that goes to server B with service xx will
>> work because the server keeps no state of the client. If you use
>> security in Riena you can bring a session ticket with each call and
>> the server will restore a user context for each call but the server
>> does not and I believe should not keep a state.
>>
>> So the way we use it, is in other words that you have a loadbalancer
>> in front of all your servers, the client call
>> http://localbalancer/hessian/CustomerSearch and the loadbalancer
>> decides whether that mean http://serverA/hessian/CustomerSearch or
>> http://serverB/hessian/CustomerSearch. The result should and must be
>> the same.
>>
>> Maybe however (and remember we are guessing) your world is different
>> and you have say split your customer database over several servers and
>> you need the client to call the CustomerSearch on each service and
>> aggregate the result on the client (reconsider your architecture here
>> :-) ) then the client had to call each service one by one.
>>
>> The good news is that you can use the Injector for all these cases. I
>> didnt quit get why you couldnt. The Injector can be used if a service
>> for a specific type is singleton or if you have 100 of the same type.
>> BTW the Injector has nothing to do with remote services per se, the
>> Injector gets also used for remoting when it injects the local proxies.
>> The Injector can inject only local OSGi Services into an instance. If
>> you have multiple instances of one type, guess what, it calls the bind
>> method multiple times.
>>
>> The remoting is NOT done by creating Remote Service Descriptions (that
>> is an internal metadata format for the remote services) but by calling
>> the RemoteServiceFactory. The method createProxyAndRegister(...) can
>> and will create a proxy for a specific remote service and register it
>> as a local OSGI service. The RemoteServiceFactory is called on the
>> client, you specify the URL, protocol and interface and it generate a
>> protocol specific proxy and registers it as a local OSGi Service. Then
>> you call the Injector. You can also call just createProxy and register
>> the proxy yourself and add some metadata (i.e. the server where the
>> service is located or else).
>>
>> The Injector can not only inject single services or many many services
>> (by multiple calls to bind) it can also filter by looking at the
>> metadata. So if your local proxy has an attribute saying "oh this
>> service is in germany", "oh this service is in italy", the injector
>> can be told to only give you german services (because say they are
>> closer).
>> The Injector can also use Ranking, a standard OSGi property, to give
>> services priority. So the Injector can always inject the service with
>> the highest rank into your component.
>>
>> Does this list give you some ideas ? Dont hesitate to ask more
>> specific questions. We are trying to help but dont really understand
>> the problem as good as you do.
>>
>> regards
>> christian campo
>>
>>
>> Joel Rosi-Schwartz schrieb:
>>> Hi,
>>>
>>> In ORMF we support clients registering with multiple servers and any
>>> given server of course will have many clients. I am considering how
>>> to best achieve this with Riena remote services. Of course your
>>> Injection service is not useful in this instance, because a given
>>> client will have to define many remote services of the same type; one
>>> for each server it is interested in.
>>>
>>> I have been looking through the Riena code and it appears to me that
>>> my client can create multiple RemoteServiceDescription, one for each
>>> service on every server it is having a dialogue with. Is this the
>>> best way to go about it? Can I cache these or is it better to create
>>> them on demand and release after each service call?
>>>
>>> Thanks,
>>> Joel
>
|
|
|
Re: Client to Server remote access in a many to many topology [message #13421 is a reply to message #13405] |
Tue, 07 October 2008 15:17 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
|
On 2008-10-07 14:28:38 +0100, Christian Campo
<christian.campo@compeople.de> said:
> Hi Joel,
>
> so why on earth do people use Dependency Injection :-). So I guess you
> dont want me to point you at the various sources of explanation for DI.
Well not actually, I have been using DI for many a year. What I was
soliciting was why to use it in this specific case where the consumer
of the service is actually the one who creates the reference and the
life cycle of the reference is tied to to the consumer. There is one
and only one use of the remote reference, being the consumer.
Btw, something I did not mention is the ORMF client runs inside the
Eclipse workbench. It does not seem to be typical practice yet to use
OSGi services inside of Eclipse, while there is no good reason not to.
Kind of shame that the Eclipse plug-in community have not embraced this
pattern yet. Possibly another reason I should use DI and OSGi services
here :-)
> So here are some thoughts on DI:
>
> While your client (your enduser) might know about the availability of a
> service, not necessaryly every component in your client app has the
> same knowledge.
> Say you create a service proxy and registers that as local service with
> the additional property ("ormf.server=true") in your equinox, many
> components get automatically notified about the existence of yet
> another ORMF server to know about. The get notified because started an
> Injector like this
> Inject.service(IProjectService.class.getName()).filter("(ormf.server=true) ").into(this).andStart(context);
The
>
situation is that in this scenario the service references can not
always be created during activation. The scenario when the user
requests the addition of a new repository location also has to be
catered for. Think CVS repository for a analogous workflow. But I as
far as I can see this is not really a problem.
The way the ORMF is wired is that for each defined repository a set of
ServiceDelegate are created with each delegate responsible for given
service on the particular repository. Clients of the services simply
make a request from a (singleton) ServiceLiaison which sorts out which
repository is responsible for the context of that call and dispatches
it to the appropriate delegate.
I will think about this awhile and consider if the OSGi service route
simplifies my architecture in this instance or not.
> Even better the components get created by a factory or an Activator and
> the Activator starts the Injector. Now the components gets all these
> bind calls everytime a ORMF server is added without doing anything.
>
> How cool is that for Unit testing, when you actually mock an
> IProjectService so that you can test your component without being
> dependendant on an external service. For Unittests you rather call the
> bind method yourself and inject a mock object.
This point is well worth considering.
> Also the code has less dependency on the container and can concentrate
> on its business funcationality. So it does not deal with contexts and
> ServiceReferences, it only deal with instances that implement your own
> business interfaces. The rest is magic (= infrastructure) and still a
> fairly loose coupling.
True.
> I personally prefer Dependency Injection because so many things can go
> wrong when you get a service "by hand" and you have to check for each
> one of them.
>
> getServiceReference (can be null, better check)
> getService (can be null even for a valid service Reference)
>
> call the service
>
> dont forget to unget the service.
>
> I think its easier to just call the service (check that the instance is
> not null) and be done.
All good points in favour of using DI in general. In this situation you
have me considering.
Thanks,
Joel
> Just my personal taste.
>
> christian campo
>
>
>
> Joel Rosi-Schwartz schrieb:
>> Hi Christian,
>>
>> Ah you are so right, I assumed a common "background of consciousness"
>> that obviously is not there :-) So lets try again!
>>
>> This is not a load balance situation. Our situation is analogous to CVS
>> and SVN. We will have are millions of ORMF users (everyone loves
>> requirements;-) all over the world. There will be thousands of ORMF
>> servers, each serving up a different set of projects, all over the
>> world. Each server, however, has the same set of services, the
>> difference being that each has a unique set of projects it services.
>> Any user can (with appropriate authentication and authorisation)
>> connect to a server and open one or more projects to work on. At any
>> time a user may be connected to 0..n servers. This happens dynamically,
>> just as in CVS, by creating a new repository connection.
>>
>> Is that a bit clearer? If you want me to expound further, I would be
>> very happy to tell you the whole story :-)
>>
>> Your explanations below and your reply to my other message clarify
>> much. Thanks!
>>
>> What I am pondering is why in THIS situation injection is superior to
>> simply obtaining the RemoteServiceReference (or the service instance)
>> directly. I love DI but in this case where the consumer is the creator
>> I miss the benefit. I am new to OSGi so if I am missing something about
>> the "OSGi way of doing things" please let me know.
>>
>> Many thanks,
>> Joel
>>
>>
>> On 2008-10-07 13:18:11 +0100, Christian Campo
>> <christian.campo@compeople.de> said:
>>
>>> Joel,
>>>
>>> I discussed your posting with Stefan Liebig and we were a little unsure
>>> what you concern and issues are. It seemed you condensed all your ORMF
>>> knowledge into not so many lines of posting. So we are not sure what
>>> you are doing, and what you like to achieve here. So a lot of guessing
>>> from our side but I try my best :-).
>>>
>>> Yes you have multiple servers and I believe what you are saying is that
>>> each server has a list of services and they are all the same. All
>>> servers run the same services.
>>>
>>> Now in my world that is true but you wouldnt connect each client to
>>> each service wouldnt you ? Since the remote services are accessed using
>>> HTTP and the remote service itself runs in Tomcat or whatever
>>> webcontainer, you would loadbalance them using Apache. The client then
>>> calls the loadbalancer and the call gets routed to any of the services
>>> but only to one. At least the way we use it, that remote service calls
>>> or webservice calls are stateless. So even if call 1 goes to server A
>>> with service xx then call 2 that goes to server B with service xx will
>>> work because the server keeps no state of the client. If you use
>>> security in Riena you can bring a session ticket with each call and the
>>> server will restore a user context for each call but the server does
>>> not and I believe should not keep a state.
>>>
>>> So the way we use it, is in other words that you have a loadbalancer in
>>> front of all your servers, the client call
>>> http://localbalancer/hessian/CustomerSearch and the loadbalancer
>>> decides whether that mean http://serverA/hessian/CustomerSearch or
>>> http://serverB/hessian/CustomerSearch. The result should and must be
>>> the same.
>>>
>>> Maybe however (and remember we are guessing) your world is different
>>> and you have say split your customer database over several servers and
>>> you need the client to call the CustomerSearch on each service and
>>> aggregate the result on the client (reconsider your architecture here
>>> :-) ) then the client had to call each service one by one.
>>>
>>> The good news is that you can use the Injector for all these cases. I
>>> didnt quit get why you couldnt. The Injector can be used if a service
>>> for a specific type is singleton or if you have 100 of the same type.
>>> BTW the Injector has nothing to do with remote services per se, the
>>> Injector gets also used for remoting when it injects the local proxies.
>>> The Injector can inject only local OSGi Services into an instance. If
>>> you have multiple instances of one type, guess what, it calls the bind
>>> method multiple times.
>>>
>>> The remoting is NOT done by creating Remote Service Descriptions (that
>>> is an internal metadata format for the remote services) but by calling
>>> the RemoteServiceFactory. The method createProxyAndRegister(...) can
>>> and will create a proxy for a specific remote service and register it
>>> as a local OSGI service. The RemoteServiceFactory is called on the
>>> client, you specify the URL, protocol and interface and it generate a
>>> protocol specific proxy and registers it as a local OSGi Service. Then
>>> you call the Injector. You can also call just createProxy and register
>>> the proxy yourself and add some metadata (i.e. the server where the
>>> service is located or else).
>>>
>>> The Injector can not only inject single services or many many services
>>> (by multiple calls to bind) it can also filter by looking at the
>>> metadata. So if your local proxy has an attribute saying "oh this
>>> service is in germany", "oh this service is in italy", the injector can
>>> be told to only give you german services (because say they are closer).
>>> The Injector can also use Ranking, a standard OSGi property, to give
>>> services priority. So the Injector can always inject the service with
>>> the highest rank into your component.
>>>
>>> Does this list give you some ideas ? Dont hesitate to ask more specific
>>> questions. We are trying to help but dont really understand the problem
>>> as good as you do.
>>>
>>> regards
>>> christian campo
>>>
>>>
>>> Joel Rosi-Schwartz schrieb:
>>>> Hi,
>>>>
>>>> In ORMF we support clients registering with multiple servers and any
>>>> given server of course will have many clients. I am considering how to
>>>> best achieve this with Riena remote services. Of course your Injection
>>>> service is not useful in this instance, because a given client will
>>>> have to define many remote services of the same type; one for each
>>>> server it is interested in.
>>>>
>>>> I have been looking through the Riena code and it appears to me that my
>>>> client can create multiple RemoteServiceDescription, one for each
>>>> service on every server it is having a dialogue with. Is this the best
>>>> way to go about it? Can I cache these or is it better to create them on
>>>> demand and release after each service call?
>>>>
>>>> Thanks,
>>>> Joel
--
Joel Rosi-Schwartz
Etish Limited [http://www.etish.org]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^...^
/ o,o \ The proud parents of Useme & ORMF
|) ::: (| Open Requirements Management Framework
====w=w==== [http://www.eclipse.org/ormf/]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
Re: Client to Server remote access in a many to many topology [message #14010 is a reply to message #13366] |
Tue, 07 October 2008 16:56 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
|
On 2008-10-07 13:26:12 +0100, Christian Campo
<christian.campo@compeople.de> said:
> Hi Joel,
>
> this looks like our communication pingpong example. Not sure what you
> modified. It works yes.
Yes I copied the method from pingpong and tested it with that example.
What I changed was I am getting the RemoteServiceReference directly and
then simply using it rather than registering it so that it can be
retrieved later using DI.
I would like to know if this is a clean way to proceed if I do not go
the DI route. I believe deeply in the elegance of DI/IoC but nor do I
wish to be its slave :-)
> Joel Rosi-Schwartz schrieb:
>> I've been doing some investigating and experimenting, and have come up
>> with the following that works:
>>
>> void sendPing2() {
>> RemoteServiceFactory rsf = new RemoteServiceFactory();
>> Class<?> serviceInterface = IPingPong.class;
>> String url = "http://localhost:8080/hessian/PingPongWS";
>> //$NON-NLS-1$
>> String protocol = "hessian"; //$NON-NLS-1$
>>
>> IRemoteServiceReference pingPongRef =
>> rsf.createProxy(serviceInterface, url, protocol,
>> "de.compeople.pingpong.config"); //$NON-NLS-1$
>> IPingPong pingPong = (IPingPong) pingPongRef.getServiceInstance();
>>
>> Ping ping = new Ping();
>> ping.setText("AGAIN I ping you and you pong me"); //$NON-NLS-1$
>>
>> Pong pong = pingPong.ping(ping);
>> System.out.println("PingPong::Client:: " + pong); //$NON-NLS-1$
>>
>> }
>>
>> I have several questions:
>> 1. Is this pattern okay for production code?
>> 2. Should I be caching the the IRemoteServiceReference or the
>> service instance between calls?
>> 3. What is the the purpose of the config string, e.g.
>> "de.compeople.pingpong.config"?
>>
>> Cheers,
>> Joel
--
Joel Rosi-Schwartz
Etish Limited [http://www.etish.org]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^...^
/ o,o \ The proud parents of Useme & ORMF
|) ::: (| Open Requirements Management Framework
====w=w==== [http://www.eclipse.org/ormf/]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
Re: Client to Server remote access in a many to many topology [message #14022 is a reply to message #14010] |
Tue, 07 October 2008 20:15 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) |
Christian Campo![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=christian.campo%40compeople.de) Messages: 597 Registered: July 2009 |
Senior Member |
|
|
Joel,
I overlooked that change. After all they are regular OSGi Services. So its your call how you get them, either the
classic way through getServiceReference, through ServiceInjector. You can also use Declarative Services(DS) to let the
Service injected that way or use SAT (Service Activation Toolkit).
No difference the proxy its just a regular OSGi Service.
christian
Joel Rosi-Schwartz schrieb:
> On 2008-10-07 13:26:12 +0100, Christian Campo
> <christian.campo@compeople.de> said:
>
>> Hi Joel,
>>
>> this looks like our communication pingpong example. Not sure what you
>> modified. It works yes.
>
> Yes I copied the method from pingpong and tested it with that example.
> What I changed was I am getting the RemoteServiceReference directly and
> then simply using it rather than registering it so that it can be
> retrieved later using DI.
>
> I would like to know if this is a clean way to proceed if I do not go
> the DI route. I believe deeply in the elegance of DI/IoC but nor do I
> wish to be its slave :-)
>
>> Joel Rosi-Schwartz schrieb:
>>> I've been doing some investigating and experimenting, and have come
>>> up with the following that works:
>>>
>>> void sendPing2() {
>>> RemoteServiceFactory rsf = new RemoteServiceFactory();
>>> Class<?> serviceInterface = IPingPong.class;
>>> String url = "http://localhost:8080/hessian/PingPongWS";
>>> //$NON-NLS-1$
>>> String protocol = "hessian"; //$NON-NLS-1$
>>>
>>> IRemoteServiceReference pingPongRef =
>>> rsf.createProxy(serviceInterface, url, protocol,
>>> "de.compeople.pingpong.config"); //$NON-NLS-1$
>>> IPingPong pingPong = (IPingPong)
>>> pingPongRef.getServiceInstance();
>>>
>>> Ping ping = new Ping();
>>> ping.setText("AGAIN I ping you and you pong me");
>>> //$NON-NLS-1$
>>>
>>> Pong pong = pingPong.ping(ping);
>>> System.out.println("PingPong::Client:: " + pong);
>>> //$NON-NLS-1$
>>>
>>> }
>>>
>>> I have several questions:
>>> 1. Is this pattern okay for production code?
>>> 2. Should I be caching the the IRemoteServiceReference or the
>>> service instance between calls?
>>> 3. What is the the purpose of the config string, e.g.
>>> "de.compeople.pingpong.config"?
>>>
>>> Cheers,
>>> Joel
>
>
|
|
|
Re: Client to Server remote access in a many to many topology [message #575693 is a reply to message #13291] |
Tue, 07 October 2008 11:40 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) |
|
I've been doing some investigating and experimenting, and have come up
with the following that works:
void sendPing2() {
RemoteServiceFactory rsf = new RemoteServiceFactory();
Class<?> serviceInterface = IPingPong.class;
String url = "http://localhost:8080/hessian/PingPongWS"; //$NON-NLS-1$
String protocol = "hessian"; //$NON-NLS-1$
IRemoteServiceReference pingPongRef =
rsf.createProxy(serviceInterface, url, protocol,
"de.compeople.pingpong.config"); //$NON-NLS-1$
IPingPong pingPong = (IPingPong) pingPongRef.getServiceInstance();
Ping ping = new Ping();
ping.setText("AGAIN I ping you and you pong me"); //$NON-NLS-1$
Pong pong = pingPong.ping(ping);
System.out.println("PingPong::Client:: " + pong); //$NON-NLS-1$
}
I have several questions:
1. Is this pattern okay for production code?
2. Should I be caching the the IRemoteServiceReference or the service
instance between calls?
3. What is the the purpose of the config string, e.g.
"de.compeople.pingpong.config"?
Cheers,
Joel
--
Joel Rosi-Schwartz
Etish Limited [http://www.etish.org]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^...^
/ o,o \ The proud parents of Useme & ORMF
|) ::: (| Open Requirements Management Framework
====w=w==== [http://www.eclipse.org/ormf/]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
Re: Client to Server remote access in a many to many topology [message #575707 is a reply to message #13291] |
Tue, 07 October 2008 12:18 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) |
Christian Campo![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=christian.campo%40compeople.de) Messages: 597 Registered: July 2009 |
Senior Member |
|
|
Joel,
I discussed your posting with Stefan Liebig and we were a little unsure what you concern and issues are. It seemed you
condensed all your ORMF knowledge into not so many lines of posting. So we are not sure what you are doing, and what you
like to achieve here. So a lot of guessing from our side but I try my best :-).
Yes you have multiple servers and I believe what you are saying is that each server has a list of services and they are
all the same. All servers run the same services.
Now in my world that is true but you wouldnt connect each client to each service wouldnt you ? Since the remote services
are accessed using HTTP and the remote service itself runs in Tomcat or whatever webcontainer, you would loadbalance
them using Apache. The client then calls the loadbalancer and the call gets routed to any of the services but only to
one. At least the way we use it, that remote service calls or webservice calls are stateless. So even if call 1 goes to
server A with service xx then call 2 that goes to server B with service xx will work because the server keeps no state
of the client. If you use security in Riena you can bring a session ticket with each call and the server will restore a
user context for each call but the server does not and I believe should not keep a state.
So the way we use it, is in other words that you have a loadbalancer in front of all your servers, the client call
http://localbalancer/hessian/CustomerSearch and the loadbalancer decides whether that mean
http://serverA/hessian/CustomerSearch or http://serverB/hessian/CustomerSearch The result should and must be the same.
Maybe however (and remember we are guessing) your world is different and you have say split your customer database over
several servers and you need the client to call the CustomerSearch on each service and aggregate the result on the
client (reconsider your architecture here :-) ) then the client had to call each service one by one.
The good news is that you can use the Injector for all these cases. I didnt quit get why you couldnt. The Injector can
be used if a service for a specific type is singleton or if you have 100 of the same type. BTW the Injector has nothing
to do with remote services per se, the Injector gets also used for remoting when it injects the local proxies.
The Injector can inject only local OSGi Services into an instance. If you have multiple instances of one type, guess
what, it calls the bind method multiple times.
The remoting is NOT done by creating Remote Service Descriptions (that is an internal metadata format for the remote
services) but by calling the RemoteServiceFactory. The method createProxyAndRegister(...) can and will create a proxy
for a specific remote service and register it as a local OSGI service. The RemoteServiceFactory is called on the client,
you specify the URL, protocol and interface and it generate a protocol specific proxy and registers it as a local OSGi
Service. Then you call the Injector. You can also call just createProxy and register the proxy yourself and add some
metadata (i.e. the server where the service is located or else).
The Injector can not only inject single services or many many services (by multiple calls to bind) it can also filter by
looking at the metadata. So if your local proxy has an attribute saying "oh this service is in germany", "oh this
service is in italy", the injector can be told to only give you german services (because say they are closer).
The Injector can also use Ranking, a standard OSGi property, to give services priority. So the Injector can always
inject the service with the highest rank into your component.
Does this list give you some ideas ? Dont hesitate to ask more specific questions. We are trying to help but dont really
understand the problem as good as you do.
regards
christian campo
Joel Rosi-Schwartz schrieb:
> Hi,
>
> In ORMF we support clients registering with multiple servers and any
> given server of course will have many clients. I am considering how to
> best achieve this with Riena remote services. Of course your Injection
> service is not useful in this instance, because a given client will have
> to define many remote services of the same type; one for each server it
> is interested in.
>
> I have been looking through the Riena code and it appears to me that my
> client can create multiple RemoteServiceDescription, one for each
> service on every server it is having a dialogue with. Is this the best
> way to go about it? Can I cache these or is it better to create them on
> demand and release after each service call?
>
> Thanks,
> Joel
|
|
|
Re: Client to Server remote access in a many to many topology [message #575738 is a reply to message #13319] |
Tue, 07 October 2008 12:26 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) |
Christian Campo![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=christian.campo%40compeople.de) Messages: 597 Registered: July 2009 |
Senior Member |
|
|
Hi Joel,
this looks like our communication pingpong example. Not sure what you modified. It works yes. You could now also use the
Injector after you called the RemoteServiceFactory to get the proxy injected like
Inject.service(IPingPong.class.getName()).into(this).andStar t(context);
It then requires a local method for bind and unbind
public void bind(IPingPong pingPong) {
Ping ping = new Ping();
ping.setText("AGAIN I ping you and you pong me"); //$NON-NLS-1$
Pong pong = pingPong.ping(ping);
System.out.println("PingPong::Client:: " + pong); //$NON-NLS-1$
}
When creating the proxy you should use a variable for the hostname to easily switch between different environments look at
org.eclipse.riena.communcation.sample.pingpong.client.config
2. If you inject Service you just keep the reference to the instance that you get injected, nothing else is required
3. forget the config id, it will go away
christian campo
Joel Rosi-Schwartz schrieb:
> I've been doing some investigating and experimenting, and have come up
> with the following that works:
>
> void sendPing2() {
> RemoteServiceFactory rsf = new RemoteServiceFactory();
> Class<?> serviceInterface = IPingPong.class;
> String url = "http://localhost:8080/hessian/PingPongWS";
> //$NON-NLS-1$
> String protocol = "hessian"; //$NON-NLS-1$
>
> IRemoteServiceReference pingPongRef =
> rsf.createProxy(serviceInterface, url, protocol,
> "de.compeople.pingpong.config"); //$NON-NLS-1$
> IPingPong pingPong = (IPingPong)
> pingPongRef.getServiceInstance();
>
> Ping ping = new Ping();
> ping.setText("AGAIN I ping you and you pong me"); //$NON-NLS-1$
>
> Pong pong = pingPong.ping(ping);
> System.out.println("PingPong::Client:: " + pong); //$NON-NLS-1$
>
> }
>
> I have several questions:
> 1. Is this pattern okay for production code?
> 2. Should I be caching the the IRemoteServiceReference or the
> service instance between calls?
> 3. What is the the purpose of the config string, e.g.
> "de.compeople.pingpong.config"?
>
> Cheers,
> Joel
|
|
|
Re: Client to Server remote access in a many to many topology [message #575755 is a reply to message #13345] |
Tue, 07 October 2008 13:03 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) |
|
Hi Christian,
Ah you are so right, I assumed a common "background of consciousness"
that obviously is not there :-) So lets try again!
This is not a load balance situation. Our situation is analogous to CVS
and SVN. We will have are millions of ORMF users (everyone loves
requirements;-) all over the world. There will be thousands of ORMF
servers, each serving up a different set of projects, all over the
world. Each server, however, has the same set of services, the
difference being that each has a unique set of projects it services.
Any user can (with appropriate authentication and authorisation)
connect to a server and open one or more projects to work on. At any
time a user may be connected to 0..n servers. This happens dynamically,
just as in CVS, by creating a new repository connection.
Is that a bit clearer? If you want me to expound further, I would be
very happy to tell you the whole story :-)
Your explanations below and your reply to my other message clarify
much. Thanks!
What I am pondering is why in THIS situation injection is superior to
simply obtaining the RemoteServiceReference (or the service instance)
directly. I love DI but in this case where the consumer is the creator
I miss the benefit. I am new to OSGi so if I am missing something about
the "OSGi way of doing things" please let me know.
Many thanks,
Joel
On 2008-10-07 13:18:11 +0100, Christian Campo
<christian.campo@compeople.de> said:
> Joel,
>
> I discussed your posting with Stefan Liebig and we were a little unsure
> what you concern and issues are. It seemed you condensed all your ORMF
> knowledge into not so many lines of posting. So we are not sure what
> you are doing, and what you like to achieve here. So a lot of guessing
> from our side but I try my best :-).
>
> Yes you have multiple servers and I believe what you are saying is that
> each server has a list of services and they are all the same. All
> servers run the same services.
>
> Now in my world that is true but you wouldnt connect each client to
> each service wouldnt you ? Since the remote services are accessed using
> HTTP and the remote service itself runs in Tomcat or whatever
> webcontainer, you would loadbalance them using Apache. The client then
> calls the loadbalancer and the call gets routed to any of the services
> but only to one. At least the way we use it, that remote service calls
> or webservice calls are stateless. So even if call 1 goes to server A
> with service xx then call 2 that goes to server B with service xx will
> work because the server keeps no state of the client. If you use
> security in Riena you can bring a session ticket with each call and the
> server will restore a user context for each call but the server does
> not and I believe should not keep a state.
>
> So the way we use it, is in other words that you have a loadbalancer in
> front of all your servers, the client call
> http://localbalancer/hessian/CustomerSearch and the loadbalancer
> decides whether that mean http://serverA/hessian/CustomerSearch or
> http://serverB/hessian/CustomerSearch The result should and must be
> the same.
>
> Maybe however (and remember we are guessing) your world is different
> and you have say split your customer database over several servers and
> you need the client to call the CustomerSearch on each service and
> aggregate the result on the client (reconsider your architecture here
> :-) ) then the client had to call each service one by one.
>
> The good news is that you can use the Injector for all these cases. I
> didnt quit get why you couldnt. The Injector can be used if a service
> for a specific type is singleton or if you have 100 of the same type.
> BTW the Injector has nothing to do with remote services per se, the
> Injector gets also used for remoting when it injects the local proxies.
> The Injector can inject only local OSGi Services into an instance. If
> you have multiple instances of one type, guess what, it calls the bind
> method multiple times.
>
> The remoting is NOT done by creating Remote Service Descriptions (that
> is an internal metadata format for the remote services) but by calling
> the RemoteServiceFactory. The method createProxyAndRegister(...) can
> and will create a proxy for a specific remote service and register it
> as a local OSGI service. The RemoteServiceFactory is called on the
> client, you specify the URL, protocol and interface and it generate a
> protocol specific proxy and registers it as a local OSGi Service. Then
> you call the Injector. You can also call just createProxy and register
> the proxy yourself and add some metadata (i.e. the server where the
> service is located or else).
>
> The Injector can not only inject single services or many many services
> (by multiple calls to bind) it can also filter by looking at the
> metadata. So if your local proxy has an attribute saying "oh this
> service is in germany", "oh this service is in italy", the injector can
> be told to only give you german services (because say they are closer).
> The Injector can also use Ranking, a standard OSGi property, to give
> services priority. So the Injector can always inject the service with
> the highest rank into your component.
>
> Does this list give you some ideas ? Dont hesitate to ask more specific
> questions. We are trying to help but dont really understand the problem
> as good as you do.
>
> regards
> christian campo
>
>
> Joel Rosi-Schwartz schrieb:
>> Hi,
>>
>> In ORMF we support clients registering with multiple servers and any
>> given server of course will have many clients. I am considering how to
>> best achieve this with Riena remote services. Of course your Injection
>> service is not useful in this instance, because a given client will
>> have to define many remote services of the same type; one for each
>> server it is interested in.
>>
>> I have been looking through the Riena code and it appears to me that my
>> client can create multiple RemoteServiceDescription, one for each
>> service on every server it is having a dialogue with. Is this the best
>> way to go about it? Can I cache these or is it better to create them on
>> demand and release after each service call?
>>
>> Thanks,
>> Joel
|
|
|
Re: Client to Server remote access in a many to many topology [message #575772 is a reply to message #13386] |
Tue, 07 October 2008 13:28 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) |
Christian Campo![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=christian.campo%40compeople.de) Messages: 597 Registered: July 2009 |
Senior Member |
|
|
Hi Joel,
so why on earth do people use Dependency Injection :-). So I guess you dont want me to point you at the various sources
of explanation for DI.
So here are some thoughts on DI:
While your client (your enduser) might know about the availability of a service, not necessaryly every component in your
client app has the same knowledge.
Say you create a service proxy and registers that as local service with the additional property ("ormf.server=true") in
your equinox, many components get automatically notified about the existence of yet another ORMF server to know about.
The get notified because started an Injector like this
Inject.service(IProjectService.class.getName()).filter("(ormf.server=true) ").into(this).andStart(context);
Even better the components get created by a factory or an Activator and the Activator starts the Injector. Now the
components gets all these bind calls everytime a ORMF server is added without doing anything.
How cool is that for Unit testing, when you actually mock an IProjectService so that you can test your component without
being dependendant on an external service. For Unittests you rather call the bind method yourself and inject a mock object.
Also the code has less dependency on the container and can concentrate on its business funcationality. So it does not
deal with contexts and ServiceReferences, it only deal with instances that implement your own business interfaces. The
rest is magic (= infrastructure) and still a fairly loose coupling.
I personally prefer Dependency Injection because so many things can go wrong when you get a service "by hand" and you
have to check for each one of them.
getServiceReference (can be null, better check)
getService (can be null even for a valid service Reference)
call the service
dont forget to unget the service.
I think its easier to just call the service (check that the instance is not null) and be done.
Just my personal taste.
christian campo
Joel Rosi-Schwartz schrieb:
> Hi Christian,
>
> Ah you are so right, I assumed a common "background of consciousness"
> that obviously is not there :-) So lets try again!
>
> This is not a load balance situation. Our situation is analogous to CVS
> and SVN. We will have are millions of ORMF users (everyone loves
> requirements;-) all over the world. There will be thousands of ORMF
> servers, each serving up a different set of projects, all over the
> world. Each server, however, has the same set of services, the
> difference being that each has a unique set of projects it services. Any
> user can (with appropriate authentication and authorisation) connect to
> a server and open one or more projects to work on. At any time a user
> may be connected to 0..n servers. This happens dynamically, just as in
> CVS, by creating a new repository connection.
>
> Is that a bit clearer? If you want me to expound further, I would be
> very happy to tell you the whole story :-)
>
> Your explanations below and your reply to my other message clarify much.
> Thanks!
>
> What I am pondering is why in THIS situation injection is superior to
> simply obtaining the RemoteServiceReference (or the service instance)
> directly. I love DI but in this case where the consumer is the creator I
> miss the benefit. I am new to OSGi so if I am missing something about
> the "OSGi way of doing things" please let me know.
>
> Many thanks,
> Joel
>
>
> On 2008-10-07 13:18:11 +0100, Christian Campo
> <christian.campo@compeople.de> said:
>
>> Joel,
>>
>> I discussed your posting with Stefan Liebig and we were a little
>> unsure what you concern and issues are. It seemed you condensed all
>> your ORMF knowledge into not so many lines of posting. So we are not
>> sure what you are doing, and what you like to achieve here. So a lot
>> of guessing from our side but I try my best :-).
>>
>> Yes you have multiple servers and I believe what you are saying is
>> that each server has a list of services and they are all the same. All
>> servers run the same services.
>>
>> Now in my world that is true but you wouldnt connect each client to
>> each service wouldnt you ? Since the remote services are accessed
>> using HTTP and the remote service itself runs in Tomcat or whatever
>> webcontainer, you would loadbalance them using Apache. The client then
>> calls the loadbalancer and the call gets routed to any of the services
>> but only to one. At least the way we use it, that remote service calls
>> or webservice calls are stateless. So even if call 1 goes to server A
>> with service xx then call 2 that goes to server B with service xx will
>> work because the server keeps no state of the client. If you use
>> security in Riena you can bring a session ticket with each call and
>> the server will restore a user context for each call but the server
>> does not and I believe should not keep a state.
>>
>> So the way we use it, is in other words that you have a loadbalancer
>> in front of all your servers, the client call
>> http://localbalancer/hessian/CustomerSearch and the loadbalancer
>> decides whether that mean http://serverA/hessian/CustomerSearch or
>> http://serverB/hessian/CustomerSearch The result should and must be
>> the same.
>>
>> Maybe however (and remember we are guessing) your world is different
>> and you have say split your customer database over several servers and
>> you need the client to call the CustomerSearch on each service and
>> aggregate the result on the client (reconsider your architecture here
>> :-) ) then the client had to call each service one by one.
>>
>> The good news is that you can use the Injector for all these cases. I
>> didnt quit get why you couldnt. The Injector can be used if a service
>> for a specific type is singleton or if you have 100 of the same type.
>> BTW the Injector has nothing to do with remote services per se, the
>> Injector gets also used for remoting when it injects the local proxies.
>> The Injector can inject only local OSGi Services into an instance. If
>> you have multiple instances of one type, guess what, it calls the bind
>> method multiple times.
>>
>> The remoting is NOT done by creating Remote Service Descriptions (that
>> is an internal metadata format for the remote services) but by calling
>> the RemoteServiceFactory. The method createProxyAndRegister(...) can
>> and will create a proxy for a specific remote service and register it
>> as a local OSGI service. The RemoteServiceFactory is called on the
>> client, you specify the URL, protocol and interface and it generate a
>> protocol specific proxy and registers it as a local OSGi Service. Then
>> you call the Injector. You can also call just createProxy and register
>> the proxy yourself and add some metadata (i.e. the server where the
>> service is located or else).
>>
>> The Injector can not only inject single services or many many services
>> (by multiple calls to bind) it can also filter by looking at the
>> metadata. So if your local proxy has an attribute saying "oh this
>> service is in germany", "oh this service is in italy", the injector
>> can be told to only give you german services (because say they are
>> closer).
>> The Injector can also use Ranking, a standard OSGi property, to give
>> services priority. So the Injector can always inject the service with
>> the highest rank into your component.
>>
>> Does this list give you some ideas ? Dont hesitate to ask more
>> specific questions. We are trying to help but dont really understand
>> the problem as good as you do.
>>
>> regards
>> christian campo
>>
>>
>> Joel Rosi-Schwartz schrieb:
>>> Hi,
>>>
>>> In ORMF we support clients registering with multiple servers and any
>>> given server of course will have many clients. I am considering how
>>> to best achieve this with Riena remote services. Of course your
>>> Injection service is not useful in this instance, because a given
>>> client will have to define many remote services of the same type; one
>>> for each server it is interested in.
>>>
>>> I have been looking through the Riena code and it appears to me that
>>> my client can create multiple RemoteServiceDescription, one for each
>>> service on every server it is having a dialogue with. Is this the
>>> best way to go about it? Can I cache these or is it better to create
>>> them on demand and release after each service call?
>>>
>>> Thanks,
>>> Joel
>
|
|
|
Re: Client to Server remote access in a many to many topology [message #575797 is a reply to message #13405] |
Tue, 07 October 2008 15:17 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) |
|
On 2008-10-07 14:28:38 +0100, Christian Campo
<christian.campo@compeople.de> said:
> Hi Joel,
>
> so why on earth do people use Dependency Injection :-). So I guess you
> dont want me to point you at the various sources of explanation for DI.
Well not actually, I have been using DI for many a year. What I was
soliciting was why to use it in this specific case where the consumer
of the service is actually the one who creates the reference and the
life cycle of the reference is tied to to the consumer. There is one
and only one use of the remote reference, being the consumer.
Btw, something I did not mention is the ORMF client runs inside the
Eclipse workbench. It does not seem to be typical practice yet to use
OSGi services inside of Eclipse, while there is no good reason not to.
Kind of shame that the Eclipse plug-in community have not embraced this
pattern yet. Possibly another reason I should use DI and OSGi services
here :-)
> So here are some thoughts on DI:
>
> While your client (your enduser) might know about the availability of a
> service, not necessaryly every component in your client app has the
> same knowledge.
> Say you create a service proxy and registers that as local service with
> the additional property ("ormf.server=true") in your equinox, many
> components get automatically notified about the existence of yet
> another ORMF server to know about. The get notified because started an
> Injector like this
> Inject.service(IProjectService.class.getName()).filter("(ormf.server=true) ").into(this).andStart(context);
The
>
situation is that in this scenario the service references can not
always be created during activation. The scenario when the user
requests the addition of a new repository location also has to be
catered for. Think CVS repository for a analogous workflow. But I as
far as I can see this is not really a problem.
The way the ORMF is wired is that for each defined repository a set of
ServiceDelegate are created with each delegate responsible for given
service on the particular repository. Clients of the services simply
make a request from a (singleton) ServiceLiaison which sorts out which
repository is responsible for the context of that call and dispatches
it to the appropriate delegate.
I will think about this awhile and consider if the OSGi service route
simplifies my architecture in this instance or not.
> Even better the components get created by a factory or an Activator and
> the Activator starts the Injector. Now the components gets all these
> bind calls everytime a ORMF server is added without doing anything.
>
> How cool is that for Unit testing, when you actually mock an
> IProjectService so that you can test your component without being
> dependendant on an external service. For Unittests you rather call the
> bind method yourself and inject a mock object.
This point is well worth considering.
> Also the code has less dependency on the container and can concentrate
> on its business funcationality. So it does not deal with contexts and
> ServiceReferences, it only deal with instances that implement your own
> business interfaces. The rest is magic (= infrastructure) and still a
> fairly loose coupling.
True.
> I personally prefer Dependency Injection because so many things can go
> wrong when you get a service "by hand" and you have to check for each
> one of them.
>
> getServiceReference (can be null, better check)
> getService (can be null even for a valid service Reference)
>
> call the service
>
> dont forget to unget the service.
>
> I think its easier to just call the service (check that the instance is
> not null) and be done.
All good points in favour of using DI in general. In this situation you
have me considering.
Thanks,
Joel
> Just my personal taste.
>
> christian campo
>
>
>
> Joel Rosi-Schwartz schrieb:
>> Hi Christian,
>>
>> Ah you are so right, I assumed a common "background of consciousness"
>> that obviously is not there :-) So lets try again!
>>
>> This is not a load balance situation. Our situation is analogous to CVS
>> and SVN. We will have are millions of ORMF users (everyone loves
>> requirements;-) all over the world. There will be thousands of ORMF
>> servers, each serving up a different set of projects, all over the
>> world. Each server, however, has the same set of services, the
>> difference being that each has a unique set of projects it services.
>> Any user can (with appropriate authentication and authorisation)
>> connect to a server and open one or more projects to work on. At any
>> time a user may be connected to 0..n servers. This happens dynamically,
>> just as in CVS, by creating a new repository connection.
>>
>> Is that a bit clearer? If you want me to expound further, I would be
>> very happy to tell you the whole story :-)
>>
>> Your explanations below and your reply to my other message clarify
>> much. Thanks!
>>
>> What I am pondering is why in THIS situation injection is superior to
>> simply obtaining the RemoteServiceReference (or the service instance)
>> directly. I love DI but in this case where the consumer is the creator
>> I miss the benefit. I am new to OSGi so if I am missing something about
>> the "OSGi way of doing things" please let me know.
>>
>> Many thanks,
>> Joel
>>
>>
>> On 2008-10-07 13:18:11 +0100, Christian Campo
>> <christian.campo@compeople.de> said:
>>
>>> Joel,
>>>
>>> I discussed your posting with Stefan Liebig and we were a little unsure
>>> what you concern and issues are. It seemed you condensed all your ORMF
>>> knowledge into not so many lines of posting. So we are not sure what
>>> you are doing, and what you like to achieve here. So a lot of guessing
>>> from our side but I try my best :-).
>>>
>>> Yes you have multiple servers and I believe what you are saying is that
>>> each server has a list of services and they are all the same. All
>>> servers run the same services.
>>>
>>> Now in my world that is true but you wouldnt connect each client to
>>> each service wouldnt you ? Since the remote services are accessed using
>>> HTTP and the remote service itself runs in Tomcat or whatever
>>> webcontainer, you would loadbalance them using Apache. The client then
>>> calls the loadbalancer and the call gets routed to any of the services
>>> but only to one. At least the way we use it, that remote service calls
>>> or webservice calls are stateless. So even if call 1 goes to server A
>>> with service xx then call 2 that goes to server B with service xx will
>>> work because the server keeps no state of the client. If you use
>>> security in Riena you can bring a session ticket with each call and the
>>> server will restore a user context for each call but the server does
>>> not and I believe should not keep a state.
>>>
>>> So the way we use it, is in other words that you have a loadbalancer in
>>> front of all your servers, the client call
>>> http://localbalancer/hessian/CustomerSearch and the loadbalancer
>>> decides whether that mean http://serverA/hessian/CustomerSearch or
>>> http://serverB/hessian/CustomerSearch The result should and must be
>>> the same.
>>>
>>> Maybe however (and remember we are guessing) your world is different
>>> and you have say split your customer database over several servers and
>>> you need the client to call the CustomerSearch on each service and
>>> aggregate the result on the client (reconsider your architecture here
>>> :-) ) then the client had to call each service one by one.
>>>
>>> The good news is that you can use the Injector for all these cases. I
>>> didnt quit get why you couldnt. The Injector can be used if a service
>>> for a specific type is singleton or if you have 100 of the same type.
>>> BTW the Injector has nothing to do with remote services per se, the
>>> Injector gets also used for remoting when it injects the local proxies.
>>> The Injector can inject only local OSGi Services into an instance. If
>>> you have multiple instances of one type, guess what, it calls the bind
>>> method multiple times.
>>>
>>> The remoting is NOT done by creating Remote Service Descriptions (that
>>> is an internal metadata format for the remote services) but by calling
>>> the RemoteServiceFactory. The method createProxyAndRegister(...) can
>>> and will create a proxy for a specific remote service and register it
>>> as a local OSGI service. The RemoteServiceFactory is called on the
>>> client, you specify the URL, protocol and interface and it generate a
>>> protocol specific proxy and registers it as a local OSGi Service. Then
>>> you call the Injector. You can also call just createProxy and register
>>> the proxy yourself and add some metadata (i.e. the server where the
>>> service is located or else).
>>>
>>> The Injector can not only inject single services or many many services
>>> (by multiple calls to bind) it can also filter by looking at the
>>> metadata. So if your local proxy has an attribute saying "oh this
>>> service is in germany", "oh this service is in italy", the injector can
>>> be told to only give you german services (because say they are closer).
>>> The Injector can also use Ranking, a standard OSGi property, to give
>>> services priority. So the Injector can always inject the service with
>>> the highest rank into your component.
>>>
>>> Does this list give you some ideas ? Dont hesitate to ask more specific
>>> questions. We are trying to help but dont really understand the problem
>>> as good as you do.
>>>
>>> regards
>>> christian campo
>>>
>>>
>>> Joel Rosi-Schwartz schrieb:
>>>> Hi,
>>>>
>>>> In ORMF we support clients registering with multiple servers and any
>>>> given server of course will have many clients. I am considering how to
>>>> best achieve this with Riena remote services. Of course your Injection
>>>> service is not useful in this instance, because a given client will
>>>> have to define many remote services of the same type; one for each
>>>> server it is interested in.
>>>>
>>>> I have been looking through the Riena code and it appears to me that my
>>>> client can create multiple RemoteServiceDescription, one for each
>>>> service on every server it is having a dialogue with. Is this the best
>>>> way to go about it? Can I cache these or is it better to create them on
>>>> demand and release after each service call?
>>>>
>>>> Thanks,
>>>> Joel
--
Joel Rosi-Schwartz
Etish Limited [http://www.etish.org]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^...^
/ o,o \ The proud parents of Useme & ORMF
|) ::: (| Open Requirements Management Framework
====w=w==== [http://www.eclipse.org/ormf/]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
Re: Client to Server remote access in a many to many topology [message #575821 is a reply to message #13366] |
Tue, 07 October 2008 16:56 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) |
|
On 2008-10-07 13:26:12 +0100, Christian Campo
<christian.campo@compeople.de> said:
> Hi Joel,
>
> this looks like our communication pingpong example. Not sure what you
> modified. It works yes.
Yes I copied the method from pingpong and tested it with that example.
What I changed was I am getting the RemoteServiceReference directly and
then simply using it rather than registering it so that it can be
retrieved later using DI.
I would like to know if this is a clean way to proceed if I do not go
the DI route. I believe deeply in the elegance of DI/IoC but nor do I
wish to be its slave :-)
> Joel Rosi-Schwartz schrieb:
>> I've been doing some investigating and experimenting, and have come up
>> with the following that works:
>>
>> void sendPing2() {
>> RemoteServiceFactory rsf = new RemoteServiceFactory();
>> Class<?> serviceInterface = IPingPong.class;
>> String url = "http://localhost:8080/hessian/PingPongWS";
>> //$NON-NLS-1$
>> String protocol = "hessian"; //$NON-NLS-1$
>>
>> IRemoteServiceReference pingPongRef =
>> rsf.createProxy(serviceInterface, url, protocol,
>> "de.compeople.pingpong.config"); //$NON-NLS-1$
>> IPingPong pingPong = (IPingPong) pingPongRef.getServiceInstance();
>>
>> Ping ping = new Ping();
>> ping.setText("AGAIN I ping you and you pong me"); //$NON-NLS-1$
>>
>> Pong pong = pingPong.ping(ping);
>> System.out.println("PingPong::Client:: " + pong); //$NON-NLS-1$
>>
>> }
>>
>> I have several questions:
>> 1. Is this pattern okay for production code?
>> 2. Should I be caching the the IRemoteServiceReference or the
>> service instance between calls?
>> 3. What is the the purpose of the config string, e.g.
>> "de.compeople.pingpong.config"?
>>
>> Cheers,
>> Joel
--
Joel Rosi-Schwartz
Etish Limited [http://www.etish.org]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^...^
/ o,o \ The proud parents of Useme & ORMF
|) ::: (| Open Requirements Management Framework
====w=w==== [http://www.eclipse.org/ormf/]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
Re: Client to Server remote access in a many to many topology [message #575834 is a reply to message #14010] |
Tue, 07 October 2008 20:15 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) |
Christian Campo![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=christian.campo%40compeople.de) Messages: 597 Registered: July 2009 |
Senior Member |
|
|
Joel,
I overlooked that change. After all they are regular OSGi Services. So its your call how you get them, either the
classic way through getServiceReference, through ServiceInjector. You can also use Declarative Services(DS) to let the
Service injected that way or use SAT (Service Activation Toolkit).
No difference the proxy its just a regular OSGi Service.
christian
Joel Rosi-Schwartz schrieb:
> On 2008-10-07 13:26:12 +0100, Christian Campo
> <christian.campo@compeople.de> said:
>
>> Hi Joel,
>>
>> this looks like our communication pingpong example. Not sure what you
>> modified. It works yes.
>
> Yes I copied the method from pingpong and tested it with that example.
> What I changed was I am getting the RemoteServiceReference directly and
> then simply using it rather than registering it so that it can be
> retrieved later using DI.
>
> I would like to know if this is a clean way to proceed if I do not go
> the DI route. I believe deeply in the elegance of DI/IoC but nor do I
> wish to be its slave :-)
>
>> Joel Rosi-Schwartz schrieb:
>>> I've been doing some investigating and experimenting, and have come
>>> up with the following that works:
>>>
>>> void sendPing2() {
>>> RemoteServiceFactory rsf = new RemoteServiceFactory();
>>> Class<?> serviceInterface = IPingPong.class;
>>> String url = "http://localhost:8080/hessian/PingPongWS";
>>> //$NON-NLS-1$
>>> String protocol = "hessian"; //$NON-NLS-1$
>>>
>>> IRemoteServiceReference pingPongRef =
>>> rsf.createProxy(serviceInterface, url, protocol,
>>> "de.compeople.pingpong.config"); //$NON-NLS-1$
>>> IPingPong pingPong = (IPingPong)
>>> pingPongRef.getServiceInstance();
>>>
>>> Ping ping = new Ping();
>>> ping.setText("AGAIN I ping you and you pong me");
>>> //$NON-NLS-1$
>>>
>>> Pong pong = pingPong.ping(ping);
>>> System.out.println("PingPong::Client:: " + pong);
>>> //$NON-NLS-1$
>>>
>>> }
>>>
>>> I have several questions:
>>> 1. Is this pattern okay for production code?
>>> 2. Should I be caching the the IRemoteServiceReference or the
>>> service instance between calls?
>>> 3. What is the the purpose of the config string, e.g.
>>> "de.compeople.pingpong.config"?
>>>
>>> Cheers,
>>> Joel
>
>
|
|
|
Goto Forum:
Current Time: Sat Aug 31 23:09:38 GMT 2024
Powered by FUDForum. Page generated in 0.05771 seconds
|