func (c *boltConn) ackFailure(failure messages.FailureMessage) error { log.Infof("Acknowledging Failure: %#v", failure) ack := messages.NewAckFailureMessage() err := encoding.NewEncoder(c, c.chunkSize).Encode(ack) if err != nil { return errors.Wrap(err, "An error occurred encoding ack failure message") } for { respInt, err := encoding.NewDecoder(c).Decode() if err != nil { return errors.Wrap(err, "An error occurred decoding ack failure message response") } switch resp := respInt.(type) { case messages.IgnoredMessage: log.Infof("Got ignored message when acking failure: %#v", resp) continue case messages.SuccessMessage: log.Infof("Got success message when acking failure: %#v", resp) return nil case messages.FailureMessage: log.Errorf("Got failure message when acking failure: %#v", resp) return c.reset() default: log.Errorf("Got unrecognized response from acking failure: %#v", resp) err := c.Close() if err != nil { log.Errorf("An error occurred closing the session: %s", err) } return errors.New("Got unrecognized response from acking failure: %#v. CLOSING SESSION!", resp) } } }
func (c *boltConn) initialize() error { // Handle recorder. If there is no conn string, assume we're playing back a recording. // If there is a recorder and a conn string, assume we're recording the connection // Else, just create the conn normally var err error if c.connStr == "" && c.driver != nil && c.driver.recorder != nil { c.conn = c.driver.recorder } else if c.driver != nil && c.driver.recorder != nil { c.driver.recorder.Conn, err = c.createConn() if err != nil { return err } c.conn = c.driver.recorder } else { c.conn, err = c.createConn() if err != nil { return err } } if err := c.handShake(); err != nil { if e := c.Close(); e != nil { log.Errorf("An error occurred closing connection: %s", e) } return err } respInt, err := c.sendInit() if err != nil { if e := c.Close(); e != nil { log.Errorf("An error occurred closing connection: %s", e) } return err } switch resp := respInt.(type) { case messages.SuccessMessage: log.Infof("Successfully initiated Bolt connection: %+v", resp) return nil default: log.Errorf("Got an unrecognized message when initializing connection :%+v", resp) if e := c.Close(); e != nil { log.Errorf("An error occurred closing connection: %s", e) } return errors.New("Unrecognized response from the server: %#v", resp) } }
// Columns returns the columns from the result func (r *boltRows) Columns() []string { fieldsInt, ok := r.metadata["fields"] if !ok { return []string{} } fields, ok := fieldsInt.([]interface{}) if !ok { log.Errorf("Unrecognized fields from success message: %#v", fieldsInt) return []string{} } fieldsStr := make([]string, len(fields)) for i, f := range fields { if fieldsStr[i], ok = f.(string); !ok { log.Errorf("Unrecognized fields from success message: %#v", fieldsInt) return []string{} } } return fieldsStr }
func (c *boltConn) reset() error { log.Info("Resetting session") reset := messages.NewResetMessage() err := encoding.NewEncoder(c, c.chunkSize).Encode(reset) if err != nil { return errors.Wrap(err, "An error occurred encoding reset message") } for { respInt, err := encoding.NewDecoder(c).Decode() if err != nil { return errors.Wrap(err, "An error occurred decoding reset message response") } switch resp := respInt.(type) { case messages.IgnoredMessage: log.Infof("Got ignored message when resetting session: %#v", resp) continue case messages.SuccessMessage: log.Infof("Got success message when resetting session: %#v", resp) return nil case messages.FailureMessage: log.Errorf("Got failure message when resetting session: %#v", resp) err = c.Close() if err != nil { log.Errorf("An error occurred closing the session: %s", err) } return errors.New("Error resetting session: %#v. CLOSING SESSION!", resp) default: log.Errorf("Got unrecognized response from resetting session: %#v", resp) err = c.Close() if err != nil { log.Errorf("An error occurred closing the session: %s", err) } return errors.New("Got unrecognized response from resetting session: %#v. CLOSING SESSION!", resp) } } }
func (c *boltConn) handShake() error { numWritten, err := c.Write(handShake) if numWritten != 20 { log.Errorf("Couldn't write expected bytes for magic preamble + supported versions. Written: %d. Expected: 4", numWritten) if err != nil { err = errors.Wrap(err, "An error occurred writing magic preamble + supported versions") } return err } numRead, err := c.Read(c.serverVersion) if numRead != 4 { log.Errorf("Could not read server version response. Read %d bytes. Expected 4 bytes. Output: %s", numRead, c.serverVersion) if err != nil { err = errors.Wrap(err, "An error occurred reading server version") } return err } else if bytes.Equal(c.serverVersion, noVersionSupported) { return errors.New("Server responded with no supported version") } return nil }
func (c *boltConn) consume() (interface{}, error) { log.Info("Consuming response from bolt stream") respInt, err := encoding.NewDecoder(c).Decode() if err != nil { return respInt, err } if log.GetLevel() >= log.TraceLevel { log.Tracef("Consumed Response: %#v", respInt) } if failure, isFail := respInt.(messages.FailureMessage); isFail { log.Errorf("Got failure message: %#v", failure) err := c.ackFailure(failure) if err != nil { return nil, err } return failure, errors.New("Got failure message: %#v", failure) } return respInt, err }