示例#1
0
    def __init__(self,
                 writer,
                 datum_writer,
                 writers_schema=None,
                 codec='null'):
        """
        If the schema is not present, presume we're appending.

        @param writer: File-like object to write into.
        """
        self._writer = writer
        self._encoder = io.BinaryEncoder(writer)
        self._datum_writer = datum_writer
        self._buffer_writer = StringIO()
        self._buffer_encoder = io.BinaryEncoder(self._buffer_writer)
        self._block_count = 0
        self._meta = {}
        self._header_written = False

        if writers_schema is not None:
            if codec not in VALID_CODECS:
                raise DataFileException("Unknown codec: %r" % codec)
            self._sync_marker = DataFileWriter.generate_sync_marker()
            self.set_meta('avro.codec', codec)
            self.set_meta('avro.schema', str(writers_schema))
            self.datum_writer.writers_schema = writers_schema
        else:
            if writer.mode:
                if writer.mode not in ('rb+', 'ab+'):
                    raise DataFileException(
                        "When appending records to an Avro data file, the file object passed into DataFileWriter must be opened in read/write mode, e.g. for files: \"rb+\" or \"ab+\""
                    )
            else:
                if not (writer.readable() and writer.writable()):
                    raise DataFileException(
                        "When appending records to an Avro data file, the file object passed into DataFileWriter must be opened in read/write mode, e.g. for files: \"rb+\" or \"ab+\""
                    )
            # open writer for reading to collect metadata
            dfr = DataFileReader(writer, io.DatumReader())

            # TODO(hammer): collect arbitrary metadata
            # collect metadata
            self._sync_marker = dfr.sync_marker
            self.set_meta('avro.codec', dfr.get_meta('avro.codec'))

            # get schema used to write existing file
            schema_from_file = dfr.get_meta('avro.schema')
            self.set_meta('avro.schema', schema_from_file)
            self.datum_writer.writers_schema = schema.parse(schema_from_file)

            # seek to the end of the file and prepare for writing
            writer.seek(0, 2)
            self._header_written = True
示例#2
0
    def request(self, message_name, request_datum):
        """
    Writes a request message and reads a response or error message.
    """
        # build handshake and call request
        buffer_writer = StringIO()
        buffer_encoder = io.BinaryEncoder(buffer_writer)
        self.write_handshake_request(buffer_encoder)
        self.write_call_request(message_name, request_datum, buffer_encoder)

        # send the handshake and call request; block until call response
        call_request = buffer_writer.getvalue()
        return self.issue_request(call_request, message_name, request_datum)
示例#3
0
    def __init__(self, scheme=None, outputClient=None):
        """

    Parameters
    ---------------------------------------------
    scheme - The scheme for the datums to output - can be a json string
           - or an instance of Schema
    outputClient - The output client used to send messages to the parent
    """

        if not (isinstance(scheme, schema.Schema)):
            scheme = schema.parse(scheme)

        if (outputClient is None):
            raise ValueError("output client can't be none.")

        self.scheme = scheme
        self.buff = StringIO()
        self.encoder = avio.BinaryEncoder(self.buff)

        self.datum_writer = avio.DatumWriter(writers_schema=self.scheme)
        self.outputClient = outputClient
示例#4
0
def write_datum(datum, writers_schema):
    writer = StringIO()
    encoder = io.BinaryEncoder(writer)
    datum_writer = io.DatumWriter(writers_schema)
    datum_writer.write(datum, encoder)
    return writer, encoder, datum_writer
示例#5
0
    def respond(self, call_request):
        """
    Called by a server to deserialize a request, compute and serialize
    a response or error. Compare to 'handle()' in Thrift.
    """
        buffer_reader = StringIO(call_request)
        buffer_decoder = io.BinaryDecoder(buffer_reader)
        buffer_writer = StringIO()
        buffer_encoder = io.BinaryEncoder(buffer_writer)
        error = None
        response_metadata = {}

        try:
            remote_protocol = self.process_handshake(buffer_decoder,
                                                     buffer_encoder)
            # handshake failure
            if remote_protocol is None:
                return buffer_writer.getvalue()

            # read request using remote protocol
            request_metadata = META_READER.read(buffer_decoder)
            remote_message_name = buffer_decoder.read_utf8()

            # get remote and local request schemas so we can do
            # schema resolution (one fine day)
            remote_message = remote_protocol.messages.get(remote_message_name)
            if remote_message is None:
                fail_msg = 'Unknown remote message: %s' % remote_message_name
                raise schema.AvroException(fail_msg)
            local_message = self.local_protocol.messages.get(
                remote_message_name)
            if local_message is None:
                fail_msg = 'Unknown local message: %s' % remote_message_name
                raise schema.AvroException(fail_msg)
            writers_schema = remote_message.request
            readers_schema = local_message.request
            request = self.read_request(writers_schema, readers_schema,
                                        buffer_decoder)

            # perform server logic
            try:
                response = self.invoke(local_message, request)
            except AvroRemoteException as e:
                error = e
            except Exception as e:
                error = AvroRemoteException(str(e))

            # write response using local protocol
            META_WRITER.write(response_metadata, buffer_encoder)
            buffer_encoder.write_boolean(error is not None)
            if error is None:
                writers_schema = local_message.response
                self.write_response(writers_schema, response, buffer_encoder)
            else:
                writers_schema = local_message.errors
                self.write_error(writers_schema, error, buffer_encoder)
        except schema.AvroException as e:
            error = AvroRemoteException(str(e))
            buffer_encoder = io.BinaryEncoder(StringIO())
            META_WRITER.write(response_metadata, buffer_encoder)
            buffer_encoder.write_boolean(True)
            self.write_error(SYSTEM_ERROR_SCHEMA, error, buffer_encoder)
        return buffer_writer.getvalue()