[ 
https://issues.apache.org/jira/browse/BROOKLYN-492?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15993947#comment-15993947
 ] 

Alex Heneveld commented on BROOKLYN-492:
----------------------------------------

The hack workaround suggestion was to have two files claiming identical 
versions but with different ranges on the Import-Package so that only the right 
one can be resolved, avoiding indeterminacy.  But you are correct Karaf doesn't 
let you have two installed bundles with the same name+version so that's out.

But maybe that idea will work with an extra dependency?

Let's say the problem is this:

* Author has a bundle {{my_java:1.0}} which depends on {{brooklyn}} version 
0.11, and a catalog item {{foo}} which requires code in {{my_java}} in package 
{{org.my_java}}, and this catalog item is declared in a catalog BOM depending 
on library {{http:://artifactory/path/to/my_java_1.0.jar}}
* User has deployed an instance of {{foo}} to a brooklyn 0.11 server
* Operator wants to update the brooklyn server to 0.12 -- but {{my_java:1.0}} 
doesn't work with 0.12, that bundle won't install, and as a result {{foo}} 
fails to rebind (or possibly fails after rebind)

Could a manual workaround be as follows:

# Author creates a new bundle {{my_java_real:1.0}} containing the java 
currently in {{my_java}}, and ensures that bundle depends on 
{{brooklyn:[0.11,0.12)}} (e.g. through an imports-package statement)
# Author creates an upgrade to that bundle in {{my_java_real:1.1}} which 
depends on (and is compatible with) {{brooklyn:[0.12,0.13)}}
# Author creates a new {{my_java}} which {{Import-Package: org.my_java}} (any 
version) and exports the same package
# Author installs this new {{my_java}} at the URL referenced in the BOM -- 
masking it
# Operator installs both {{my_java_real:1.0}} and {{my_java_real:1.1}} into 
their brooklyn container and uninstalls any existing (old) {{my_java}} -- which 
version of the brooklyn container doesn't matter and of course one of the 
{{my_java_real}} versions won't be resolvable but that's going to be okay
# Operator now rebinds to existing state (possibly a rebind was attempted 
previously and failed, but at least it provided an opportunity to install the 
{{my_java_real}} bundles into their container; this should pull down the new 
{{my_java}} which will then resolve the correct {{my_java_real}}

It's a bit tedious, it means manually installing dependency bundles, and 
swapping the {{my_java}} URL is ugly but:

* This gives a technique that works with either Brooklyn version
* It doesn't require the *user* to do anything
* It doesn't require doing anything to persisted state

For a v2 of {{foo}} I'd say to put {{foo}} and the BOM into in an OSGi bundle 
which declares a {{MANIFEST.MF}} dependency to {{Import-Package: org.my_java}}; 
this removes the need for the intermediate {{my_java}} bundle and means 
Brooklyn doesn't have to track any dependencies and versions, plus it means we 
don't need to update {{foo}} on a Brooklyn version change.  This doesn't solve 
the problem that we need the appropriate {{my_java_real}} bundle installed, but 
there are quite a few options -- simplest is to say to install it into the old 
version of Brooklyn, and give an option not to start it (or by default don't 
start if there is no {{catalog.bom}} contained inside) -- though in any case it 
feels like we could live without that.

There will be times when we _do_ need to update {{foo}} on a Brooklyn version 
change.  Ideally there should be a {{foo}} that works with multiple Brooklyn 
versions so we can install new {{foo}} into old-version Brooklyn instance, then 
we have a way to mark old {{foo}} as deprecated, then upgrade all old {{foo}} 
instances, then start new Brooklyn version.  But we should think through the 
case when {{foo}} _can't_ work with multiple Brooklyn versions; eg {{foo:2}} 
works with {{brooklyn:0.12}} and {{foo:3}} with {{brooklyn:0.13}}.  One 
technique could be to install {{foo:3}} into the {{brooklyn:0.12}} container 
but with some sort of "optional" flag so it doesn't complain if it can't 
resolve.  We then have a boot-time (or pre-rebind) way when starting 
{{brooklyn:0.13}} to say:  "mark {{foo:2}} optional and deprecated, and mark 
{{foo:3}} not optional, and upgrade all deprecated things".

I still think the proposal and leaning more on OSGi largely solves things.  I 
definitely prefer that over copy-state transformations!


> Brooklyn upgrade tricky if using `brooklyn.libraries` for custom OSGi bundles
> -----------------------------------------------------------------------------
>
>                 Key: BROOKLYN-492
>                 URL: https://issues.apache.org/jira/browse/BROOKLYN-492
>             Project: Brooklyn
>          Issue Type: Bug
>            Reporter: Aled Sage
>
> When a user refers to their custom OSGi bundle in a catalog's 
> {{brooklyn.libraries}} section, this could make subsequent upgrade of 
> Brooklyn more difficult.
> This is separate from Alex's email thread to dev@brooklyn "Making blueprint 
> upgrades easier - feature proposal" (i.e. it would not be solved by Alex's 
> proposal). However, it's worth thinking about that as well for a long-term 
> holistic solution.
> ---
> Consider the following steps:
> * With Brooklyn 0.11.0:
>   * A user writes a custom OSGi bundle (e.g. containing their own custom 
> policy or Java entity or whatever), compiled against Brooklyn 0.11.0.
>   * The user creates a catalog item (v1.0), which references that bundle.
>   * The user deploys some apps that use this catalog item (with their state 
> being persisted).
> * When Brooklyn 0.12.0 comes out, the user attempts to upgrade:
>   * The user tries to start 0.12.0, rebinding against their existing 
> persisted state. This reads the catalog, and thus attempts to install/active 
> the user's custom OSGi bundle.
>   * Their custom bundle may fail to install (e.g. perhaps there are wiring 
> errors due to dependency changes between 0.11.0 and 0.12.0);
>     or alternatively perhaps the bundle loads, but the instances of the Java 
> policy/entity fail to be instantiated (e.g. 0.11.0 and 0.12.0 are not binary 
> compatible, with the user's code relying on some class/method that has 
> changed).
>   * Rebind therefore might fails.
> * The user tries to update their custom OSGi bundle:
>   * The user updates their code and recompiles, to create a v2.0 of their 
> bundle and of their catalog item.
>   * However, they can't start 0.12.0 with the existing persisted state in 
> order to add the v2.0 catalog item, and upgrade their entities.
>   * The user might then try starting 0.11.0 up instead, and adding v2.0 of 
> the catalog item there.  
>     This might work, or it might lead to bundle wiring errors because v2.0 is 
> incompatible with Brooklyn 0.11.0.
> How likely this is to actually impact a user depends on: 1) what binary 
> incompatible changes we might make in Brooklyn between versions; and 2) what 
> parts of Brooklyn the user's Java code makes use of. Some power-users do some 
> pretty sophisticated things, digging into the less frequented classes of 
> Brooklyn that on first blush might not be considered part of our "api"!
> ---
> The long-term solution needs a lot more discussion on the dev@brooklyn 
> mailing list.
> However, it might well revolve around being able to start Brooklyn into a 
> usable state, even when some blueprints/entities have errors. This is 
> important so that errors can be resolved, and so that errors in some 
> blueprints don't cause the entire server to become unusable.
> This is particularly important for big companies using Brooklyn, where there 
> is a separation of teams: one team responsible for managing Brooklyn 
> servers/upgrades, and other teams responsible for writing blueprints / 
> catalog items.
> ---
> A short-term solution could involve using offline tools to transform the 
> persisted state (e.g. using something like {{bin/brooklyn copy-state ... 
> --transformations ...}}).
> Note that the {{copy-state}} commands are not readily available if one is 
> using just the Karaf distro of Brooklyn.
> Also note that {{./bin/brooklyn launch --catalogAdd ...}} is also not 
> available if using the Karaf distro of Brooklyn.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to