// 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 }
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 }
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 }
// 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 }
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 }
func NewCassandraCommand(name string, typeId thrift.TMessageType, seqId int32) *CassandraCommand { protoFac := thrift.NewTBinaryProtocolFactoryDefault() exc := &CassandraCommand{name, typeId, seqId, protoFac, false, nil, nil} return exc }
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 }