github.com/datastax/go-cassandra-native-protocol@v0.0.0-20220706104457-5e8aad05cf90/message/startup.go (about)

     1  // Copyright 2020 DataStax
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package message
    16  
    17  import (
    18  	"errors"
    19  	"fmt"
    20  	"io"
    21  
    22  	"github.com/datastax/go-cassandra-native-protocol/primitive"
    23  )
    24  
    25  const (
    26  
    27  	// StartupOptionCqlVersion is the version of CQL to use. This option is mandatory and currently the only version
    28  	// supported is "3.0.0". Note that this is different from the protocol version.
    29  	StartupOptionCqlVersion = "CQL_VERSION"
    30  
    31  	// StartupOptionCompression is the compression algorithm to use.
    32  	StartupOptionCompression = "COMPRESSION"
    33  
    34  	StartupOptionClientId           = "CLIENT_ID"
    35  	StartupOptionApplicationName    = "APPLICATION_NAME"
    36  	StartupOptionApplicationVersion = "APPLICATION_VERSION"
    37  
    38  	// StartupOptionDriverName allows clients to supply a free-form label representing the driver implementation.
    39  	// This is displayed in the output of `nodetool clientstats`.
    40  	StartupOptionDriverName = "DRIVER_NAME"
    41  
    42  	// StartupOptionDriverVersion allows clients to supply a free-form label representing the driver version. This is
    43  	// displayed in the output of `nodetool clientstats`.
    44  	StartupOptionDriverVersion = "DRIVER_VERSION"
    45  
    46  	// StartupOptionThrowOnOverload specifies server behaviour where the incoming message rate is too high.
    47  	// A [string] value of "1" instructs the server to respond with an Error when its resources are exhausted.
    48  	// Any other value, or if the key is not present, and the server will apply backpressure to the connection until it
    49  	// has cleared its backlog of inbound messages.
    50  	StartupOptionThrowOnOverload = "THROW_ON_OVERLOAD"
    51  )
    52  
    53  // Startup is the first request message that a client sends when establishing a connection. The server will respond by
    54  // either a Ready response message (in which case the connection is ready for queries) or with an Authenticate response
    55  // message (in which case credentials will need to be provided using a subsequent AuthResponse request message).
    56  // +k8s:deepcopy-gen=true
    57  // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message
    58  type Startup struct {
    59  	// Currently supported options are:
    60  	// - "CQL_VERSION"
    61  	// - "COMPRESSION"
    62  	// Starting with DSE v2 the following options are also recognized:
    63  	// - "CLIENT_ID": string representation of the client instance. Recommended is a ID unique per runtime instance
    64  	//   (e.g. DataStax Java Driver's CqlSession instance), generated by the driver.
    65  	// - "APPLICATION_NAME": optional, name of the application, should include the vendor name.
    66  	//   For example "DataStax Studio".
    67  	// - "APPLICATION_VERSION": optional, version of the application.
    68  	// - "DRIVER_NAME": product name of the driver implementation. For example: 'DataStax Java Driver'.
    69  	// - "DRIVER_VERSION": version of the driver implementation, typically a semantic version string.
    70  	Options map[string]string
    71  }
    72  
    73  func NewStartup(keysAndValues ...string) *Startup {
    74  	startup := &Startup{map[string]string{StartupOptionCqlVersion: "3.0.0"}}
    75  	for i := 0; i < len(keysAndValues); i += 2 {
    76  		startup.Options[keysAndValues[i]] = keysAndValues[i+1]
    77  	}
    78  	return startup
    79  }
    80  
    81  func (m *Startup) GetCompression() primitive.Compression {
    82  	if compressionStr, found := m.Options[StartupOptionCompression]; !found {
    83  		return primitive.CompressionNone
    84  	} else {
    85  		return primitive.Compression(compressionStr)
    86  	}
    87  }
    88  
    89  func (m *Startup) SetCompression(compression primitive.Compression) {
    90  	if compression == primitive.CompressionNone {
    91  		delete(m.Options, StartupOptionCompression)
    92  	} else {
    93  		m.Options[StartupOptionCompression] = string(compression)
    94  	}
    95  }
    96  
    97  func (m *Startup) GetClientId() string {
    98  	return m.Options[StartupOptionClientId]
    99  }
   100  
   101  func (m *Startup) SetClientId(clientId string) {
   102  	m.Options[StartupOptionClientId] = clientId
   103  }
   104  
   105  func (m *Startup) GetApplicationName() string {
   106  	return m.Options[StartupOptionApplicationName]
   107  }
   108  
   109  func (m *Startup) SetApplicationName(applicationName string) {
   110  	m.Options[StartupOptionApplicationName] = applicationName
   111  }
   112  
   113  func (m *Startup) GetApplicationVersion() string {
   114  	return m.Options[StartupOptionApplicationVersion]
   115  }
   116  
   117  func (m *Startup) SetApplicationVersion(applicationVersion string) {
   118  	m.Options[StartupOptionApplicationVersion] = applicationVersion
   119  }
   120  
   121  func (m *Startup) GetDriverName() string {
   122  	return m.Options[StartupOptionDriverName]
   123  }
   124  
   125  func (m *Startup) SetDriverName(driverName string) {
   126  	m.Options[StartupOptionDriverName] = driverName
   127  }
   128  
   129  func (m *Startup) GetDriverVersion() string {
   130  	return m.Options[StartupOptionDriverVersion]
   131  }
   132  
   133  func (m *Startup) SetDriverVersion(driverVersion string) {
   134  	m.Options[StartupOptionDriverVersion] = driverVersion
   135  }
   136  
   137  func (m *Startup) IsThrowOnOverload() bool {
   138  	v, found := m.Options[StartupOptionThrowOnOverload]
   139  	return found && v == "1"
   140  }
   141  
   142  func (m *Startup) SetThrowOnOverload(throwOnOverload bool) {
   143  	if throwOnOverload {
   144  		m.Options[StartupOptionDriverVersion] = "1"
   145  	} else {
   146  		delete(m.Options, StartupOptionDriverVersion)
   147  	}
   148  }
   149  
   150  func (m *Startup) IsResponse() bool {
   151  	return false
   152  }
   153  
   154  func (m *Startup) GetOpCode() primitive.OpCode {
   155  	return primitive.OpCodeStartup
   156  }
   157  
   158  func (m *Startup) String() string {
   159  	return fmt.Sprint("STARTUP ", m.Options)
   160  }
   161  
   162  type startupCodec struct{}
   163  
   164  func (c *startupCodec) Encode(msg Message, dest io.Writer, _ primitive.ProtocolVersion) error {
   165  	startup, ok := msg.(*Startup)
   166  	if !ok {
   167  		return errors.New(fmt.Sprintf("expected *message.Startup, got %T", msg))
   168  	}
   169  	return primitive.WriteStringMap(startup.Options, dest)
   170  }
   171  
   172  func (c *startupCodec) EncodedLength(msg Message, _ primitive.ProtocolVersion) (int, error) {
   173  	startup, ok := msg.(*Startup)
   174  	if !ok {
   175  		return -1, errors.New(fmt.Sprintf("expected *message.Startup, got %T", msg))
   176  	}
   177  	return primitive.LengthOfStringMap(startup.Options), nil
   178  }
   179  
   180  func (c *startupCodec) Decode(source io.Reader, _ primitive.ProtocolVersion) (Message, error) {
   181  	if options, err := primitive.ReadStringMap(source); err != nil {
   182  		return nil, err
   183  	} else {
   184  		return &Startup{Options: options}, nil
   185  	}
   186  }
   187  
   188  func (c *startupCodec) GetOpCode() primitive.OpCode {
   189  	return primitive.OpCodeStartup
   190  }