OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

tosca message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: Proposal for requirement "occurrences"


Hi all, as promised here is my attempt to add clarity to Calin's ad hoc proposal.

Let's start by pretending that the counting keywords do not exist and examine what the basic grammar means.

WHAT ARE REQUIREMENT ASSIGNMENTS?

1) A node type does not in itself require anything. It does, however, allow us to declare and structurally constrain the kinds of requirement assignments would be possible for the node template. We give each requirement definition a name and can specify what base capability, node, and relationship types are allowed. A potential point of confusion is that this section is syntactically structured as a list. However, it is a sequenced list, meaning that you could only declare a requirement name once here. It is thus semantically equivalent to a map (and it's worth discussing if we should change it to a map). So, at this level there is no real meaning for asking "how many requirements" at this level. Here, no requirements are assigned and we are only providing them with structure. Example:

capability_types:

 Server: {}

 PremiumServer:
ÂÂÂ derived_from: Server

node_types:

 App:
ÂÂÂ requirements:
ÂÂÂ - host:
ÂÂÂÂÂÂÂ capability: Server

2) It's at the node template that we can actually assign requirements within the structural constraints declared at the node type. Again, if we ignore the counting keywords, this means that we don't have to assign any requirement, but we could assign a single requirement or as many as we want. Here the requirement section is a true list and we can use the same requirement name multiple times, as long as we adhere to the constraints declared in the node type for that name. The refinement grammar allows us some flexibility in assignment, and indeed we can assign a requirement of the same name several times using different refinements for each. In the other words the requirement name's use here is to tell the parser which structure to use from the sequenced list at the node type. Example:

topology_template:

 node_templates:

ÂÂÂ # No requirements assigned here
ÂÂÂ app-a:
ÂÂÂÂÂ type: App

ÂÂÂ # Single requirement assigned here
ÂÂÂ app-b:
ÂÂÂÂÂ type: App
ÂÂÂÂÂ requirements:
ÂÂÂÂÂ - host: {} # capability: Server

ÂÂÂ # Three requirements assigned here
ÂÂÂ app-c:
ÂÂÂÂÂ type: App
ÂÂÂÂÂ requirements:
ÂÂÂÂÂ - host: {} # capability: Server
ÂÂÂÂÂ - host: {} # capability: Server
ÂÂÂÂÂ - host:
ÂÂÂÂÂÂÂÂÂ capability: PremiumServer # we're allowed to use this capability type here because it derives from "Server"

3) The processor (or orchestrator) will then go through each node template's assigned requirements one at a time -- they are a list, so they are ordered -- and try to fulfil them. (We don't all agree on how fulfilment works, but let's ignore that for now. We do agree that they will be fulfilled.) In the example above "app-a" has no assigned requirements, so there's nothing to do. "app-b" has a single one. For "app-c" we have three. The first two look identical but they are separate assignments and thus will be fulfilled separately, each result ingin its own relationship. Note however that the relationship targets could be different node template but they can also be to a different or even the same capability on the same node template. The third requirement assignment is more specific than the previous two. Note that a "PremiumServer" capability could also be used to fulfil a "Server" capability, from which it is derived. So, indeed, potentially all three of these requirements assignments could end up being fulfilled by a single capability (of type "PremiumServer") of a single node template. If we'd want them to each have a different target then we would have to assign a specific node template for each requirement assignment.

Also note that we are here assuming that all requirements are "hard", meaning all requirements must be fulfilled. More on that later.

Hopefully the above is clear and not controversial. Now, let's look at the proposed keywords.

REQUIREMENT ASSIGNMENT "COUNT"

I want to start with the "count" keyword for node templates. This is an integer that must be 1 or greater and defaults to 1 if not specified. What does a number greater than 1 mean? It means: assign this requirement multiple times. Why is this useful? To avoid copying and pasting. The example above could thus be syntactically simplified as so:

