Example #1
0
/*
 * Write the exception to the protocol.
 *
 * Does not assume the protocol's transport is ready for writing (you must prepare this yourself.)
 * Begins writing, writes the exception, and flushes the protocol's transport.
 */
func TWriteException(name string, seqId int32, prot thrift.TProtocol, exc thrift.TException) {
	// see whihch of the known thrift exception types it was
	_, isProtExc := exc.(thrift.TProtocolException)
	appExc, isAppExc := exc.(thrift.TApplicationException)
	_, isTransExc := exc.(thrift.TTransportException)

	// write the exception header
	prot.WriteMessageBegin(name, thrift.EXCEPTION, seqId)

	// convert it into an application exception if not already
	if !isAppExc {
		if isProtExc {
			appExc = thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, exc.Error())
		} else if isTransExc {
			appExc = thrift.NewTApplicationException(thrift.INTERNAL_ERROR, exc.Error())
		} else {
			appExc = thrift.NewTApplicationExceptionMessage(exc.Error())
		}
	}

	appExc.Write(prot)

	// finish it
	prot.WriteMessageEnd()
	prot.Transport().Flush()
}
Example #2
0
func (r *CommandReceiver) Handshake() (*ConnectionDef, Command, error) {
	// start reading immediatly; get the header
	name, typeId, seqId, err := r.protocol.ReadMessageBegin()
	if err != nil {
		log.Print("CommandReceiver:Handshake could not read from client ", err)
		r.protocol.Skip(thrift.STRUCT)
		r.protocol.ReadMessageEnd()
		TWriteException(name, seqId, r.protocol, err)
		return nil, nil, err
	}

	var lastHandhakeStep string // set if handshaking, used to generate useful logging output
	connDef := NewEmptyConnectionDef()

	// if we are handshaking, that is name is either `set_keyspace` or `login` then
	for name == "set_keyspace" || name == "login" {
		lastHandhakeStep = name
		// set up the passthrough processor
		pt := NewLoginAndKeyspaceHijackingHandler()
		proc := cassandra.NewCassandraProcessor(pt)

		// get a processor for the name
		processor, nameFound := proc.GetProcessorFunction(name)

		if !nameFound || processor == nil {
			// have no idea what you are tryn'a do son (shouldn't ever get here as we provide the processor)
			exc := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name)
			r.protocol.Skip(thrift.STRUCT)
			r.protocol.ReadMessageEnd()
			TWriteException(name, seqId, r.protocol, exc)
			return nil, nil, nil // nil err = did not have a connection error
		}

		// run it
		_, exc := processor.Process(seqId, r.protocol, r.protocol)
		if exc != nil {
			log.Print("CommandReceiver:Receiver failed to execute function '", name, "': ", exc)
			TWriteException(name, seqId, r.protocol, exc)
			return nil, nil, nil // nil err = did not have a connection error
		}

		if pt.HasLogin() {
			connDef.SetLoginReq(NewLoginReq(pt.Username(), pt.Password()))
		}
		if pt.HasKeyspace() {
			connDef.SetKeyspace(pt.Keyspace())
		}

		name, typeId, seqId, err = r.protocol.ReadMessageBegin() // start reading the next message to get the command

		if err != nil {
			log.Print("CommandReceiver:Handshake could not read message header from client after handshake step '", lastHandhakeStep, "' ", err)
			r.protocol.Skip(thrift.STRUCT)
			r.protocol.ReadMessageEnd()
			TWriteException(name, seqId, r.protocol, err)
			return nil, nil, err // bail out totally
		}
	}

	// we are not handshaking, just executing commands
	return connDef, NewCassandraCommand(name, typeId, seqId), nil
}