[openstack-dev] [Murano] Improvements to MuranoPL contracts

Stan Lagun slagun at mirantis.com
Mon May 26 14:40:09 UTC 2014


Hello everyone!

Recently I've been looking for a best way to fix incorrect handling of
defaults in MuranoPL's property contracts [1]. I analyzed how contracts
used in applications that are currently in app-incubator, typical mistakes
and usage patterns. I've found number of places where contract system can
be significantly improved. Here is my list of proposed improvements I'd
like to deliberate with you:

Problem: when contract violation happens it is very hard to tell without
debugger what went wrong. Especially this is a problem for complex nested
structures. Currently it even impossible to tell which property caused
exception during class load

Solution: during contract traversal keep track of path to a part of
contract being processed (for example 'foo/0/bar'). Include that path in
every thrown exception alongside with human-readable description describing
what value was processed and what contract was violated. Prepend property
name to exception text so that is would be clear what property cannot be
initialized. The same for method arguments.

---

Problem: Single default value is not enough for properties that are not of
scalar type.
For example if we have contract like
- name: $.string()
  disabled: $.bool()

(array of structures) it is reasonable to have default value for "disabled"
attribute of each list entry whereas there is no meaningful default for
"name" attribute. Current approach allows to provide initial filling of
entire array which is obviously not what developer expects.

Solution: to have Default reflect contract structure so that different
parts of Default can serve as an independent defaults for corresponding
parts of the contract. Default need to be traversed in parallel with
contract spec and provided value. Default value need not provide value for
every single attribute mentioned in contract spec and thus can be simpler
than contract itself.

---

Problem: Default value is only used when no property value provided at all.
Null (None) value is a valid value even if it not valid for particular
contract. Thus is null is passed Default is not used.

Solution: to treat every missing value as null. Missing Default is also
considered to be null. This greatly simplifies understanding of contracts
and client development (it is easier to set attribute value to None rather
then deleting attribute from object if default value is desired, especially
for generic clients)

---

Problem: most of the time developer writes $.int() contract he doesn't
realize that null is also valid value for such contract and the correct
form is $.int().notNull(). This is even more obvious in case of bool().
Developers are lazy and usually forget to wright long verbose contracts.

Solution: to make all primitive types be not-nullable with obvious defaults
(0 for int, false for bool).
This is enough for 95% of use cases. For the rest 5% where null value does
valid to have separate contract methods optionalInt(), optionalBool() etc.

As for strings I think that the same approach should be used - $.string()
is a non-nullable sequence of chars with empty string as a default. And
there should also be optionalString() that es equal to current $.string().
But in most cases when developer writes $.string() what he really wants is
$.string().notNull().trim().notEmpty(). So while it is reasonable to have
all this helper functions (notEmpty(), notBlank(), trim() etc.) is would be
great to have one contract function that does exactly that.

---

While some of proposed changes can possible break existing contracts in
practice they just legalize current state of affairs so nothing would break.

What do you think?

[1]: https://bugs.launchpad.net/murano/+bug/1313694

Sincerely yours,
Stan Lagun
Principal Software Engineer @ Mirantis

 <slagun at mirantis.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstack.org/pipermail/openstack-dev/attachments/20140526/3d23c748/attachment.html>


More information about the OpenStack-dev mailing list