github.com/altipla-consulting/ravendb-go-client@v0.1.3/tcp_connection_header_message.go (about)

     1  package ravendb
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  )
     7  
     8  type operationTypes = string
     9  
    10  const (
    11  	operationNone           = "None"
    12  	operationDrop           = "Drop"
    13  	operationSubscription   = "Subscription"
    14  	operationReplication    = "Replication"
    15  	operationCluster        = "Cluster"
    16  	operationHeartbeats     = "Heartbeats"
    17  	operationPing           = "Ping"
    18  	operationTestConnection = "TestConnection"
    19  )
    20  
    21  const (
    22  	numberOfRetriesForSendingTCPHeader = 2
    23  	pingBaseLine                       = -1
    24  	noneBaseLine                       = -1
    25  	dropBaseLine                       = -2
    26  	hearthbeatsBaseLine                = 20
    27  	subscriptionBaseLine               = 40
    28  	testConnectionBaseLine             = 50
    29  
    30  	heartbeatsTCPVersion     = hearthbeatsBaseLine
    31  	subscriptionTCPVersion   = subscriptionBaseLine
    32  	testConnectionTCPVersion = testConnectionBaseLine
    33  )
    34  
    35  type tcpConnectionHeaderMessage struct {
    36  	DatabaseName     string         `json:"DatabaseName"`
    37  	SourceNodeTag    string         `json:"SourceNodeTag"`
    38  	Operation        operationTypes `json:"Operation"`
    39  	OperationVersion int            `json:"OperationVersion"`
    40  	Info             string         `json:"Info"`
    41  }
    42  
    43  type pingFeatures struct {
    44  	baseLine bool
    45  }
    46  
    47  func newPingFeatures() *pingFeatures {
    48  	return &pingFeatures{
    49  		baseLine: true,
    50  	}
    51  }
    52  
    53  type noneFeatures struct {
    54  	baseLine bool
    55  }
    56  
    57  func newNoneFeatures() *noneFeatures {
    58  	return &noneFeatures{
    59  		baseLine: true,
    60  	}
    61  }
    62  
    63  type dropFeatures struct {
    64  	baseLine bool
    65  }
    66  
    67  func newDropFeatures() *dropFeatures {
    68  	return &dropFeatures{
    69  		baseLine: true,
    70  	}
    71  }
    72  
    73  type subscriptionFeatures struct {
    74  	baseLine bool
    75  }
    76  
    77  func newSubscriptionFeatures() *subscriptionFeatures {
    78  	return &subscriptionFeatures{
    79  		baseLine: true,
    80  	}
    81  }
    82  
    83  type heartbeatsFeatures struct {
    84  	baseLine bool
    85  }
    86  
    87  func newHeartbeatsFeatures() *heartbeatsFeatures {
    88  	return &heartbeatsFeatures{
    89  		baseLine: true,
    90  	}
    91  }
    92  
    93  type testConnectionFeatures struct {
    94  	baseLine bool
    95  }
    96  
    97  func newTestConnectionFeatures() *testConnectionFeatures {
    98  	return &testConnectionFeatures{
    99  		baseLine: true,
   100  	}
   101  }
   102  
   103  type replicationFeatures struct {
   104  	baseLine           bool
   105  	missingAttachments bool
   106  }
   107  
   108  func newReplicationFeatures() *replicationFeatures {
   109  	return &replicationFeatures{
   110  		baseLine: true,
   111  	}
   112  }
   113  
   114  type supportedFeatures struct {
   115  	protocolVersion int
   116  
   117  	ping           *pingFeatures
   118  	none           *noneFeatures
   119  	drop           *dropFeatures
   120  	subscription   *subscriptionFeatures
   121  	heartbeats     *heartbeatsFeatures
   122  	testConnection *testConnectionFeatures
   123  }
   124  
   125  func newSupportedFeatures(version int) *supportedFeatures {
   126  	return &supportedFeatures{
   127  		protocolVersion: version,
   128  	}
   129  }
   130  
   131  var (
   132  	operationsToSupportedProtocolVersions = map[operationTypes][]int{}
   133  	supportedFeaturesByProtocol           = map[operationTypes]map[int]*supportedFeatures{}
   134  )
   135  
   136  func init() {
   137  	operationsToSupportedProtocolVersions[operationPing] = []int{pingBaseLine}
   138  	operationsToSupportedProtocolVersions[operationNone] = []int{noneBaseLine}
   139  	operationsToSupportedProtocolVersions[operationDrop] = []int{dropBaseLine}
   140  	operationsToSupportedProtocolVersions[operationSubscription] = []int{subscriptionBaseLine}
   141  	operationsToSupportedProtocolVersions[operationHeartbeats] = []int{hearthbeatsBaseLine}
   142  	operationsToSupportedProtocolVersions[operationTestConnection] = []int{testConnectionBaseLine}
   143  
   144  	pingFeaturesMap := map[int]*supportedFeatures{}
   145  	supportedFeaturesByProtocol[operationPing] = pingFeaturesMap
   146  	pingFeatures := newSupportedFeatures(pingBaseLine)
   147  	pingFeatures.ping = newPingFeatures()
   148  	pingFeaturesMap[pingBaseLine] = pingFeatures
   149  
   150  	noneFeaturesMap := map[int]*supportedFeatures{}
   151  	supportedFeaturesByProtocol[operationNone] = noneFeaturesMap
   152  	noneFeatures := newSupportedFeatures(noneBaseLine)
   153  	noneFeatures.none = newNoneFeatures()
   154  	noneFeaturesMap[noneBaseLine] = noneFeatures
   155  
   156  	dropFeaturesMap := map[int]*supportedFeatures{}
   157  	supportedFeaturesByProtocol[operationDrop] = dropFeaturesMap
   158  	dropFeatures := newSupportedFeatures(dropBaseLine)
   159  	dropFeatures.drop = newDropFeatures()
   160  	dropFeaturesMap[dropBaseLine] = dropFeatures
   161  
   162  	subscriptionFeaturesMap := map[int]*supportedFeatures{}
   163  	supportedFeaturesByProtocol[operationSubscription] = subscriptionFeaturesMap
   164  	subscriptionFeatures := newSupportedFeatures(subscriptionBaseLine)
   165  	subscriptionFeatures.subscription = newSubscriptionFeatures()
   166  	subscriptionFeaturesMap[subscriptionBaseLine] = subscriptionFeatures
   167  
   168  	heartbeatsFeaturesMap := map[int]*supportedFeatures{}
   169  	supportedFeaturesByProtocol[operationHeartbeats] = heartbeatsFeaturesMap
   170  	heartbeatsFeatures := newSupportedFeatures(hearthbeatsBaseLine)
   171  	heartbeatsFeatures.heartbeats = newHeartbeatsFeatures()
   172  	heartbeatsFeaturesMap[hearthbeatsBaseLine] = heartbeatsFeatures
   173  
   174  	testConnectionFeaturesMap := map[int]*supportedFeatures{}
   175  	supportedFeaturesByProtocol[operationTestConnection] = testConnectionFeaturesMap
   176  	testConnectionFeatures := newSupportedFeatures(testConnectionBaseLine)
   177  	testConnectionFeatures.testConnection = newTestConnectionFeatures()
   178  	testConnectionFeaturesMap[testConnectionBaseLine] = testConnectionFeatures
   179  
   180  }
   181  
   182  var (
   183  	// validate
   184  	operations = []operationTypes{
   185  		operationCluster,
   186  		operationDrop,
   187  		operationHeartbeats,
   188  		operationNone,
   189  		operationPing,
   190  		operationReplication,
   191  		operationSubscription,
   192  		operationTestConnection,
   193  	}
   194  )
   195  
   196  type supportedStatus int
   197  
   198  const (
   199  	supportedStatus_OUT_OF_RANGE supportedStatus = iota
   200  	supportedStatus_NOT_SUPPORTED
   201  	supportedStatus_SUPPORTED
   202  )
   203  
   204  func operationVersionSupported(operationType operationTypes, version int, currentRef *int) supportedStatus {
   205  	*currentRef = -1
   206  
   207  	supportedProtocols := operationsToSupportedProtocolVersions[operationType]
   208  	panicIf(len(supportedProtocols) == 0, "This is a bug. Probably you forgot to add '"+operationType+"' operation to the operationsToSupportedProtocolVersions map")
   209  
   210  	for i := 0; i < len(supportedProtocols); i++ {
   211  		*currentRef = supportedProtocols[i]
   212  		if *currentRef == version {
   213  			return supportedStatus_SUPPORTED
   214  		}
   215  
   216  		if *currentRef < version {
   217  			return supportedStatus_NOT_SUPPORTED
   218  		}
   219  	}
   220  
   221  	return supportedStatus_OUT_OF_RANGE
   222  }
   223  
   224  func getOperationTcpVersion(operationType operationTypes, index int) int {
   225  	// we don't check the if the index go out of range, since this is expected and means that we don't have
   226  	switch operationType {
   227  	case operationPing, operationNone:
   228  		return -1
   229  	case operationDrop:
   230  		return -2
   231  	case operationSubscription, operationReplication, operationCluster,
   232  		operationHeartbeats, operationTestConnection:
   233  		return operationsToSupportedProtocolVersions[operationType][index]
   234  	default:
   235  		panic(fmt.Sprintf("invalid operationType '%v'", operationType))
   236  	}
   237  }
   238  
   239  func getSupportedFeaturesFor(typ operationTypes, protocolVersion int) *supportedFeatures {
   240  	features := supportedFeaturesByProtocol[typ][protocolVersion]
   241  	panicIf(features == nil, typ+" in protocol "+strconv.Itoa(protocolVersion)+" was not found in the features set")
   242  	return features
   243  }