Example #1
0
File: cass.go Project: araddon/cass
// opens a cassandra connection
func (conn *CassandraConnection) Open(keyspace string) error {

	Log(DEBUG, "creating new cassandra connection ", conn.pool)
	tcpConn, err := net.Dial("tcp", conn.Server)
	if err != nil {
		return err
	}

	ts, err := thrift.NewTSocketConn(tcpConn)
	if err != nil || ts == nil {
		return fmt.Errorf("Failed opening thrift socket: %s %s", err, ts)
	}

	if ts == nil {
		return errors.New("No TSocket connection?")
	}

	// the TSocket implements interface TTransport
	trans := thrift.NewTFramedTransport(ts)

	// A previous version of this code called trans.Open() at this point, but it's already open

	protocolfac := thrift.NewTBinaryProtocolFactoryDefault()

	conn.Client = cassandra.NewCassandraClientFactory(trans, protocolfac)

	Log(DEBUG, " in conn.Open, how is client? ", conn.Client)

	ire, t3e := conn.Client.SetCqlVersion("3.0.0")
	if ire != nil || t3e != nil {
		Log(ERROR, ire, t3e)
		return fmt.Errorf("Failed in SetCqlVersion: %s %s", ire.Why, t3e)
	}
	return nil
}
Example #2
0
func NewCommandReceiver(conn net.Conn, hostList HostList, poolMan PoolManager) *CommandReceiver {
	sock, _ := thrift.NewTNonblockingSocketConn(conn) // err is always nil, so just ignore it
	trans := thriftutils.NewTFramedTransport(sock)
	protoFac := thrift.NewTBinaryProtocolFactoryDefault()
	prot := protoFac.GetProtocol(trans)

	cmr := &CommandReceiver{}
	cmr.remoteConn = conn
	cmr.hostList = hostList
	cmr.poolMan = poolMan
	cmr.tsocket = sock
	cmr.transport = trans
	cmr.protocol = prot

	return cmr
}
Example #3
0
func Dial(node string, keyspace string, timeout time.Duration) (*CassConnection, error) {
	// resolve the address
	addr, err := net.ResolveTCPAddr("tcp", node)
	if err != nil {
		return nil, err
	}
	// get a socket
	sock, err := thrift.NewTNonblockingSocketAddr(addr)
	if err != nil {
		return nil, err
	}
	sock.SetTimeout(int64(timeout))

	// build the client
	transport := thriftutils.NewTFramedTransport(sock)
	protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
	cli := cassandra.NewCassandraClientFactory(transport, protocolFactory)

	// connect, with a timeout of `timeout`
	ch := make(chan bool, 1)
	go func() {
		err = transport.Open()
		ch <- true
	}()
	timedOut := false
	select {
	case <-time.After(timeout):
		timedOut = true
	case <-ch:
	}
	if timedOut {
		return nil, ErrorConnectionTimeout
	}
	// get the version and check for min version and what not
	ver, err := cli.DescribeVersion()
	if err != nil {
		transport.Close()
		return nil, err
	}
	log.Print("Opened new connection, protocol version: ", ver)
	return &CassConnection{sock, transport, cli, node, keyspace, protocolFactory}, nil
}
Example #4
0
// opens a cassandra connection
func (conn *CassandraConnection) Open(keyspace string) error {

	Log(DEBUG, "creating new cassandra connection ", conn.pool)
	tcpConn, er := net.Dial("tcp", conn.Server)
	if er != nil {
		return er
	}
	ts, err := thrift.NewTSocketConn(tcpConn)
	if err != nil {
		return err
	}

	if ts == nil {
		return errors.New("No TSocket connection?")
	}

	// the TSocket implements interface TTransport
	trans := thrift.NewTFramedTransport(ts)
	trans.Open()

	protocolfac := thrift.NewTBinaryProtocolFactoryDefault()

	conn.Client = cassandra.NewCassandraClientFactory(trans, protocolfac)

	Log(DEBUG, " in conn.Open, how is client? ", conn.Client)

	ire, er := conn.Client.SetKeyspace(keyspace)
	if ire != nil || er != nil {
		// most likely this is because it hasn't been created yet, so we will
		// ignore for now, as SetKeyspace() is purely optional
		Log(ERROR, ire, er)
	}
	e, t3e := conn.Client.SetCqlVersion("3.0.0")
	if e != nil || t3e != nil {
		Log(ERROR, e, t3e)
	}
	return nil
}
Example #5
0
func newConnection(node, keyspace string, timeout int, authentication map[string]string) (*connection, error) {

	addr, err := net.ResolveTCPAddr("tcp", node)
	if err != nil {
		return nil, err
	}

	c := &connection{node: node}

	c.socket, err = thrift.NewTNonblockingSocketAddr(addr)
	if err != nil {
		return nil, err
	}

	// socket not open yet, so no error expected. it expects nanos, we have milis, so it's 1e6
	c.socket.SetTimeout(int64(timeout) * 1e6)

	c.transport = thrift.NewTFramedTransport(c.socket)
	protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
	c.client = cassandra.NewCassandraClientFactory(c.transport, protocolFactory)

	// simulate timeout support for the underlying Dial() in .Open(). needless to say this sucks
	// restore sanity to this for Go v1 with the new DialTimeout() func
	ch := make(chan bool, 1)
	go func() {
		err = c.transport.Open()
		ch <- true
	}()
	timedOut := false
	select {
	case <-time.After(time.Duration(timeout) * time.Millisecond):
		timedOut = true
	case <-ch:
	}
	if timedOut {
		return nil, ErrorConnectionTimeout
	}
	if err != nil {
		return nil, err
	}

	version, err := c.client.DescribeVersion()
	if err != nil {
		c.close()
		return nil, err
	}
	versionComponents := strings.Split(version, ".")
	if len(versionComponents) < 1 {
		return nil, ErrorInvalidThriftVersion
	}
	majorVersion, err := strconv.Atoi(versionComponents[0])
	if err != nil {
		return nil, ErrorInvalidThriftVersion
	}
	if majorVersion < LOWEST_COMPATIBLE_VERSION {
		return nil, ErrorWrongThriftVersion
	}

	if len(authentication) > 0 {
		ar := cassandra.NewAuthenticationRequest()
		ar.Credentials = thrift.NewTMap(thrift.STRING, thrift.STRING, 1)
		for k, v := range authentication {
			ar.Credentials.Set(k, v)
		}
		autE, auzE, err := c.client.Login(ar)
		if autE != nil {
			return nil, ErrorAuthenticationFailed
		}
		if auzE != nil {
			return nil, ErrorAuthorizationFailed
		}
		if err != nil {
			return nil, err
		}
	}

	ire, err := c.client.SetKeyspace(keyspace)
	if err != nil {
		c.close()
		return nil, err
	}
	if ire != nil {
		c.close()
		return nil, ErrorSetKeyspace
	}

	c.keyspace = keyspace

	return c, nil
}
Example #6
0
func NewCassandraCommand(name string, typeId thrift.TMessageType, seqId int32) *CassandraCommand {
	protoFac := thrift.NewTBinaryProtocolFactoryDefault()
	exc := &CassandraCommand{name, typeId, seqId, protoFac, false, nil, nil}
	return exc
}
Example #7
0
func newConnection(node, keyspace string, timeout int) (*connection, error) {

	addr, err := net.ResolveTCPAddr("tcp", node)
	if err != nil {
		return nil, err
	}

	c := &connection{node: node}

	c.socket, err = thrift.NewTNonblockingSocketAddr(addr)
	if err != nil {
		return nil, err
	}

	// socket not open yet, so no error expected. it expects nanos, we have milis, so it's 1e6
	c.socket.SetTimeout(int64(timeout) * 1e6)

	c.transport = thrift.NewTFramedTransport(c.socket)
	protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
	c.client = cassandra.NewCassandraClientFactory(c.transport, protocolFactory)

	// simulate timeout support for the underlying Dial() in .Open(). needless to say this sucks
	// restore sanity to this for Go v1 with the new DialTimeout() func
	ch := make(chan bool, 1)
	go func() {
		err = c.transport.Open()
		ch <- true
	}()
	timedOut := false
	select {
	case <-time.After(time.Duration(timeout) * time.Millisecond):
		timedOut = true
	case <-ch:
	}
	if timedOut {
		return nil, ErrorConnectionTimeout
	}
	if err != nil {
		return nil, err
	}

	version, err := c.client.DescribeVersion()
	if err != nil {
		c.close()
		return nil, err
	}
	versionComponents := strings.Split(version, ".")
	if len(versionComponents) < 1 {
		return nil, errors.New(fmt.Sprint("Cannot parse the Thrift API version number: ", version))
	}
	majorVersion, err := strconv.Atoi(versionComponents[0])
	if err != nil {
		return nil, errors.New(fmt.Sprint("Cannot parse the Thrift API version number: ", version))
	}
	if majorVersion < LOWEST_COMPATIBLE_VERSION {
		return nil, errors.New(fmt.Sprint("Unsupported Thrift API version, lowest supported is ", LOWEST_COMPATIBLE_VERSION,
			", server reports ", majorVersion))
	}

	ire, err := c.client.SetKeyspace(keyspace)
	if err != nil {
		c.close()
		return nil, err
	}
	if ire != nil {
		c.close()
		return nil, errors.New("Cannot set the keyspace")
	}

	c.keyspace = keyspace

	return c, nil
}