ÂÂÂ # Three requirements assigned here
ÂÂÂ app-c:
ÂÂÂÂÂ type: App
ÂÂÂÂÂ requirements:
ÂÂÂÂÂ - host: # capability: Server
ÂÂÂÂÂÂÂÂÂ count: 2
ÂÂÂÂÂ - host:
ÂÂÂÂÂÂÂÂÂ capability: PremiumServer # we're allowed to use this capability type here because it derives from "Server"

Hopefully you can see why the implied default for the "count" keyword is 1. When not specified it works exactly like how TOSCA would work if the keyword didn't exist: every assignment is, well, an assignment. It's a singular thing. So, the second "host" entry in the list here indeed is a singular assignment (its implied default "count" is 1).

I hope it's also clear why a "count" of 0 doesn't make sense. It would imply that this assignment is not even here. So why would you ever write it down? :) Just omit it if you don't want it.

How useful is this feature? To be honest, I don't think it's incredibly useful. But it's very straightforward to implement and can make some designs more succinct. For example, what if you have 100 requirements assignments that are all identically structured? Just give it a "count" of 100. That's definitely shorter.

REQUIREMENT DEFINITION "OCCURRENCES"

As you recall, at the node type we only declare the structure of potential requirements. We don't actually assign them there. However, the "occurrences" keyword allows us some control over how many assignments there can be per name. Let's rewrite the examples above with it:

node_types:

 App:
ÂÂÂ requirements:
ÂÂÂ - host:
ÂÂÂÂÂÂÂ capability: Server
ÂÂÂÂÂÂÂ occurrences: [ 2, 4 ]

topology_template:

 node_templates:

ÂÂÂ # No requirements assigned here
ÂÂÂ app-a:
ÂÂÂÂÂ type: App

ÂÂÂ # Single requirement assigned here
ÂÂÂ app-b:
ÂÂÂÂÂ type: App
ÂÂÂÂÂ requirements:
ÂÂÂÂÂ - host: {} # capability: Server

ÂÂÂ # Three requirements assigned here
ÂÂÂ app-c:
ÂÂÂÂÂ type: App
ÂÂÂÂÂ requirements:
ÂÂÂÂÂ - host: {} # capability: Server
ÂÂÂÂÂ - host: {} # capability: Server
ÂÂÂÂÂ - host:
ÂÂÂÂÂÂÂÂÂ capability: PremiumServer # we're allowed to use this capability type here because it derives from "Server"

ÂÂÂ # Five requirements assigned here
ÂÂÂ app-d:
ÂÂÂÂÂ type: App
ÂÂÂÂÂ requirements:
ÂÂÂÂÂ - host: {} # capability: Server
ÂÂÂÂÂ - host: {} # capability: Server
ÂÂÂÂÂ - host: {} # capability: Server
ÂÂÂÂÂ - host: {} # capability: Server
ÂÂÂÂÂ - host: {} # capability: Server

This topology is nominally speaking invalid (more on that below). The reason is that of our three node templates only "app-c" has a total count of requirement assignments named "host" (3) that is in the range [ 2, 4 ]. "app-a" has 0 and "app-b" only has 1, while "app-d" has 5.

And that's all there is to it. By the way, the node template "count" is only indirectly related to this feature. Again, it's just about avoiding copy-paste. For example, we can rewrite node "app-d" above like so:

ÂÂÂ # Five requirements assigned here
ÂÂÂ app-d:
ÂÂÂÂÂ type: App
ÂÂÂÂÂ requirements:
ÂÂÂÂÂ - host: # capability: Server
ÂÂÂÂÂÂÂÂÂ count: 5

No difference at all. It would still fail to meet the [ 2, 4 ] range.

So, why is the requirement definition "occurrences" keyword useful? Again, I don't think it's very useful, because it's really only about counting assignments rather than other forms of control. For example, we might want to say that a certain node type should require exactly 3 servers. But that's not something we can achieve with this feature, because each requirement assignment could end up being fulfilled by the same server node template. We can only achieve this by specifying explicit node template names when assigning the requirements in the node template. So all we're doing here is saying that there have to be 3 relationships, even if they have the same target. At the end of the day the real "meat" of the design happens at the node template level, and thus I'm in favor of leaving it there and not introducing this node-type-level counting constraint, which at the end of the day is confusing. We've spent so many hours just trying to explain it to each other. I would thus vote to remove this keyword.

