Opened 20 years ago

Closed 16 years ago

#996 closed defect (fixed)

Need a OWS version negotiation function...

Reported by: sdlime Owned by: tomkralidis
Priority: high Milestone: 5.2 release
Component: WMS Server Version: unspecified
Severity: normal Keywords:
Cc: mapserverbugs, warmerdam

Description (last modified by dmorissette)

It would be helpful to eventually have some sort of a function to apply the negotiation rules set forth in the various OGC specs. I believe the logic is consistent from spec to spec. Input would be the requested version and an array of supported versions and the result would be the version to return.

Something like:

  int MS_NUMWCSVERSIONS = 2
  char *wcsVersions[MS_NUMWCSVERSIONS] = {"1.0.0", "1.1.0"};

  version = msOWSGetVersion(request->version, wcsVersions);

A requested version of 1.2.0 would return 1.0.0 and so on. Not a big deal for WFS and WCS at the momement since there's only one version out, but for WMS I would think version negotiation would be getting cumbersome. I see Julien has already added functions to turn version strings into numbers so comparison is easy so we're part way there.

Steve

BTW I've attached this to WMS component in lieu of a OWS component...

Change History (13)

comment:1 by dmorissette, 20 years ago

Milestone: FUTURE
It would likely be more efficient to use an array of OWS_x_y_z constants (from
mapows.h) for the list of supported versions, starting with the highest version
number so that it is found first, e.g.

  int wcsVersions[] = {OWS_1_1_0, OWS_1_0_0, OWS_NULL_VERSION};

  version = msOWSGetVersion(request->version, wcsVersions);

Then internally the comparison would just be a loop that would return the first
entry that's lower than or equal to the requested version, or the lowest version
if the requested version is lower than the lowest version (that's the rule). If
request->version is not set then the highest version should be returned.

Note that version negotiation is likely to change in future specs to a mode
where the client sends a list of versions it is ready to accept (the
AcceptVersions parameter). This is described in section 7.3.2 of the OWS Common
Implementation Specification discussion paper (04-016r4).

comment:2 by dmorissette, 20 years ago

I've set target milestone to FUTURE. Was that ok? Did you see a need for this in
4.4?

comment:3 by sdlime, 20 years ago

This is not needed for 4.4 (you can't set a target when creating a bug for some
reason). It came up as a result of a discussion J.F. and I had about WCS
versions. Right now WCS throws an exception for anything other than 1.0.0. Not
exactly up to spec, but since there's only one version out there I left it that
way. I didn't want to loose the idea though, hence the bug...

I would think that once we get all the WxS common stuff we'll have lots of
opportunities for general functions.

Steve

comment:4 by tomkralidis, 19 years ago

Question: Do we need this for both server and client side version negotiations?

Comment: What I've most commonly seen for x.y.z version checking are base
functions for evaluating version x.y.z to a numerical value for numerical
calculations, i.e.:

# perl code :)
# turn a version value into a number for version negotiation
sub GetVersionInteger {
  my $version_string = $_[0]; # i.e. "1.1.1"
  my ($i,$j,$k) = split /\./, $version_string;
  return($i * 10000 + $j * 100 + $k);
}

...so there would be numerical comparisons vs. string comparisons.  Something
like this would be used by a version negotiator.

comment:5 by tomkralidis, 16 years ago

Cc: tomkralidis added

Here's a first pass at this functionality:

int msOWSGetNegotiatedVersion(int requested_version, int supported_versions[], int num_supported_versions) {
  int i;

  /* if version is not set return highest version */
  if (! requested_version)
    return -1;

  /* if the requested version is lower than the lowest version return the lowest version  */
  if (requested_version < supported_versions[num_supported_versions-1])
    return supported_versions[num_supported_versions-1];

  /* return the first entry that's lower than or equal to the requested version */
  for (i = 0; i < num_supported_versions; i++) {
    if (supported_versions[i] <= requested_version) {
      return supported_versions[i];
    }
  }

  return requested_version;
}

..which one would call with something like:

  int version;
  int num_supported_versions = 3;
  int wcsVersions[] = {OWS_1_1_1, OWS_1_1_0, OWS_1_0_0};
  version = msOWSGetNegotiatedVersion(msOWSGetVersionInteger(request->version), wcsVersions, num_supported_versions);

comment:6 by tomkralidis, 16 years ago

P.S. note that the function assumes that the values in the supported_versions array passed are from highest to lowest.

comment:7 by dmorissette, 16 years ago

Description: modified (diff)
Milestone: FUTURE5.2 release

Tom, I guess we also need to deal with the differences between traditional WMS/WFS negociation and the new version negociation mechanism introduced in OWS Common. There was a thread on this a few days ago on the wfs-dev list:

http://mail.opengeospatial.org/pipermail/wfs-dev/2008-January/000479.html

comment:8 by tomkralidis, 16 years ago

Cc: mapserverbugs added

True. See #2475 which would benefit from the "old" style of version negotation for WCS 1.0.0 compliance.

So our logic should be:

  • check for ACCEPT_VERSIONS; it it's there, then handle per OWS Common 1.1.0 D.11
  • check for VERSION; if it's there, then handle as per the logic in this ticket

Note that ACCEPT_VERSIONS support should be implemented in mapowscommon.c and called by the various wXs calling code, when the implementation supports ACCEPT_VERSIONS

Does this make sense?

comment:9 by tomkralidis, 16 years ago

Cc: warmerdam added

cc'ing Frank. Given the barrage of related tickets (#2475, #2482, #2483), I think it's a good time for implementation.

comment:10 by tomkralidis, 16 years ago

r7326 implements the OWS Common style of version negotiation. The calling function must convert the version strings to integers, setup the array, etc. If -1 is returned, then an exception is thrown (i.e. "VersionNegotiationFailed") by the caller.

Now we need to implement the "old style" version negotiation...

comment:11 by tomkralidis, 16 years ago

r7328 implements "old style" version negotiation. Note that the calling function has to set/convert the given inputs to int's, etc. Once we get this working with a calling implementation (i.e. WCS 1.0.0) we can close.

comment:12 by tomkralidis, 16 years ago

Cc: tomkralidis removed
Owner: changed from mapserverbugs to tomkralidis

msOWSNegotiateVersion has been used (r7336) in addressing #2475, #2482, #2483 with success, so the function works as expected, given the right setup by the calling code.

comment:13 by tomkralidis, 16 years ago

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.