1// Copyright 2013-2020 Aerospike, Inc.
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
15package aerospike
16
17import (
18	"crypto/tls"
19	"time"
20)
21
22// ClientPolicy encapsulates parameters for client policy command.
23type ClientPolicy struct {
24	// AuthMode specifies authentication mode used when user/password is defined. It is set to AuthModeInternal by default.
25	AuthMode AuthMode
26
27	// User authentication to cluster. Leave empty for clusters running without restricted access.
28	User string
29
30	// Password authentication to cluster. The password will be stored by the client and sent to server
31	// in hashed format. Leave empty for clusters running without restricted access.
32	Password string
33
34	// ClusterName sets the expected cluster ID.  If not null, server nodes must return this cluster ID in order to
35	// join the client's view of the cluster. Should only be set when connecting to servers that
36	// support the "cluster-name" info command. (v3.10+)
37	ClusterName string //=""
38
39	// Initial host connection timeout duration.  The timeout when opening a connection
40	// to the server host for the first time.
41	Timeout time.Duration //= 30 seconds
42
43	// Connection idle timeout. Every time a connection is used, its idle
44	// deadline will be extended by this duration. When this deadline is reached,
45	// the connection will be closed and discarded from the connection pool.
46	// The value is limited to 24 hours (86400s).
47	//
48	// It's important to set this value to a few seconds less than the server's proto-fd-idle-ms
49	// (default 60000 milliseconds or 1 minute), so the client does not attempt to use a socket
50	// that has already been reaped by the server.
51	//
52	// Connection pools are now implemented by a LIFO stack. Connections at the tail of the
53	// stack will always be the least used. These connections are checked for IdleTimeout
54	// on every tend (usually 1 second).
55	//
56	// Default: 55 seconds
57	IdleTimeout time.Duration //= 55 seconds
58
59	// LoginTimeout specifies the timeout for login operation for external authentication such as LDAP.
60	LoginTimeout time.Duration //= 10 seconds
61
62	// ConnectionQueueCache specifies the size of the Connection Queue cache PER NODE.
63	// Note: One connection per node is reserved for tend operations and is not used for transactions.
64	ConnectionQueueSize int //= 256
65
66	// MinConnectionsPerNode specifies the minimum number of synchronous connections allowed per server node.
67	// Preallocate min connections on client node creation.
68	// The client will periodically allocate new connections if count falls below min connections.
69	//
70	// Server proto-fd-idle-ms may also need to be increased substantially if min connections are defined.
71	// The proto-fd-idle-ms default directs the server to close connections that are idle for 60 seconds
72	// which can defeat the purpose of keeping connections in reserve for a future burst of activity.
73	//
74	// If server proto-fd-idle-ms is changed, client ClientPolicy.IdleTimeout should also be
75	// changed to be a few seconds less than proto-fd-idle-ms.
76	//
77	// Default: 0
78	MinConnectionsPerNode int
79
80	// If set to true, will not create a new connection
81	// to the node if there are already `ConnectionQueueSize` active connections.
82	// Note: One connection per node is reserved for tend operations and is not used for transactions.
83	LimitConnectionsToQueueSize bool //= true
84
85	// Number of connections allowed to established at the same time.
86	// This value does not limit the number of connections. It just
87	// puts a threshold on the number of parallel opening connections.
88	// By default, there are no limits.
89	OpeningConnectionThreshold int // 0
90
91	// Throw exception if host connection fails during addHost().
92	FailIfNotConnected bool //= true
93
94	// TendInterval determines interval for checking for cluster state changes.
95	// Minimum possible interval is 10 Milliseconds.
96	TendInterval time.Duration //= 1 second
97
98	// A IP translation table is used in cases where different clients
99	// use different server IP addresses.  This may be necessary when
100	// using clients from both inside and outside a local area
101	// network. Default is no translation.
102	// The key is the IP address returned from friend info requests to other servers.
103	// The value is the real IP address used to connect to the server.
104	IpMap map[string]string
105
106	// UseServicesAlternate determines if the client should use "services-alternate" instead of "services"
107	// in info request during cluster tending.
108	//"services-alternate" returns server configured external IP addresses that client
109	// uses to talk to nodes.  "services-alternate" can be used in place of providing a client "ipMap".
110	// This feature is recommended instead of using the client-side IpMap above.
111	//
112	// "services-alternate" is available with Aerospike Server versions >= 3.7.1.
113	UseServicesAlternate bool // false
114
115	// RackAware directs the client to update rack information on intervals.
116	// When this feature is enabled, the client will prefer to use nodes which reside
117	// on the same rack as the client for read transactions. The application should also set the RackId, and
118	// use the ReplicaPolicy.PREFER_RACK for reads.
119	// This feature is in particular useful if the cluster is in the cloud and the cloud provider
120	// is charging for network bandwidth out of the zone. Keep in mind that the node on the same rack
121	// may not be the Master, and as such the data may be stale. This setting is particularly usable
122	// for clusters that are read heavy.
123	RackAware bool // false
124
125	// RackId defines the Rack the application is on. This will only influence reads if Rackaware is enabled on the client,
126	// and configured on the server.
127	RackId int // 0
128
129	// TlsConfig specifies TLS secure connection policy for TLS enabled servers.
130	// For better performance, we suggest preferring the server-side ciphers by
131	// setting PreferServerCipherSuites = true.
132	TlsConfig *tls.Config //= nil
133
134	// IgnoreOtherSubnetAliases helps to ignore aliases that are outside main subnet
135	IgnoreOtherSubnetAliases bool //= false
136}
137
138// NewClientPolicy generates a new ClientPolicy with default values.
139func NewClientPolicy() *ClientPolicy {
140	return &ClientPolicy{
141		AuthMode:                    AuthModeInternal,
142		Timeout:                     30 * time.Second,
143		IdleTimeout:                 55 * time.Second,
144		LoginTimeout:                10 * time.Second,
145		ConnectionQueueSize:         256,
146		OpeningConnectionThreshold:  0,
147		FailIfNotConnected:          true,
148		TendInterval:                time.Second,
149		LimitConnectionsToQueueSize: true,
150		IgnoreOtherSubnetAliases:    false,
151	}
152}
153
154// RequiresAuthentication returns true if a User or Password is set for ClientPolicy.
155func (cp *ClientPolicy) RequiresAuthentication() bool {
156	return (cp.User != "") || (cp.Password != "")
157}
158
159func (cp *ClientPolicy) servicesString() string {
160	if cp.UseServicesAlternate {
161		return "services-alternate"
162	}
163	return "services"
164}
165
166func (cp *ClientPolicy) serviceString() string {
167	if cp.TlsConfig == nil {
168		if cp.UseServicesAlternate {
169			return "service-clear-alt"
170		}
171		return "service-clear-std"
172	}
173
174	if cp.UseServicesAlternate {
175		return "service-tls-alt"
176	}
177	return "service-tls-std"
178}
179
180func (cp *ClientPolicy) peersString() string {
181	if cp.TlsConfig != nil {
182		if cp.UseServicesAlternate {
183			return "peers-tls-alt"
184		}
185		return "peers-tls-std"
186	}
187
188	if cp.UseServicesAlternate {
189		return "peers-clear-alt"
190	}
191	return "peers-clear-std"
192}
193