Beispiel #1
0
    def execute(self, script, params={}, isolate=True, transaction=True, pretty=False):
        """
        executes the given gremlin script with the provided parameters

        :param script: the gremlin script to isolate
        :type script: string
        :param params: the parameters to execute the script with
        :type params: dictionary
        :param isolate: wraps the script in a closure so any variables set aren't persisted for the next execute call
        :type isolate: bool
        :param transaction: query will be wrapped in a transaction if set to True (default)
        :type transaction: bool
        :param pretty: will dedent the script if set to True
        :type pretty: bool

        :rtype: list
        """
        self._conn.send_message(
            messages.ScriptRequest(
                script=script,
                params=params,
                session_key=self._session_key,
                isolate=isolate,
                in_transaction=transaction
            )
        )
        response = self._conn.get_response()

        if isinstance(response, messages.ErrorResponse):
            raise exceptions.RexProScriptException(response.message)

        return response.results
Beispiel #2
0
 def open_transaction(self):
     """ opens a transaction """
     if self._in_transaction:
         raise exceptions.RexProScriptException("transaction is already open")
     self.execute(
         script='g.stopTransaction(FAILURE)',
         isolate=False
     )
     self._in_transaction = True
Beispiel #3
0
    def _validate_params(self):
        """
        Checks that the parameters are ok
        (no invalid types, no weird key names)
        """
        for k, v in self.params.items():

            if re.findall(r'^[0-9]', k):
                raise exceptions.RexProScriptException(
                    "parameter names can't begin with a number")
            if re.findall(r'[\s\.]', k):
                raise exceptions.RexProException(
                    "parameter names can't contain {}".format(
                        re.findall(r'^[0-9]', k)[0]))

            if not isinstance(
                    v, (int, long, float, basestring, dict, list, tuple)):
                raise exceptions.RexProScriptException(
                    "{} is an unsupported type".format(type(v)))
Beispiel #4
0
 def raise_exception(self):
     if self.meta == self.INVALID_MESSAGE_ERROR:
         raise exceptions.RexProInvalidMessageException(self.message)
     elif self.meta == self.INVALID_SESSION_ERROR:
         raise exceptions.RexProInvalidSessionException(self.message)
     elif self.meta == self.SCRIPT_FAILURE_ERROR:
         raise exceptions.RexProScriptException(self.message)
     elif self.meta == self.AUTH_FAILURE_ERROR:
         raise exceptions.RexProAuthenticationFailure(self.message)
     elif self.meta == self.GRAPH_CONFIG_ERROR:
         raise exceptions.RexProGraphConfigException(self.message)
     elif self.meta == self.CHANNEL_CONFIG_ERROR:
         raise exceptions.RexProChannelConfigException(self.message)
     elif self.meta == self.RESULT_SERIALIZATION_ERROR:
         raise exceptions.RexProSerializationException(
             "Meta: {} ({}), Message: {}, Raw Data: {}".format(
                 self.meta, type(self.meta), self.message, repr(self.data)))
     else:
         raise exceptions.RexProScriptException(
             "Meta: {} ({}), Message: {}, Raw Data: {}".format(
                 self.meta, type(self.meta), self.message, repr(self.data)))
Beispiel #5
0
    def close_transaction(self, success=True):
        """
        closes an open transaction

        :param success: indicates which status to close the transaction with, True will commit the changes, False will roll them back
        :type success: bool
        """
        if not self._in_transaction:
            raise exceptions.RexProScriptException("transaction is not open")
        self.execute(
            script='g.stopTransaction({})'.format('SUCCESS' if success else 'FAILURE'),
            isolate=False
        )
        self._in_transaction = False
Beispiel #6
0
    def get_response(self):
        """
        gets the message type and message from rexster


        Basic Message Structure:  reference: https://github.com/tinkerpop/rexster/wiki/RexPro-Messages

        +---------------------+--------------+---------------------------------------------------------+
        | segment             | type (bytes) | description                                             |
        +=====================+==============+=========================================================+
        | protocol version    | byte (1)     | Version of RexPro, should be 1                          |
        +---------------------+--------------+---------------------------------------------------------+
        | serializer type     | byte (1)     | Type of Serializer: msgpack==0, json==1                 |
        +---------------------+--------------+---------------------------------------------------------+
        | reserved for future | byte (4)     | Reserved for future use.                                |
        +---------------------+--------------+---------------------------------------------------------+
        | message type        | byte (1)     | Tye type of message as described in the value columns.  |
        +---------------------+--------------+---------------------------------------------------------+
        | message size        | int (4)      | The length of the message body                          |
        +---------------------+--------------+---------------------------------------------------------+
        | message body        | byte (n)     | The body of the message itself. The Good, Bad and Ugly. |
        +---------------------+--------------+---------------------------------------------------------+



        Message Types:

        +--------------+----------+-------+---------------------------------------------------------------+
        | message type | type     | value | description                                                   |
        +==============+==========+=======+===============================================================+
        | session      | request  | 1     | A request to open or close the session with the RexPro Server |
        +--------------+----------+-------+---------------------------------------------------------------+
        | session      | response | 2     | RexPro server response to session request                     |
        +--------------+----------+-------+---------------------------------------------------------------+
        | script       | request  | 3     | A request to process a gremlin script                         |
        +--------------+----------+-------+---------------------------------------------------------------+
        | script       | response | 5     | A response to a script request                                |
        +--------------+----------+-------+---------------------------------------------------------------+
        | error        | response | 0     | A RexPro server error response                                |
        +--------------+----------+-------+---------------------------------------------------------------+

        :returns: RexProMessage
        """
        msg_version = self.recv(1)
        if not msg_version:  # pragma: no cover
            # Can only be tested against a known broken version - none known yet.
            raise exceptions.RexProConnectionException(
                'socket connection has been closed')
        if bytearray(msg_version)[0] != 1:  # pragma: no cover
            # Can only be tested against a known broken version - none known yet.
            raise exceptions.RexProConnectionException(
                'unsupported protocol version: {}'.format(msg_version))

        serializer_type = self.recv(1)
        if bytearray(serializer_type)[0] != 0:  # pragma: no cover
            # Can only be tested against a known broken version - none known yet.
            raise exceptions.RexProConnectionException(
                'unsupported serializer version: {}'.format(serializer_type))

        # get padding
        self.recv(4)

        msg_type = self.recv(1)
        msg_type = bytearray(msg_type)[0]

        msg_len = struct.unpack('!I', self.recv(4))[0]

        if msg_len == 0:  # pragma: no cover
            # This shouldn't happen unless there is a server-side problem
            raise exceptions.RexProScriptException(
                "Insufficient data received")

        #response = ''
        #while len(response) < msg_len:
        #    response += self.recv(msg_len)
        response = bytearray()
        while msg_len > 0:
            chunk = self.recv(msg_len)
            response.extend(chunk)
            msg_len -= len(chunk)

        MessageTypes = messages.MessageTypes

        type_map = {
            MessageTypes.ERROR: messages.ErrorResponse,
            MessageTypes.SESSION_RESPONSE: messages.SessionResponse,
            MessageTypes.SCRIPT_RESPONSE: messages.MsgPackScriptResponse
        }

        if msg_type not in type_map:  # pragma: no cover
            # this shouldn't happen unless there is an unknown rexpro version change
            raise exceptions.RexProConnectionException(
                "can't deserialize message type {}".format(msg_type))
        return type_map[int(msg_type)].deserialize(response)