github.com/m3db/m3@v1.5.0/src/cluster/placementhandler/handleroptions/service_options.go (about) 1 // Copyright (c) 2019 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package handleroptions 22 23 import ( 24 "errors" 25 "net/http" 26 "strings" 27 "time" 28 29 "github.com/m3db/m3/src/cluster/kv" 30 "github.com/m3db/m3/src/cluster/services" 31 "github.com/m3db/m3/src/x/headers" 32 ) 33 34 const ( 35 // M3DBServiceName is the service name for M3DB. 36 M3DBServiceName = "m3db" 37 // M3AggregatorServiceName is the service name for M3Aggregator. 38 M3AggregatorServiceName = "m3aggregator" 39 // M3CoordinatorServiceName is the service name for M3Coordinator. 40 M3CoordinatorServiceName = "m3coordinator" 41 42 defaultM3AggMaxAggregationWindowSize = time.Minute 43 // defaultM3AggWarmupDuration configures the buffer to account for the delay 44 // of propagating aggregator placement to clients, usually needed when there is 45 // a large amount of clients sending traffic to m3aggregator. 46 defaultM3AggWarmupDuration = 0 47 ) 48 49 var ( 50 errServiceNameIsRequired = errors.New("service name is required") 51 errServiceEnvironmentIsRequired = errors.New("service environment is required") 52 errServiceZoneIsRequired = errors.New("service zone is required") 53 errM3AggServiceOptionsRequired = errors.New("m3agg service options are required") 54 ) 55 56 // ServiceOptions are the options for Service. 57 type ServiceOptions struct { 58 ServiceName string 59 ServiceEnvironment string 60 ServiceZone string 61 62 M3Agg *M3AggServiceOptions 63 64 DryRun bool 65 Force bool 66 } 67 68 // M3AggServiceOptions contains the service options that are 69 // specific to the M3Agg service. 70 type M3AggServiceOptions struct { 71 MaxAggregationWindowSize time.Duration 72 WarmupDuration time.Duration 73 } 74 75 // ServiceOptionsDefault is a default to apply to service options. 76 type ServiceOptionsDefault func(o ServiceOptions) ServiceOptions 77 78 // WithDefaultServiceEnvironment returns the default service environment. 79 func WithDefaultServiceEnvironment(env string) ServiceOptionsDefault { 80 return func(o ServiceOptions) ServiceOptions { 81 o.ServiceEnvironment = env 82 return o 83 } 84 } 85 86 // WithDefaultServiceZone returns the default service zone. 87 func WithDefaultServiceZone(zone string) ServiceOptionsDefault { 88 return func(o ServiceOptions) ServiceOptions { 89 o.ServiceZone = zone 90 return o 91 } 92 } 93 94 // ServiceNameAndDefaults is the params used when identifying a service 95 // and it's service option defaults. 96 type ServiceNameAndDefaults struct { 97 ServiceName string 98 Defaults []ServiceOptionsDefault 99 } 100 101 // NewServiceOptions returns a ServiceOptions based on the provided 102 // values. 103 func NewServiceOptions( 104 service ServiceNameAndDefaults, 105 header http.Header, 106 m3AggOpts *M3AggServiceOptions, 107 ) ServiceOptions { 108 opts := ServiceOptions{ 109 ServiceName: service.ServiceName, 110 ServiceEnvironment: headers.DefaultServiceEnvironment, 111 ServiceZone: headers.DefaultServiceZone, 112 113 DryRun: false, 114 Force: false, 115 116 M3Agg: &M3AggServiceOptions{ 117 MaxAggregationWindowSize: defaultM3AggMaxAggregationWindowSize, 118 WarmupDuration: defaultM3AggWarmupDuration, 119 }, 120 } 121 for _, applyDefault := range service.Defaults { 122 opts = applyDefault(opts) 123 } 124 125 if v := strings.TrimSpace(header.Get(headers.HeaderClusterEnvironmentName)); v != "" { 126 opts.ServiceEnvironment = v 127 } 128 if v := strings.TrimSpace(header.Get(headers.HeaderClusterZoneName)); v != "" { 129 opts.ServiceZone = v 130 } 131 if v := strings.TrimSpace(header.Get(headers.HeaderDryRun)); v == "true" { 132 opts.DryRun = true 133 } 134 if v := strings.TrimSpace(header.Get(headers.HeaderForce)); v == "true" { 135 opts.Force = true 136 } 137 138 if m3AggOpts != nil { 139 if m3AggOpts.MaxAggregationWindowSize > 0 { 140 opts.M3Agg.MaxAggregationWindowSize = m3AggOpts.MaxAggregationWindowSize 141 } 142 143 if m3AggOpts.WarmupDuration > 0 { 144 opts.M3Agg.WarmupDuration = m3AggOpts.WarmupDuration 145 } 146 } 147 148 return opts 149 } 150 151 // Validate ensures the service options are valid. 152 func (opts *ServiceOptions) Validate() error { 153 if opts.ServiceName == "" { 154 return errServiceNameIsRequired 155 } 156 if opts.ServiceEnvironment == "" { 157 return errServiceEnvironmentIsRequired 158 } 159 if opts.ServiceZone == "" { 160 return errServiceZoneIsRequired 161 } 162 if opts.ServiceName == M3AggregatorServiceName && opts.M3Agg == nil { 163 return errM3AggServiceOptionsRequired 164 } 165 return nil 166 } 167 168 // ServiceID constructs a cluster services ID from the options. 169 func (opts *ServiceOptions) ServiceID() services.ServiceID { 170 return services.NewServiceID(). 171 SetName(opts.ServiceName). 172 SetEnvironment(opts.ServiceEnvironment). 173 SetZone(opts.ServiceZone) 174 } 175 176 // KVOverrideOptions constructs KV overrides from the current service options. 177 func (opts *ServiceOptions) KVOverrideOptions() kv.OverrideOptions { 178 return kv.NewOverrideOptions(). 179 SetEnvironment(opts.ServiceEnvironment). 180 SetZone(opts.ServiceZone) 181 }