However, there is a small and interesting twist on it:

AUTOMATICALLY GENERATED ASSIGNMENTS

Let's for a moment ignore the upper bound of requirement definition "occurrences" and look only at the lower bound. What it means is that we need at least that number of assignments of this name in the node template. Any less would nominally result in a validation error, right?

Well, here's the thing: this error can be easily avoided by having the processor automatically generate the missing assignments for us. With that in mind, let's look again at those two node templates that did not have enough assignments (remember, the lower bound is 2):

ÂÂÂ # No requirements assigned here
ÂÂÂ app-a:
ÂÂÂÂÂ type: App

ÂÂÂ # Single requirement assigned here
ÂÂÂ app-b:
ÂÂÂÂÂ type: App
ÂÂÂÂÂ requirements:
ÂÂÂÂÂ - host: {} # capability: Server

"app-a" is missing 2 requirement assignments and "app-b" is missing 1. But we know exactly how those missing assignments could look: just the way we declared them in the node type. So, with these automatic additions the result would be semantically equivalent to this:

ÂÂÂ # Two requirement assignments added
ÂÂÂ app-a:
ÂÂÂÂÂ type: App
ÂÂÂÂÂ requirements:
ÂÂÂÂÂ - host: {} # capability: Server, automatically generated
ÂÂÂÂÂ - host: {} # capability: Server, automatically generated

ÂÂÂ # One requirement assignment added
ÂÂÂ app-b:
ÂÂÂÂÂ type: App
ÂÂÂÂÂ requirements:
ÂÂÂÂÂ - host: {} # capability: Server
ÂÂÂÂÂ - host: {} # capability: Server, automatically generated

That's quite convenient, no? It means we would never get a "not enough assignments" validation error (though we could get a "too many assignments" validation error if we exceed the upper bounds).

It also follows a very common pattern in TOSCA, whereby in many cases users do not need to refine the requirement. Without this feature, they would still have to explicitly assign requirements at the node template, even if it's just an empty "{}".

I think we've all agreed that this is a good feature.

My proposal, then, is to only have a lower bound keyword instead of a ranged "occurrences" ("occurrences" is a terrible name in any case). I would call the keyword "min_count", and it would be an integer that must be â0 and would default to 1. So, in most cases, when the keyword is not specified it would mean that the requirement must be assigned at least once. Which is usually what we mean when we declare a requirement, right? We are declaring it because we intend it to be assigned and possibly also refined.

However, there are some cases in which we really want requirement assignment to be optional. So in those cases we would set "min_count" to 0. What this means is that unless the designer explicitly assigns the requirement at the node template, then there really is no requirement. None would be automatically generated. Like so:

node_types:

 App:
ÂÂÂ requirements:
ÂÂÂ - host:
ÂÂÂÂÂÂÂ capability: Server
ÂÂÂÂÂÂÂ min_count: 0

I would ideally simplify this even further and make it a boolean instead of an integer, because again I feel like controlling the count is not useful, even if it's a minimum count. What we mostly care about here is this specific convenience feature of automatically generating an assignment if the user didn't specify one. So it would look like this:

node_types:

 App:
ÂÂÂ requirements:
ÂÂÂ - host:
ÂÂÂÂÂÂÂ capability: Server
ÂÂÂÂÂÂÂ optional: true

This is equivalent to "min_count: 0" above, meaning that automatic generation has been turned off for this requirement name and designers have to explicitly assign one or more if they want.

Note that this is VERY DIFFERENT from the "optional" keyword Calin proposed in the ad hoc for the node template level, which is about allowing for "soft" requirements that might not have to be fulfilled. In this entire discussion I have assumed we are only dealing with "hard" requirements. This is already a very long email, so I don't want to confuse things by adding to that. I hope that we can reach some kind of agreement about all of the above, and if so we could in the future discuss a "soft" requirements feature for TOSCA (which it never had) and how to implement it. Again, I think Calin's proposal for that is pretty straightforward!



[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]