Alex,
Comments inline ...
On 5/10/2013 7:18 AM, Alex Heneveld
wrote:
Folks-
I set out the main questions a wee while ago. Now I want to share
some summaries of some of the answers.
Here are the approaches we have discussed to question 1, including
a better explanation about why typed
requirements are useful. (Starting with a summary of the
questions.)
--A
BIG QUESTIONS
(1) handling dependencies: implicit requirements on typed
containers, or typed requirements, or mixins
(2) how to express component specifications (abstract, interfaces,
etc)
(3) how to handle parameters and references
(4) what does POST take (CAMP-3 / CAMP-65 -- ie multi-part etc)
SMALL QUESTIONS
(5) where to put deployment plan metadata: top-level tags or a
separate section
(6) key name: "specifications" or "components" or "resources" or
something else?
(7) allow specifications to be a map where "id" is provided as a
key (for readability and referenceability) ?
---
Preface
I think we are generally agreed that the core of the DP consist of
a list of "specification" objects (ComponentSpecification) which
typically refer to types understood by the system, often but not
necessarily corresponding to ApplicationComponents. Thus we could
say:
specifications:
- type: com.example.java:WAR
content: { href: VitaMinder.war }
"com.example.java:WAR" is a type understood at the platform -- its
documentation and implementation would specify its behaviour, for
instance as indicating a web archive which will by default be
deployed and run in a servlet container. (That might be a tomcat
process or a PaaS ... up to the platform in this case.)
---
Re (1) handling dependencies: implicit requirements on typed
containers, or typed requirements, or mixins
Consider the code above, and imagine that I want to further
specify a JVM version, dependency injection scheme, and a required
available heap size (-Xmx) for the container(s) where this runs.
There are two general approaches which have been suggested and a
third I'm suggesting here, listed below.
(1a) implicit requirements on typed containers (Gil)
specifications:
- type: com.example.java:WAR
content: { href: VitaMinder.war }
requirements:
- targetType: com.example.java:ServletContainer
dependencyInjectionMode: spring
javaVersion: [1.6,)
heapMemory: 768M
In this model the meaning of the attributes
"dependencyInjectionMode", "javaVersion", and "heapMemory" are
documented and implemented by a type ServletContainer which I
imagine as a platform component. Thus we could also write it as
follows (where "fulfillment" is a way of pointing to an instance
potentially shared across multiple items).
specifications:
- type: com.example.java:WAR
content: { href: VitaMinder.war }
requirements:
- fulfillment: id:appserver
- type: com.example.java:ServletContainer
id: appserver
dependencyInjectionMode: spring
javaVersion: [1.6,)
heapMemory: 768M
On our internal call yesterday morning, the Oracle people were
unanimous in their dislike for using "ComponentSpecifications" (or
whatever we decide to call them) to describe platform-provided
components. We think there are fundamental differences between
describing a component that you are supplying (either in the PDP or
through a reference to some other location) and describing the
features that a platform component must have in order to satisfy
your requirements. The later is not really a description of "a
component" but rather the outlines of an entire sheaf of possible
services that could satisfy the needs to the component. Putting both
of these kinds of things at the same level in the DP is confusing
because there are semantically different statements.
(1b) typed requirements (Alex original)
specifications:
- type: com.example.java:WAR
content: { href: VitaMinder.war }
requirements:
- type: com.example.java:ServletDeployment
dependencyInjectionMode: spring
javaVersion: [1.6,)
heapMemory: 768M
In this model the meaning of the attributes
"dependencyInjectionMode", "javaVersion", and "heapMemory" are
documented and implemented by a type ServletDeployment which is a
new requirement/relationship type. The key difference here is
that it is NOT a component type, but rather its implementation is
responsible for finding/creating the appropriate platform
component (which would probably be a ServletContainer).
My contention is that by making the _link_ explicit we get more
expressivity than in (1a), essentially separation of concerns
between those restrictions on the component itself versus the
wiring instructions / external component requirements. More on
this below.
Making the link explicit might be more expressive (though I'm not
sure I agree), but it also makes it less explicit. How is the
platform supposed to know what kind of platform component is going
to be on the other end of a link of type
"com.example.java:ServletDeployment"? It seems you would have to
specify, somewhere, that links of type
"com.example.java:ServletDeployment" can reference platform
components of type "com.example.java:ServletContainer" (and types
that inherit from that type?) It seems simpler jut to explicitly
list the type of the platform component(s) that can satisfy the
requirement (as in 1a).
You could also be explicit about the fulfillment and
so in (1b) you could also say:
specifications:
- type: com.example.java:WAR
content: { href: VitaMinder.war }
requirements:
- type: com.example.java:ServletDeployment
fulfillment: id:appserver
- type: com.example.java:ServletContainer
id: appserver
dependencyInjectionMode: spring
javaVersion: [1.6,)
heapMemory: 768M
And assuming that the 3 attributes we're caring about here (DI
mode, java version, minRam) have the same semantics whether they
are on the deployment requirement or on the appserver component
they could be put on either. But again more on this below.
There isn't that much difference between this and 1a. You've
promoted the "targetType" stuff to it's own ComponentSpecification
and referenced it from your requirement. The only additional
information is the requirement type
"com.example.java:ServletDeployment" which, as I've said before, is
redundant unless there is more than one thing you can do with a WAR
file and a servlet container. If there were (for example, suppose we
could deploy a WAR file on a servlet container as either a
stand-alone application or a shared-library), you could resolve this
with another attribute on the requirement. So:
specifications:
- type: com.example.java:WAR
content: { href: VitaMinder.war }
requirements:
-
targetType: com.example.java:ServletContainer
action: deployAsSharedLibrary
dependencyInjectionMode: spring
javaVersion: [1.6,)
heapMemory: 768M
(1c) mixins
This is really a simplification of (1b) but we drop the separate
requirements block, and allow referring to a requirement type
directly in the component, and we also allow requirements to
indicate attributes on a component which they can interpret. Thus
if "com.example.java:ServletDeployment" registered itself as a
handler for a "deployment" attribute on "com.example.java:WAR" we
could write:
specifications:
- type: com.example.java:WAR
content: { href: VitaMinder.war }
deployment:
dependencyInjectionMode: spring
javaVersion: [1.6,)
heapMemory: 768M
The advantage here over (1b) is mainly that the plans are tighter.
Plus people seem to like mixins these days -- this is the
extensibility model used in OCCI where it seems to work nicely.
But it could get confusing putting everything at the top level.
I am undecided between (1b) and (1c) -- or even something better
yet to come. However I am opposed to (1a). I think I was muddled
on the call Tuesday but let me give some clear examples where I
think (1a) is problematic:
- say we are deploying multiple WAR files to the same container,
but to different context paths: in (1a) the context path (e.g.
"/app1" and "/app2") doesn't belong as part of the WAR, but
neither can it go on the Container -- it is an attribute of the
relationship/requirement between the two (in 1b and 1c it fits
neatly in the Deployment type)
- similarly we can imagine that the heapMemory might be supplied
per WAR deployment, resulting in the heapMemory at the container
which is the _sum_ of all the apps deployed there
- finally (for a non-java example) imagine we are supplying a
bunch of images as part of customising / white-labelling a
"BlogSite" component; we need a way to say how each image should
be used, e.g. component spec "image1" is the favicon for component
spec "myblog" and component spec "image2" is the banner for
"myblog": again favicon/banner/etc are aspects of the
relationship between the two
I think we all decided on Monday's call that mixins were too messy
to deal with; no way to sort out which attributes apply to which
requirements.
Lastly I want to sanity check that we really do need
to decide this. A simple option would be just to specify the
outline -- i.e. what is in the preface, leaving it up to the
component spec types and the platforms to decide what all the
attributes inside mean, even the "requirements". That would make
the DP spec fairly small and easy to understand. *But* I fear it
will cause too much interoperable issues as it leaves a whole lot
which different types would have to agree on by convention -- or
do the same things in different ways.
It's a judgement call, but I agree with you; I don't see how we can
neglect to specify the basics of how you describe what is in the PDP
and how you specify at least the higher-level aspects of the
services that stuff depends upon.
That said we could start with that, then refine it
once we have done some interop, especially if we don't reach a
decision soon on the finer points (choosing 1a / 1b / 1c / other).
+1. Let's try to agree on the simplest stuff that *has* to be there,
and noodle on the finer points in interop testing.
END
---------------------------------------------------------------------
To unsubscribe from this mail list, you must leave the OASIS TC
that generates this mail. Follow this link to all your TCs in
OASIS at:
https://www.oasis-open.org/apps/org/workgroup/portal/my_workgroups.php
|