<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jun 5, 2013 at 12:46 AM, Ken'ichi Ohmichi <span dir="ltr"><<a href="mailto:oomichi@mxs.nes.nec.co.jp" target="_blank">oomichi@mxs.nes.nec.co.jp</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Hi,<br>
<div class="im"><br>
On Tue, 04 Jun 2013 10:39:51 -0400<br>
Russell Bryant <<a href="mailto:rbryant@redhat.com">rbryant@redhat.com</a>> wrote:<br>
> ><br>
> >     WSME does type checking and validation.  Doug, can you comment further?<br>
> ><br>
> ><br>
> > WSME does type conversion/checking. I typically implement validation in<br>
> > the model class constructor so it's right there inline and easy to find.<br>
><br>
> Ah, ok, I see where the line is now.  Thanks for the clarification.<br>
><br>
> If there's value in doing jsonschema validation on top of WSME, it would<br>
> be interesting to see a prototype to see what it would look like.<br>
<br>
</div>To compare both validation mechanisms, I'd like to pick two APIs.<br>
The one is Ceilometer "v2/alarms/" API for simple validation, and<br>
the other is Nova "v2/os-fixed-ips/{fixed_ip}/action" API for strict<br>
validation.<br>
I try to create these API schema prototypes like the following:<br>
<br>
== Ceilometer "v2/alarms/" API ======================================<br>
  *** Schema implemented with WSME ***<br>
  class Alarm(_Base):<br>
      alarm_id = wtypes.text<br>
      name = wtypes.text<br>
      description = wtypes.text<br>
      counter_name = wtypes.text<br>
      project_id = wtypes.text<br>
      user_id = wtypes.text<br>
      comparison_operator = wtypes.Enum(str, 'lt', 'le', 'eq', 'ne', 'ge', 'gt')<br>
      [snip]<br>
<br>
  *** Schema implemented with JSONSCHEMA ***<br>
  alarm = {<br>
      'type': 'object',<br>
      'properties': {<br>
          'alarm_id': {'type': 'string'},<br>
          'name': {'type': 'string'},<br>
          'description': {'type': 'string'},<br>
          'counter_name': {'type': 'string'},<br>
          'project_id': {'type': 'string'},<br>
          'user_id': {'type': 'string'},<br>
          'comparison_operator': {<br>
              'enum': ['lt', 'le', 'eq', 'ne', 'ge', 'gt']<br>
          },<br>
          [snip]<br>
      }<br>
  }<br>
<br>
== Nova "v2/os-fixed-ips/{fixed_ip}/action" ============================<br>
  *** Schema implemented with WSME ***<br>
  class FixedIpAction:<br>
      _reserve = None<br>
      _unreserve = None<br>
<br>
      def get_reserve(self):<br>
          return self._reserve<br>
<br>
      def set_reserve(self, value):<br>
          assert is_valid_ipv4(value), "invalid ipv4 data"<br>
          assert _unreserve==None "Both reserve and unreserve should not be specified"<br>
          self._reserve = value<br>
<br>
      def get_unreserve(self):<br>
          return self._unreserve<br>
<br>
      def set_unreserve(self, value):<br>
          assert is_valid_ipv4(value), "invalid ipv4 data"<br>
          assert _reserve==None "Both reserve and unreserve should not be specified"<br>
          self._unreserve = value<br>
<br>
      reserve = wsme.wsproperty(str, get_reserve, set_reserve)<br>
      unreserve = wsme.wsproperty(str, get_unreserve, set_unreserve)<br></blockquote><div><br></div><div style>This API looks odd to me. The "action" to take as part of the payload of the message, where I would have thought they should be separate endpoints. If there were separate reserve and unreserve endpoints in the API, then each would only need to declare that they took an IPv4 address as an argument, along with whatever else is needed (the instance id?). That IPv4 address would be represented by new WSME user-defined type, which would be reusable throughout the APIs that work with network addresses. It would not be possible to specify both reserve and unreserve at the same time, so you wouldn't need that check at all.</div>
<div style><br></div><div style>Doug</div><div style><br></div><div style> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
  *** Schema implemented with JSONSCHEMA ***<br>
  action = {<br>
      'type': 'object',<br>
      'oneOf': [<br>
          {<br>
              'properties': {<br>
                  'reserve': {'type': ('null', 'string'), 'format': 'ipv4'},<br>
              },<br>
              'required': ['reserve'],<br>
          },<br>
          {<br>
              'properties': {<br>
                  'unreserve': {'type': ('null', 'string'), 'format': 'ipv4'},<br>
              },<br>
              'required': ['unreserve'],<br>
          },<br>
      ]<br>
  }<br>
<br>
I think WSME is easy to implement API schema for simple validation,<br>
which checks parameter types only. The schema code is so simple.<br>
<br>
On the other hand, jsonschema is easy to do it for strict validation,<br>
which checks parameter types, lengths, ranges and formats.<br>
If implementing strict validation with WSME, we need to create getter/<br>
setter methods for each parameter and validation code is necessary in<br>
getter method.<br>
<br>
<br>
Thanks<br>
<span class="HOEnZb"><font color="#888888">Ken'ichi Ohmichi<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
_______________________________________________<br>
OpenStack-dev mailing list<br>
<a href="mailto:OpenStack-dev@lists.openstack.org">OpenStack-dev@lists.openstack.org</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
</div></div></blockquote></div><br></div></div>