github.com/m3db/m3@v1.5.0/src/integration/resources/docker/coordinator.go (about) 1 // Copyright (c) 2020 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 docker 22 23 import ( 24 "errors" 25 "fmt" 26 "net/http" 27 "time" 28 29 "github.com/ory/dockertest/v3" 30 "github.com/prometheus/common/model" 31 32 "github.com/m3db/m3/src/integration/resources" 33 "github.com/m3db/m3/src/query/api/v1/options" 34 "github.com/m3db/m3/src/query/generated/proto/admin" 35 "github.com/m3db/m3/src/query/generated/proto/prompb" 36 ) 37 38 const ( 39 defaultCoordinatorSource = "coordinator" 40 defaultCoordinatorName = "coord01" 41 ) 42 43 var ( 44 defaultCoordinatorList = []int{7201, 7203, 7204} 45 46 defaultCoordinatorOptions = ResourceOptions{ 47 Source: defaultCoordinatorSource, 48 ContainerName: defaultCoordinatorName, 49 PortList: defaultCoordinatorList, 50 } 51 ) 52 53 type coordinator struct { 54 resource *Resource 55 client resources.CoordinatorClient 56 } 57 58 func newDockerHTTPCoordinator( 59 pool *dockertest.Pool, 60 opts ResourceOptions, 61 ) (resources.Coordinator, error) { 62 opts = opts.withDefaults(defaultCoordinatorOptions) 63 opts.TmpfsMounts = []string{"/etc/m3coordinator/"} 64 65 resource, err := NewDockerResource(pool, opts) 66 if err != nil { 67 return nil, err 68 } 69 70 return &coordinator{ 71 resource: resource, 72 client: resources.NewCoordinatorClient(resources.CoordinatorClientOptions{ 73 Client: http.DefaultClient, 74 HTTPPort: 7201, 75 Logger: resource.logger, 76 RetryFunc: resource.pool.Retry, 77 }), 78 }, nil 79 } 80 81 func (c *coordinator) Start() { 82 // noop as docker container should already be started 83 } 84 85 func (c *coordinator) HostDetails() (*resources.InstanceInfo, error) { 86 // TODO: add implementation 87 return nil, errors.New("not implemented") 88 } 89 90 func (c *coordinator) GetNamespace() (admin.NamespaceGetResponse, error) { 91 if c.resource.closed { 92 return admin.NamespaceGetResponse{}, errClosed 93 } 94 95 return c.client.GetNamespace() 96 } 97 98 func (c *coordinator) GetPlacement( 99 opts resources.PlacementRequestOptions, 100 ) (admin.PlacementGetResponse, error) { 101 if c.resource.closed { 102 return admin.PlacementGetResponse{}, errClosed 103 } 104 105 return c.client.GetPlacement(opts) 106 } 107 108 func (c *coordinator) InitPlacement( 109 opts resources.PlacementRequestOptions, 110 req admin.PlacementInitRequest, 111 ) (admin.PlacementGetResponse, error) { 112 if c.resource.closed { 113 return admin.PlacementGetResponse{}, errClosed 114 } 115 116 return c.client.InitPlacement(opts, req) 117 } 118 119 func (c *coordinator) DeleteAllPlacements( 120 opts resources.PlacementRequestOptions, 121 ) error { 122 if c.resource.closed { 123 return errClosed 124 } 125 126 return c.client.DeleteAllPlacements(opts) 127 } 128 129 func (c *coordinator) WaitForNamespace(name string) error { 130 if c.resource.closed { 131 return errClosed 132 } 133 134 return c.client.WaitForNamespace(name) 135 } 136 137 func (c *coordinator) WaitForInstances( 138 ids []string, 139 ) error { 140 if c.resource.closed { 141 return errClosed 142 } 143 144 return c.client.WaitForInstances(ids) 145 } 146 147 func (c *coordinator) WaitForShardsReady() error { 148 if c.resource.closed { 149 return errClosed 150 } 151 152 return c.client.WaitForShardsReady() 153 } 154 155 func (c *coordinator) WaitForClusterReady() error { 156 if c.resource.closed { 157 return errClosed 158 } 159 160 return c.client.WaitForClusterReady() 161 } 162 163 func (c *coordinator) CreateDatabase( 164 addRequest admin.DatabaseCreateRequest, 165 ) (admin.DatabaseCreateResponse, error) { 166 if c.resource.closed { 167 return admin.DatabaseCreateResponse{}, errClosed 168 } 169 170 return c.client.CreateDatabase(addRequest) 171 } 172 173 func (c *coordinator) AddNamespace( 174 addRequest admin.NamespaceAddRequest, 175 ) (admin.NamespaceGetResponse, error) { 176 if c.resource.closed { 177 return admin.NamespaceGetResponse{}, errClosed 178 } 179 180 return c.client.AddNamespace(addRequest) 181 } 182 183 func (c *coordinator) UpdateNamespace( 184 req admin.NamespaceUpdateRequest, 185 ) (admin.NamespaceGetResponse, error) { 186 if c.resource.closed { 187 return admin.NamespaceGetResponse{}, errClosed 188 } 189 190 return c.client.UpdateNamespace(req) 191 } 192 193 func (c *coordinator) DeleteNamespace(namespaceID string) error { 194 if c.resource.closed { 195 return errClosed 196 } 197 198 return c.client.DeleteNamespace(namespaceID) 199 } 200 201 func (c *coordinator) WriteCarbon( 202 port int, metric string, v float64, t time.Time, 203 ) error { 204 if c.resource.closed { 205 return errClosed 206 } 207 208 url := c.resource.resource.GetHostPort(fmt.Sprintf("%d/tcp", port)) 209 210 return c.client.WriteCarbon(url, metric, v, t) 211 } 212 213 func (c *coordinator) WriteProm( 214 name string, 215 tags map[string]string, 216 samples []prompb.Sample, 217 headers resources.Headers, 218 ) error { 219 if c.resource.closed { 220 return errClosed 221 } 222 223 return c.client.WriteProm(name, tags, samples, headers) 224 } 225 226 func (c *coordinator) WritePromWithRequest( 227 writeRequest prompb.WriteRequest, 228 headers resources.Headers, 229 ) error { 230 if c.resource.closed { 231 return errClosed 232 } 233 234 return c.client.WritePromWithRequest(writeRequest, headers) 235 } 236 237 func (c *coordinator) ApplyKVUpdate(update string) error { 238 if c.resource.closed { 239 return errClosed 240 } 241 242 return c.client.ApplyKVUpdate(update) 243 } 244 245 func (c *coordinator) RunQuery( 246 verifier resources.ResponseVerifier, 247 query string, 248 headers resources.Headers, 249 ) error { 250 if c.resource.closed { 251 return errClosed 252 } 253 254 return c.client.RunQuery(verifier, query, headers) 255 } 256 257 func (c *coordinator) InstantQuery( 258 req resources.QueryRequest, 259 headers resources.Headers, 260 ) (model.Vector, error) { 261 if c.resource.closed { 262 return nil, errClosed 263 } 264 return c.client.InstantQuery(req, headers) 265 } 266 267 // InstantQueryWithEngine runs an instant query with provided headers and the specified 268 // query engine. 269 func (c *coordinator) InstantQueryWithEngine( 270 req resources.QueryRequest, 271 engine options.QueryEngine, 272 headers resources.Headers, 273 ) (model.Vector, error) { 274 if c.resource.closed { 275 return nil, errClosed 276 } 277 return c.client.InstantQueryWithEngine(req, engine, headers) 278 } 279 280 // RangeQuery runs a range query with provided headers 281 func (c *coordinator) RangeQuery( 282 req resources.RangeQueryRequest, 283 headers resources.Headers, 284 ) (model.Matrix, error) { 285 if c.resource.closed { 286 return nil, errClosed 287 } 288 return c.client.RangeQuery(req, headers) 289 } 290 291 // GraphiteQuery retrieves graphite raw data. 292 func (c *coordinator) GraphiteQuery(req resources.GraphiteQueryRequest) ([]resources.Datapoint, error) { 293 return c.client.GraphiteQuery(req) 294 } 295 296 // RangeQueryWithEngine runs a range query with provided headers and the specified 297 // query engine. 298 func (c *coordinator) RangeQueryWithEngine( 299 req resources.RangeQueryRequest, 300 engine options.QueryEngine, 301 headers resources.Headers, 302 ) (model.Matrix, error) { 303 if c.resource.closed { 304 return nil, errClosed 305 } 306 return c.client.RangeQueryWithEngine(req, engine, headers) 307 } 308 309 // LabelNames return matching label names based on the request. 310 func (c *coordinator) LabelNames( 311 req resources.LabelNamesRequest, 312 headers resources.Headers, 313 ) (model.LabelNames, error) { 314 if c.resource.closed { 315 return nil, errClosed 316 } 317 return c.client.LabelNames(req, headers) 318 } 319 320 // LabelValues returns matching label values based on the request. 321 func (c *coordinator) LabelValues( 322 req resources.LabelValuesRequest, 323 headers resources.Headers, 324 ) (model.LabelValues, error) { 325 if c.resource.closed { 326 return nil, errClosed 327 } 328 return c.client.LabelValues(req, headers) 329 } 330 331 // Series returns matching series based on the request. 332 func (c *coordinator) Series( 333 req resources.SeriesRequest, 334 headers resources.Headers, 335 ) ([]model.Metric, error) { 336 if c.resource.closed { 337 return nil, errClosed 338 } 339 return c.client.Series(req, headers) 340 } 341 342 func (c *coordinator) Close() error { 343 if c.resource.closed { 344 return errClosed 345 } 346 347 return c.resource.Close() 348 } 349 350 func (c *coordinator) InitM3msgTopic( 351 opts resources.M3msgTopicOptions, 352 req admin.TopicInitRequest, 353 ) (admin.TopicGetResponse, error) { 354 return c.client.InitM3msgTopic(opts, req) 355 } 356 357 func (c *coordinator) GetM3msgTopic( 358 opts resources.M3msgTopicOptions, 359 ) (admin.TopicGetResponse, error) { 360 return c.client.GetM3msgTopic(opts) 361 } 362 363 func (c *coordinator) AddM3msgTopicConsumer( 364 opts resources.M3msgTopicOptions, 365 req admin.TopicAddRequest, 366 ) (admin.TopicGetResponse, error) { 367 return c.client.AddM3msgTopicConsumer(opts, req) 368 }