brooklyn-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Aled Sage <aled.s...@gmail.com>
Subject backwards compatibility for persisted brooklyn state
Date Fri, 22 Aug 2014 11:39:31 GMT
Hi all,

I've been thinking about backwards compatibility of our persisted 
brooklyn state, in the face of us moving classes around and/or deprecating.

---
USE CASES
Let's take two use-cases:

 1. `MathPredicates.greaterThan` returns a (static) anonymous inner
    class, so is serialized by xstream as `MathPredicates$1`.
    We want to move that class to a fixed class name (e.g. `private
    static class GreaterThan {...}`) suitable for xstream.
    (It's a *really bad* idea to be using `MathPredicates$1`; if someone
    in a future release adds some code above it then the class name
    would change!)
 2. I want to move PortRanges from package `brooklyn.location.basic` to
    `brooklyn.util.net.PortRanges`.
    However, this contains inner classes such as `SinglePort`.
    If it was just code compatibility, we'd have the old `PortRanges
    extends brooklyn.util.net.PortRanges`, and do some fancy stuff to
    wrap the returned objects so they implement
    `brooklyn.location.PortRange`.

---
THE PROBLEM
xstream tries to deserialize MathPredicates$1 but that class no longer 
exists. Even if we did leave it around (yuck!), nothing changes it to 
the new class name so we could never delete it!

---
THE PROPOSED SOLUTION
I propose we have a lookup file in brooklyn that contains all the 
renamed classes.
We register a converter with xstream that, when deserializing, looks up 
this (cached) lookup file. If it contains the classname that xstream has 
encountered, we switch it for the new one and then let xstream continue 
with its deserialization.

See brooklyn.entity.rebind.persister.XmlMementoSerializer for where this 
code would go.

(Note that for the `PortRange` example, we'd require that the calling 
code had been updated to expect the new `brooklyn.util.net.PortRange` 
rather than the old `brooklyn.location.PortRange`. i.e. the returned 
instance would not implement all the same interfaces as the original 
class! We could perhaps work around that with some extra converter logic 
and wrapping classes.)

---
ALTERNATIVE SOLUTION
We could have a separate tool that is run manually once when someone is 
upgrading. It would walk through the persisted state, changing the old 
class names to the new ones.

Thoughts?

Aled


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message