Results 1 to 10 of 14

Thread: Plan <attributes/> and <property/> usage in nested plans

Hybrid View

  1. #1
    Join Date
    Dec 2005
    Location
    Philadelphia, PA, USA
    Posts
    228

    Default Plan <attributes/> and <property/> usage in nested plans

    Hi,

    I wonder if there is a way to specify properties for bundles in one plan (nested.plan) and attributes for that property in plan (outer.plan) that will import "nested.plan"?

    nested.plan
    Code:
    ...
    <artifact type="bundle" name="webapp">
            <property name="header:Web-ContextPath" value="${host.context.path}"/>
    </artifact>
    ...
    outer.plan
    Code:
    <attributes>
            <attribute name="host.context.path" value="/host-outer"/>
        </attributes>
    <artifact type="bundle" name="core"/>
    <artifact type="bundle" name="application"/>
    <artifact type="plan" name="nested.plan"/>
    From my testing it looks like attributes specified in the outer plan and not propagated into nested plan. If nested plan does not specify attribute for a placeholder value, generation of ArtifactDescriptor fails. If both nested.plan and outer.plan specify attribute value, the one in nested.plan is used.

    Code:
    Failed to read plan descriptor
    	at com.springsource.kernel.artifact.plan.PlanBridge.generateArtifactDescriptor(PlanBridge.java:84)
    	at com.springsource.repository.internal.LocalRepository.createArtifactDescriptor(LocalRepository.java:70)
    	at com.springsource.repository.internal.watched.WatchedStorageRepository.access$2(WatchedStorageRepository.java:1)
    	at com.springsource.repository.internal.watched.WatchedStorageRepository$DirectoryWatcher$1.onChange(WatchedStorageRepository.java:153)
    ....
    
    Caused by: java.lang.RuntimeException: Failed to read plan descriptor
    	at com.springsource.kernel.artifact.plan.PlanReader.read(PlanReader.java:95)
    	at com.springsource.kernel.artifact.plan.PlanBridge.generateArtifactDescriptor(PlanBridge.java:82)
    	... 58 common frames omitted
    Caused by: java.lang.RuntimeException: No value found for placeholder 'host.context.path'
    	at com.springsource.util.common.PropertyPlaceholderResolver.resolve(PropertyPlaceholderResolver.java:122)
    	at com.springsource.util.common.PropertyPlaceholderResolver.resolve(PropertyPlaceholderResolver.java:134)
    	at com.springsource.util.common.PropertyPlaceholderResolver.resolveProperty(PropertyPlaceholderResolver.java:114)
    	at com.springsource.util.common.PropertyPlaceholderResolver.resolve(PropertyPlaceholderResolver.java:107)
    	at com.springsource.util.common.PropertyPlaceholderResolver.resolve(PropertyPlaceholderResolver.java:92)
    	at com.springsource.kernel.artifact.plan.PlanReader.replacePlaceholders(PlanReader.java:170)
    	at com.springsource.kernel.artifact.plan.PlanReader.parseArtifactProperties(PlanReader.java:163)
    	at com.springsource.kernel.artifact.plan.PlanReader.parseArtifactElements(PlanReader.java:149)
    	at com.springsource.kernel.artifact.plan.PlanReader.parsePlanElement(PlanReader.java:122)
    	at com.springsource.kernel.artifact.plan.PlanReader.read(PlanReader.java:93)
    	... 59 common frames omitted
    I don't mind modifying dm-server code or decorating it in some way. Our deployment model is to use nested plans right now. Outer plan file is basically a "scope" aggregator of related "un-scoped" components to form an "application". Use of <attributes/> and <properties/> has a potential for providing an application configuration option that is not really available from config admin stand point - because (correct me here) config admin is not "scoped" to application. Another point of doing this is to be able to deploy multiple applications side by side (i.e. dev and qa) and specify context url for web-apps at the outer most level.
    Thanks
    Dmitry

  2. #2
    Join Date
    Dec 2005
    Location
    Philadelphia, PA, USA
    Posts
    228

    Default

    A little follow up:

    I spent some time trolling through code base of deployer and I think I can achieve some of that by introducing a new artifact type. Something like "plan-fragment" in line with bundle fragments. This will get me over the ArtifactDescriptor creation issue.
    But I would still need to either:
    1. modify PlanResolver to push outer.plan attributes on the included plan-fragments.
    2. create another transformer that runs prior(?) or right after (which is better I think as the tree would be created) PlanResolver and push outer plan attributes on child plan-fragments

    I haven't scoped the amount of work that this involve. Am I even close to the "golden path" with this analysis?
    Thanks
    Dmitry

  3. #3
    Join Date
    Oct 2008
    Location
    Winchester, UK
    Posts
    535

    Default

    Sounds like there is missing function here. I don't like the idea of plan fragments though as they may have all the downsides of bundle fragments (yes, I know they can be incredibly useful, but they have far outgrown their intended I18N use case).

    A basic but clean approach would be to propagate (i.e. copy when not overriddn) attributes down the tree either during plan resolution or, preferably from an encapsulation/code structure/unit testing POV, soon after. So it sounds like a new Transformer needs adding with an appropriate service ranking.
    Glyn Normington
    SpringSource

  4. #4
    Join Date
    Dec 2005
    Location
    Philadelphia, PA, USA
    Posts
    228

    Default

    One problem with that is eager resolution of property placeholder during initial provisioning. At that time there is no knowledge of who is the parent of the placeholder holding plan. That information is only available when parent plan is deployed.

    Thought:
    It would be nice to have another attribute on the plan to mark it "incomplete" vs. creating a brand new artifact type. This attribute can be used at an argument to PlanReader.PropertyPlaceholderResolver to skip unresolved placeholders. Later when deployment happens are we have a full tree - plans with "incomplete" flag are re-resolved for placeholder values and deployment fails in that case if there are any unresolved placeholders left.

    In any case there must be a new transformer that pushes parent plan attributes onto child plans during/after PlanResolver phase. That same transformer could be in charge of re-resolving placeholders or create one more transformer i.e. SecondPassPlanAttributeResolver to do resolution.

    This is interesting stuff. I really dig the ability to extend the server with fairly minimal pain.
    Thanks
    Dmitry

  5. #5
    Join Date
    Oct 2008
    Location
    Winchester, UK
    Posts
    535

    Default

    Please could you say what you mean by "initial provisioning" as, from my perspective, the plan resolver recursively provisions the tree of plans and so as each node of type PlanInstallArtifact is created, we know who its parent is.

    (It's a good job we put the restriction of at most one parent into 2.0! That is, install artifacts form a forest rather than a general DAG. There will be lots of headaches if and when we remove that restriction, but let's discuss that on another occasion.)
    Glyn Normington
    SpringSource

  6. #6
    Join Date
    Dec 2005
    Location
    Philadelphia, PA, USA
    Posts
    228

    Default

    By "initial provisioning" I mean this chain of calls:

    WatchedStorageRepository -> LocalRepository.createArtifactDescriptor -> PlanBridge.generateArtifactDescriptor

    This happens when repositories are scanned prior to anything in pickup being deployed. Basically the stack trace that I provided in the initial post.

    This might be a bad choice of words, because there is no "provisioning" that happens just examination of available artifacts in the repositories. Sorry for confusion.

    I really would like to find some solution to this. I need to be able to switch context path for web applications without modifying multiple plan definitions. Need to re-examine our deployment strategy I guess.
    Thanks
    Dmitry

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •