Bug 487356 - Code generation fails on "pass-through" connectors
Summary: Code generation fails on "pass-through" connectors
Status: CLOSED FIXED
Alias: None
Product: Papyrus-rt
Classification: Modeling
Component: codegen (show other bugs)
Version: 0.7.2   Edit
Hardware: All All
: P3 normal
Target Milestone: 1.0.0   Edit
Assignee: Ernesto Posse CLA
QA Contact:
URL:
Whiteboard:
Keywords: Documentation
Depends on: 488134 489055 489887 515855
Blocks:
  Show dependency tree
 
Reported: 2016-02-05 11:19 EST by Ernesto Posse CLA
Modified: 2017-06-12 15:37 EDT (History)
3 users (show)

See Also:
charles: documentation+


Attachments
Relay ports, "faces" and legal connectors (1) (22.87 KB, image/png)
2016-02-09 10:09 EST, Ernesto Posse CLA
no flags Details
Relay ports, "faces" and legal connectors (2) (26.46 KB, image/png)
2016-02-09 10:09 EST, Ernesto Posse CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ernesto Posse CLA 2016-02-05 11:19:40 EST
It should be possible to connect two relay ports in a capsule, regardless of their conjugation. 

The following models from the git repository result on the code-generation exception shown below.

models/tests/RelayPortPassThrough
models/tests/RelayPortOptionalPassThrough

The exception occurs when building the instance model:

java.lang.RuntimeException: not enough secondary capsule instances to connect mediator.mout{numPortInstances:1, numParts:1} and mediator.minp{numPortInstances:1, numParts:1} with RTConnector1
		at org.eclipse.papyrusrt.codegen.instance.model.CapsuleInstance.connect(CapsuleInstance.java:269)
		at org.eclipse.papyrusrt.codegen.instance.model.CapsuleInstance.connect(CapsuleInstance.java:135)
		at org.eclipse.papyrusrt.codegen.instance.model.CapsuleInstance.connect(CapsuleInstance.java:141)
		at org.eclipse.papyrusrt.codegen.cpp.structure.model.Deployment.build(Deployment.java:43)
	...

