Two services using an abstract service

Hello,

at the moment, I'm writing 2 Services (lets say A and B), that use the interface of an abstract Service (C). Service A uses the whole operation port of Service C, while Service B has an own one and additionally implements the interface of C with the AlternateServicePort attribute. The URI Strings in each ServicePort amd AlternateServicePort attribute are unique.

Now I have a Service D who wants to communicate with Service A and Service B. So I create 2 OperationPorts with type of C. An in the URI in the Partner Attribute I specify which of the services (A or B) I want to use. Right?

But if I send messages to both services (A and B) only A gets all the messages...
If I stop A, they are sent to B...
Where is the problem?

By the way, I'm using MSRS 1.0...

[793 byte] By [theSailor] at [2008-2-18]
# 1

Does it work if you use ServiceForwarders?

I strongly recommend installing the latest CTP before trying anything as the current version has lots of improvement in the infrastructure since v1.0. Also you can have v1.5CTP side by side with the older installation.

OmidK.Rad at 2007-9-25 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Decentralized Software Services (DSS)...
# 2

MSRS 1.0 or 1.5 should work the same way in regards to this.

I dont see a probelm with what you our trying to do. Only thing that would cause the issue, is from your service D, the uris are wrong.

Can you post some example sof the uris for service A and B you are using?

GeorgeChrysanthakopoulos at 2007-9-25 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Decentralized Software Services (DSS)...
# 3

sure, here is some sample code:

This is the operationPort of service A:

Code Snippet

[ServicePort("/motionplanning", AllowMultipleInstances=true)]

private ump.UniversialMotionPlanningOperations _mainPort = new ump.UniversialMotionPlanningOperations();

and this is the OperationPort of service B:

Code Snippet

[ServicePort("/orchestration", AllowMultipleInstances=false)]

private OrchestrationOperations _mainPort = new OrchestrationOperations();

[AlternateServicePort("/OrchestrationMP", AlternateContract = ump.Contract.Identifier, AllowMultipleInstances = true)]

private ump.UniversialMotionPlanningOperations _mpPort = new ump.UniversialMotionPlanningOperations();

The partner implementation of Service D looks like this:

Code Snippet

[Partner("motionplanning", Contract = ump.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExisting)]

private ump.UniversialMotionPlanningOperations _mpPort = new ump.UniversialMotionPlanningOperations();

[Partner("OrchestrationMP", Contract = ump.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExisting)]

private ump.UniversialMotionPlanningOperations _orcPort = new ump.UniversialMotionPlanningOperations();

I also tried to use a '/' in front of the name in the partner attribute at service D, there was no difference in the behaviour...

theSailor at 2007-9-25 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Decentralized Software Services (DSS)...
# 4
In Service D, you are specifying both partners to use the ump.Contract.Identifier which is the contract identifier URI for the generic contract C (not A or B). So in this case I think the runtime hooks up with the first running service it finds that implements contract C for each of the partners which results in both partners to use Service A. If for "motionplanning" partner you use the contract of Service A (srvcA.Contract.Identifier) and for "OrchestrationMP" you use the contract of Service B (srvcB.Contract.Identifier) then it should work. However, that way the problem is you won’t be using the generic service C in the generic manner it is meant to be used because of partnering with the implementing services directly rather than the generic contract itself. This is an interesting problem though, I think there should be a good solution for it.
OmidK.Rad at 2007-9-25 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Decentralized Software Services (DSS)...
# 5

ok, with changing the partner definition of Service D to

Code Snippet

[Partner("/motionplanning", Contract = motion.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExisting)]

private ump.UniversialMotionPlanningOperations _mpPort = new ump.UniversialMotionPlanningOperations();

[Partner("/OrchestrationMP", Contract = ump.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExisting)]

private ump.UniversialMotionPlanningOperations _orcPort = new ump.UniversialMotionPlanningOperations();

I got it working...

But this only works, if one of the services uses the operationport of the abstract service as its own main operation port.

When I changed the contract in the orchestrations partner attribute to the orchestration identifier, I received an error, because only the alternate operations port could receive the message types I sent...

What would be a solution if I have to services (A and B) with a main port and an alternate port (from C) and I want to send commands from a service D to the alternate port of services A and B? Then the contract identifier must point in both cases to service C because otherwise the messages are sent to the main port and not the alternate one. Are the destination services then identified by the string URI?

Thanks,

theSailor

theSailor at 2007-9-25 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Decentralized Software Services (DSS)...
# 6

next interesting behaviour:

I got it running using the above mentioned Partner und ServicePort attributes.

Service A is a orchestration service, that can hold a number of motion planning operations and send it later to the motion planning service (Service B). The Interface of Service B is implemented in an abstract Service C (UniversalMotionPlanning)

For this purpose Service A uses the interface of Service B as alternate ServicePort (for the user there is no difference between using the motion planning service directly or sending messages to the orchestration service and execute a sequence of movements).

Now, for sending its commands to the motion planning service, Service A needs Service B as a partner.

So I added the following partner definition to Service A:

Code Snippet

[Partner("/motionplanning", Contract = motion.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExisting)]

private ump.UniversialMotionPlanningOperations _mpPort = new ump.UniversialMotionPlanningOperations();

Now something interesting is happening:

All the commands from the Dashboard service (the above mentioned service D) are not sent to the orchestration service (as they did before) but directly to the motion planning service. But I have no idea why!

theSailor at 2007-9-25 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Decentralized Software Services (DSS)...
# 7
theSailor wrote:

What would be a solution if I have to services (A and B) with a main port and an alternate port (from C) and I want to send commands from a service D to the alternate port of services A and B? Then the contract identifier must point in both cases to service C because otherwise the messages are sent to the main port and not the alternate one. Are the destination services then identified by the string URI?

Thanks,

theSailor

Note, if your service has an alternate port, it will get a different URI than its main port (you can specify even that URI in the AlternateServicePort attribute). Knowing that uri, you can now use it froma nother service directly.

My recommendation is that you use manifest to start the services, and supply the fixed,/know URI in the partner lists of the service records. YOu then controla everything exactly. Your partner attributes int he services dont change: Manifest override and precede partner attributes, and everything still gets hooked up the same. SAme thing we do for example in our sample services (like LegoRCX car manifest) where use a manifest to start a drive, and 4 motors, and supply the motors as partners. YOu can explicitly specify the URI the motor will take, and then the drive gets hooked up exactly to the URI. So if you specify the altnerate contract poirt URI, the drive *will* use that port, not the main port.

I know this all gets complicated, but this is a complicated case. VPL will make this easier, since we are working a new manifest editor that grpahically shows you the manifests, service dependencies and how to wire up partners! It can be used for services your authored or VPL generated services, or any manifest!

GeorgeChrysanthakopoulos at 2007-9-25 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Decentralized Software Services (DSS)...
# 8
in the dashboard, what URI did you select? The dashboard will send the commands to the URI you select, that implements the drive contract
GeorgeChrysanthakopoulos at 2007-9-25 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Decentralized Software Services (DSS)...

Microsoft Robotics Studio

Site Classified