Commit baf94dd0 authored by Ignacio Corderi's avatar Ignacio Corderi
Browse files

Added unsolicited status support

parent bb0ca4dc
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ This section will document changes to the library since the last release
- Client auto configures cluster_version based on initial handshake
- ErasePin and LockPin can be set during the security operation
- Client fields config and limits show device information
- Added unsolicited status support

## Behavior changes
- Removed GreenClient (Feature overlap with AsyncClient)
+3 −3
Original line number Diff line number Diff line
@@ -38,9 +38,9 @@ class AdminClient(baseclient.BaseClient):
                # update header
                self.update_header(header)
                # send message synchronously
                r, v = self.send(header, value)
            operations._check_status(r)
            return op.parse(r,v)
                _, cmd, v = self.send(header, value)
            operations._check_status(cmd)
            return op.parse(cmd,v)
        except Exception as e:
            return op.onError(e)

+19 −9
Original line number Diff line number Diff line
@@ -80,8 +80,18 @@ class BaseAsync(Client):
            raise common.ConnectionFaulted("Connection {0} is faulted. Can't receive message when connection is on a faulted state.".format(self))

        try:
            resp,value = self.network_recv()
            m, resp,value = self.network_recv()
            if m.authType == messages.Message.UNSOLICITED_STATUS:
                if self.on_unsolicited:
                    try:
                        self.dispatch(self.on_unsolicited,resp.status)
                    except Exception as e:
                        self._raise(e)
                else:
                    LOG.warn('Unsolicited status %s received but nobody listening.' % resp.status.code)
            else:
                seq = resp.header.ackSequence
                if LOG.isEnabledFor(logging.DEBUG):
                    LOG.debug("Received message with ackSequence={0} on connection {1}.".format(seq,self))
                onSuccess,_ = self._pending[seq]
                del self._pending[seq]
+25 −16
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ class BaseClient(object):
        self.wait_on_read = None
        self.use_ssl = use_ssl
        self.pin = pin
        self.on_unsolicited = None

    @property
    def socket(self):
@@ -136,29 +137,29 @@ class BaseClient(object):
    def _handshake(self):
        # Connection id handshake
        try:
            h,v = self.network_recv()
            _,cmd,v = self.network_recv() # unsolicited status
        except socket.timeout:
            raise common.KineticClientException("Handshake timeout")

        # device locked only allowed to continue over SSL
        if (h.status.code == messages.Command.Status.DEVICE_LOCKED):
        if (cmd.status.code == messages.Command.Status.DEVICE_LOCKED):
            if not self.use_ssl:
                raise KineticMessageException(h.status)
        elif (h.status.code != messages.Command.Status.SUCCESS):
            raise KineticMessageException(h.status)
                raise KineticMessageException(cmd.status)
        elif (cmd.status.code != messages.Command.Status.SUCCESS):
            raise KineticMessageException(cmd.status)

        self.config = h.body.getLog.configuration
        self.limits = h.body.getLog.limits
        self.config = cmd.body.getLog.configuration
        self.limits = cmd.body.getLog.limits

        if self.cluster_version:
            if self.cluster_version != h.header.clusterVersion:
                h.status.code = messages.Command.Status.VERSION_FAILURE
                h.status.statusMessage = \
            if self.cluster_version != cmd.header.clusterVersion:
                cmd.status.code = messages.Command.Status.VERSION_FAILURE
                cmd.status.statusMessage = \
                    'Cluster version missmatch detected during handshake'
                raise common.ClusterVersionFailureException(
                    h.status, h.header.clusterVersion)
                    cmd.status, cmd.header.clusterVersion)
        else:
            self.cluster_version = h.header.clusterVersion
            self.cluster_version = cmd.header.clusterVersion

    def has_data_available(self):
        tmp = self._socket.recv(1, socket.MSG_PEEK)
@@ -343,12 +344,20 @@ class BaseClient(object):
        if resp.header.connectionID:
            self.connection_id = resp.header.connectionID

        return (resp, value)
        return (m, resp, value)

    def send(self, header, value):
        self.network_send(header, value)
       resp = self.network_recv()
       return resp
        done = False
        while not done:
            m,cmd,value = self.network_recv()
            if m.authType == messages.Message.UNSOLICITED_STATUS:
                if self.on_unsolicited:
                    self.on_unsolicited(resp.status) # uncatched exceptions by the handler will be raised to the caller
                else:
                    LOG.warn('Unsolicited status %s received but nobody listening.' % cmd.status.code)

       return m,cmd,value

    ### with statement support ###

+3 −3
Original line number Diff line number Diff line
@@ -35,9 +35,9 @@ class Client(BaseClient):
                # update header
                self.update_header(header)
                # send message synchronously
                header, value = self.send(header, value)
            operations._check_status(header)
            return op.parse(header, value)
                _, cmd, value = self.send(header, value)
            operations._check_status(cmd)
            return op.parse(cmd, value)
        except Exception as e:
            return op.onError(e)