But the models are legal UML-RT models, as confirmed by Bran.
Comment 1 Peter Cigehn CLA 2016-02-08 09:48:27 EST
(In reply to Ernesto Posse from comment #0)
> It should be possible to connect two relay ports in a capsule, regardless of
> their conjugation. 
> 

In this scenario, the conjugation of the two relay ports should be opposite of each other. You should not be able to connect two relay ports with same conjugation. It only makes sense for such a "pass through" connector to be an assembly connector, and not a relay connector.

Please also see Bug 474244 Comment 5 which states the tooling aspect of this kind of connector.
Comment 2 Ernesto Posse CLA 2016-02-08 16:43:12 EST
Right. After a lenghty discussion with Bran he confirmed that as you say, this "pass-through" connector is possible only if either the ports have opposite conjugation, or the protocol is symmetric (all messages are inout).

What is an "assembly" connector?
Comment 3 Ernesto Posse CLA 2016-02-08 17:04:17 EST
The bug occurs even when the ports have opposite conjugation.

I think I've found the reason.

During code-generation we create what we call an "instance model", this is, a snapshot of the static structure of the model (it doesn't include dynamic capsule instances, of course). This is used later on to generate the static structure in TopControllers.cc. In fact, for each capsule, this instance model is created twice: first when the code for the capsule (CapsuleGenerator) is generated and then when the whole structure is generated (CompositionGenerator). The first creates only a shallow instance model and the second creates a deep one. 

The problem occurs in the second, more precisely in CapsuleInstance.java, lines 261-276. The instance model is build top-down, so in this model, we start from Top, create CapsuleInstances for each part in top: sender:Sender, receiver:Receiver and mediator:Mediator. This also creates PortInstances. Then we visit the connectors and connect the corresponding PortInstances. Then we recurse on the capsule instances and in particular we visit the CapsuleInstance for mediater:Mediator and do the same. But at this point, the PortInstances of the mediator CapsuleInstance have already been connected to their far-ends. However, in lines 261 and 262, when we try to obtain the far-ends for the mediator ports, we get null. This is because the PortInstances have *not* been marked with "isRelay = true". In other words, the code generator has failed to detect that these ports are relay ports.

I think this may be fixed by removing the condition in line 241 which allows to mark the relevant ports as relay ports.
Comment 4 Eclipse Genie CLA 2016-02-08 17:06:28 EST
New Gerrit change created: https://git.eclipse.org/r/66162
Comment 5 Peter Cigehn CLA 2016-02-09 03:57:06 EST
(In reply to Ernesto Posse from comment #2)
> Right. After a lenghty discussion with Bran he confirmed that as you say,
> this "pass-through" connector is possible only if either the ports have
> opposite conjugation, or the protocol is symmetric (all messages are inout).
> 
> What is an "assembly" connector?

First I need to correct myself. In Comment 1 I incorrectly wrote "relay connector". There is actually no such thing. I meant to write "delegation connector".

When it comes to the connector kind, I realize that it is a bit tricky, since my experience from the legacy tooling also is based on earlier version of UML. In that earlier versions of UML that the legacy tooling is based on, the connector kind was a non-derived property, i.e. either set to "assembly" or "delegation", and we had several cases where the legacy tooling set the connector kind incorrectly and we have discussed back and forth for several different cases which kind different connectors really should be.

But in the latest version of UML, connector kind has been changed to a derived property. The derivation is now specified like this:

body: if end->exists(
           role.oclIsKindOf(Port)
           and partWithPort->isEmpty()
           and not role.oclAsType(Port).isBehavior)
then ConnectorKind::delegation
else ConnectorKind::assembly
endif

Basically this means that this case with a "pass-through" connector will be treated as a delegation connector. In the legacy tooling (based on the earlier version of UML with a non-derived property) such a "pass-through" connector is set explicitly to be an "assembly" connector. But I guess we just have to accept that the kind will be "delegation", which probably makes sense.

I myself have always used the following rule-of-thumb when it comes to conjugation rules: delegation connector -> same conjugation and assembly connector -> opposite conjugation. This is also what I wrote in Bug 474244 Comment 0 (Remi has copy-pasted my text into the Bugzilla).

But I now realize that this special case will be breaking this rule-of-thumb, since the derivation rule will make this a delegation connector, but it should still have opposite conjugation. Well, I guess that this will be the exception that proves the rule... :(

Regarding this special case with pure symmetrical protocols, I am really not sure that we should bother about that. Sure, at the time the connector is created, the protocol might be purely symmetrical. But it can then later be changed to a be non-symmetrical and then the conjugation rule is broken. I would strongly suggest that we keep it simple and only allow "pass-through" connectors to be created between compatible relay ports with opposite conjugation.
Comment 6 Bran Selic CLA 2016-02-09 05:09:23 EST
This is a problem that is caused by the stupid decision in UML 2 to differentiate connectors (delegation vs. assembly) rather than ports (relay vs end/behavior). I resisted it, but lost in the end. Had I thought of this particular and rather uncommon case, I would have won the debate.

One helpful way to think about it is to imagine that EVERY port has two "faces". On the outward face (i.e., facing outside its container), the port "speaks" the explicitly declared protocol of the port (base or conjugate). However, on the implicit inward face, it speaks the conjugate of the port's declared protocol. (In fact, this holds for all ports, whether they are relay or behaviour: they take whatever comes in on the outward face and pump it out through its inward face -- even if that face is attached to a behaviour -- and vice versa for signals going in the opposite direction.)

Therefore, when this is understood, it should be clear that a pass-through connector is perfectly valid.

I had a discussion with the Zeligsoft team about this and their code generator now does the right thing.
Comment 7 Ernesto Posse CLA 2016-02-09 10:09:03 EST
Created attachment 259663 [details]
Relay ports, "faces" and legal connectors (1)
Comment 8 Ernesto Posse CLA 2016-02-09 10:09:28 EST
Created attachment 259664 [details]
Relay ports, "faces" and legal connectors (2)
Comment 9 Ernesto Posse CLA 2016-02-09 10:16:36 EST
For reference, I've added the diagrams we (Bran and I) discussed, illustrating the "faces" concept.

In the first file, Diagram 1 shows a legal (delegation) connector (conn2), connecting two ports (q and r) with the same conjugation. Diagram 2 makes the faces explicit.

For a base port ( p) the outer face is white and the inner face is black. 
For a conjugate port (q,r), the outer face is black and the inner face is white.

The rule is that a connector can only connect "opposite" faces.

Diagram 3 is illegal because, as depicted in Diagram 4, a connector would connect faces with the same colour.

The second file illustrates the case with a "pass-through" connector, where the protocol is *not* symmetric.

Diagram 5 is legal, since, as shown in Diagram 6, connectors only connect opposite faces.

On the other hand, Diagram 7 is illegal, because, as shown in Diagram 8, conn2 connects faces with the same colour.
Comment 10 Charles Rivet CLA 2016-08-29 15:56:50 EDT
No activity for a while. Can this be considered fixed? Does it need more testing?
Comment 11 Ernesto Posse CLA 2016-08-29 16:06:32 EDT
I don't remember if this is fixed, but I don't have time to check this right now, and it is not a priority. I can check after MODELS.
Comment 12 Peter Cigehn CLA 2016-08-30 08:52:17 EDT
(In reply to Charles Rivet from comment #10)
> No activity for a while. Can this be considered fixed? Does it need more
> testing?

Related to this is that the tooling does not yet support the creation of a "passthrough" connector, as part of Bug 474244. So I guess the work with the tooling must, to some extent at least, be aligned with support in the code-generator.
Comment 13 Charles Rivet CLA 2016-08-30 09:55:17 EDT
(In reply to Ernesto Posse from comment #11)
> I don't remember if this is fixed, but I don't have time to check this right
> now, and it is not a priority. I can check after MODELS.

OK. It will have to be a documented known issue for v0.8/MVP1
Comment 14 Charles Rivet CLA 2016-08-30 09:57:16 EDT
(In reply to Peter Cigehn from comment #12)
> (In reply to Charles Rivet from comment #10)
> > No activity for a while. Can this be considered fixed? Does it need more
> > testing?
> 
> Related to this is that the tooling does not yet support the creation of a
> "passthrough" connector, as part of Bug 474244. So I guess the work with the
> tooling must, to some extent at least, be aligned with support in the
> code-generator.

I will leave it up to Ernesto to determine whether 474244 has an impact on his solution.
Comment 15 Charles Rivet CLA 2016-11-07 15:03:25 EST
This bug's gerrit submission was merged back on 2016-03-17.

Is it now fixed?

If so,is it only waiting on Bug 489055 to be closed?
Comment 16 Ernesto Posse CLA 2016-11-07 16:29:27 EST
(In reply to Charles Rivet from comment #15)
> This bug's gerrit submission was merged back on 2016-03-17.
> 
> Is it now fixed?
> 
> If so,is it only waiting on Bug 489055 to be closed?

I need to do a bit more testing to be sure, as this issue was trickier than one would expect.
Comment 17 Eclipse Genie CLA 2017-01-20 15:44:54 EST
New Gerrit change created: https://git.eclipse.org/r/89254
Comment 19 Ernesto Posse CLA 2017-01-20 15:55:19 EST
Updated test models under models/tests/codepattern/structure. They are named RelayPort*Passthrough.

The bug has been fixed and all tests pass except for RelayPortOptionalMixedPassThrough which fails incarnating a capsule. This issue is tracked in Bug 489887 which has target milestone set to 1.0.

Since there is one test case that fails, but it seems to be failing for a different reason (failed incarnation), I cannot mark this as closed, but on Simon's advice I'm moving the milestone of this one to 1.0 and making it depend on Bug 489887, just in case this is still a problem when the other bug has been fixed.
Comment 20 Ernesto Posse CLA 2017-05-23 14:17:14 EDT
I'm adding a dependency on Bug 515855 because if optional parts are initialized incorrectly, then the behaviour of the last test model will be incorrect.
Comment 21 Eclipse Genie CLA 2017-06-12 15:15:01 EDT
New Gerrit change created: https://git.eclipse.org/r/99169
Comment 23 Ernesto Posse CLA 2017-06-12 15:36:47 EDT
Fixed.
Comment 24 Ernesto Posse CLA 2017-06-12 15:36:58 EDT
Verified.
Comment 25 Ernesto Posse CLA 2017-06-12 15:37:07 EDT
Closing.