[openstack-dev] [Keystone] Use JSON Schemas to validate API requests data

Ken'ichi Ohmichi oomichi at mxs.nes.nec.co.jp
Wed Jun 5 04:46:20 UTC 2013


Hi,

On Tue, 04 Jun 2013 10:39:51 -0400
Russell Bryant <rbryant at redhat.com> wrote:
> > 
> >     WSME does type checking and validation.  Doug, can you comment further?
> > 
> > 
> > WSME does type conversion/checking. I typically implement validation in
> > the model class constructor so it's right there inline and easy to find.
> 
> Ah, ok, I see where the line is now.  Thanks for the clarification.
> 
> If there's value in doing jsonschema validation on top of WSME, it would
> be interesting to see a prototype to see what it would look like.

To compare both validation mechanisms, I'd like to pick two APIs.
The one is Ceilometer "v2/alarms/" API for simple validation, and
the other is Nova "v2/os-fixed-ips/{fixed_ip}/action" API for strict
validation.
I try to create these API schema prototypes like the following:

== Ceilometer "v2/alarms/" API ======================================
  *** Schema implemented with WSME ***
  class Alarm(_Base):
      alarm_id = wtypes.text
      name = wtypes.text
      description = wtypes.text
      counter_name = wtypes.text
      project_id = wtypes.text
      user_id = wtypes.text
      comparison_operator = wtypes.Enum(str, 'lt', 'le', 'eq', 'ne', 'ge', 'gt')
      [snip]

  *** Schema implemented with JSONSCHEMA ***
  alarm = {
      'type': 'object',
      'properties': {
          'alarm_id': {'type': 'string'},
          'name': {'type': 'string'},
          'description': {'type': 'string'},
          'counter_name': {'type': 'string'},
          'project_id': {'type': 'string'},
          'user_id': {'type': 'string'},
          'comparison_operator': {
              'enum': ['lt', 'le', 'eq', 'ne', 'ge', 'gt']
          },
          [snip]
      }
  }

== Nova "v2/os-fixed-ips/{fixed_ip}/action" ============================
  *** Schema implemented with WSME ***
  class FixedIpAction:
      _reserve = None
      _unreserve = None

      def get_reserve(self):
          return self._reserve

      def set_reserve(self, value):
          assert is_valid_ipv4(value), "invalid ipv4 data"
          assert _unreserve==None "Both reserve and unreserve should not be specified"
          self._reserve = value

      def get_unreserve(self):
          return self._unreserve

      def set_unreserve(self, value):
          assert is_valid_ipv4(value), "invalid ipv4 data"
          assert _reserve==None "Both reserve and unreserve should not be specified"
          self._unreserve = value

      reserve = wsme.wsproperty(str, get_reserve, set_reserve)
      unreserve = wsme.wsproperty(str, get_unreserve, set_unreserve)


  *** Schema implemented with JSONSCHEMA ***
  action = {
      'type': 'object',
      'oneOf': [
          {
              'properties': {
                  'reserve': {'type': ('null', 'string'), 'format': 'ipv4'},
              },
              'required': ['reserve'],
          },
          {
              'properties': {
                  'unreserve': {'type': ('null', 'string'), 'format': 'ipv4'},
              },
              'required': ['unreserve'],
          },
      ]
  }

I think WSME is easy to implement API schema for simple validation,
which checks parameter types only. The schema code is so simple.

On the other hand, jsonschema is easy to do it for strict validation,
which checks parameter types, lengths, ranges and formats.
If implementing strict validation with WSME, we need to create getter/
setter methods for each parameter and validation code is necessary in
getter method.


Thanks
Ken'ichi Ohmichi



More information about the OpenStack-dev mailing list