'Lo.

I'm working on a system that defines a versioned networking protocol.

The protocol version consists of a major and minor version. When a
client connects to the server, it negotiates a protocol version with
the server. In practice, this means that when a client connects:

1. The server immediately announces what protocol versions are
   supported. Essentially it returns a list of (major, minor) pairs.

2. The client picks one and tells the server. Current clients
   simply pick whichever server version is highest.

3. The server responds with an agreement or a failure message.

The semantics of the version numbers are such that major numbers
indicate backwards-incompatible changes. The main consequence of this
is that if a server (internally) only provides support for version 1.3
but a client asks for 1.1, the server can simply use the 1.3 protocol
handling code to provide support for 1.1.

I'm wondering what the best way to handle this is in an OSGi context.

Clearly, at the very least, I would publish one protocol handler
service per supported protocol major version. That way, when a client
connects, the server can get a list of all protocol handling services
in order to determine what versions are currently supported. I believe
I need to use service properties to do this, but I'm struggling
to find a way to do it that's actually pleasant.

It seems as though a given protocol handler service could define a
property that states which versions are supported. Something like:

@Component(
  property = {
    "message_protocol=1.0",
    "message_protocol=1.1",
    "message_protocol=1.2",
    "message_protocol=1.3"
  })
public final class HandlerV1 { ... }

@Component(
  property = {
    "message_protocol=2.0",
    "message_protocol=2.1"
  })
public final class HandlerV2 { ... }

The problem here is in the querying of services... How do I ask OSGi
for a list of *all* supported protocol versions? I have code something
like the following (assuming a filter that selects services of type
HandlerFactoryType that have a "message_protocol" property defined):

    final ServiceReference<HandlerFactoryType>[] services =
      this.tracker.getServiceReferences();
    if (services != null) {
      for (int index = 0; index < services.length; ++index) {
        final ServiceReference<HandlerFactoryType> ref = services[index];
        Object versions = ref.getProperty("message_protocol");
        // XXX: Parse versions here?
      }
    }

The problem is that the returned property obviously can't be handled
in a type-safe way and it seems like I'd have to assume that it's a
String value and then manually parse version numbers. This is unpleasant!

Additionally... How do I ask OSGi for a list of services that can 
support _at least_ a given version? If a client wants version 2.3
but all I have installed is a 2.6 handler, using the above I'd first
need to ask for "(message_protocol=2.*)" and then manually parse version
numbers and filter out services that don't support a high enough (2.3)
version. Of course, this is also a classic race condition; the service 
might be gone by the time I've decided that it's the one I want.

Is there a better way to do this?

M

Attachment: pgpWyw8pkyN7F.pgp
Description: OpenPGP digital signature

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to