github.com/rohankumardubey/aresdb@v0.0.2-0.20190517170215-e54e3ca06b9c/subscriber/config/service_config.go (about)

     1  //  Copyright (c) 2017-2018 Uber Technologies, 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  
    15  package config
    16  
    17  import (
    18  	"errors"
    19  	"fmt"
    20  	"time"
    21  
    22  	"github.com/m3db/m3/src/cluster/client/etcd"
    23  	"github.com/uber-go/tally"
    24  	"github.com/uber/aresdb/client"
    25  	"github.com/uber/aresdb/utils"
    26  	cfgfx "go.uber.org/config"
    27  	"go.uber.org/fx"
    28  	"go.uber.org/zap"
    29  )
    30  
    31  var (
    32  	// ActiveAresNameSpace is current namespace of a list of Ares Supported in current service
    33  	ActiveAresNameSpace string
    34  
    35  	// ActiveJobNameSpace is current namespace of a list of jobs Supported in current service
    36  	ActiveJobNameSpace string
    37  
    38  	// ConfigRootPath is the root path of config
    39  	ConfigRootPath string = "config"
    40  
    41  	// ConfigFile is the file path of config file
    42  	ConfigFile string
    43  
    44  	// Module configures an HTTP server.
    45  	Module = fx.Options(
    46  		fx.Provide(
    47  			NewServiceConfig,
    48  		),
    49  	)
    50  )
    51  
    52  // Params defines the base objects for a service.
    53  type Params struct {
    54  	fx.In
    55  
    56  	Environment utils.EnvironmentContext
    57  	Logger      *zap.Logger
    58  	Scope       tally.Scope
    59  	Config      cfgfx.Provider
    60  }
    61  
    62  // Result defines the objects that the config module provides.
    63  type Result struct {
    64  	fx.Out
    65  
    66  	ServiceConfig ServiceConfig
    67  }
    68  
    69  // ServiceConfig defines the service configuration.
    70  type ServiceConfig struct {
    71  	Environment utils.EnvironmentContext
    72  	Logger      *zap.Logger
    73  	Scope       tally.Scope
    74  	Config      cfgfx.Provider
    75  
    76  	Service            string                `yaml:"service.name"`
    77  	BackendPort        int                   `yaml:"rest.http.address"`
    78  	AresNSConfig       AresNSConfig          `yaml:"ares"`
    79  	JobNSConfig        JobNSConfig           `yaml:"jobs"`
    80  	ActiveAresClusters map[string]SinkConfig `yaml:"-"`
    81  	ActiveJobs         []string              `yaml:"-"`
    82  	ControllerConfig   *ControllerConfig     `yaml:"controller"`
    83  	ZooKeeperConfig    ZooKeeperConfig       `yaml:"zookeeper"`
    84  	EtcdConfig         *etcd.Configuration   `yaml:"etcd"`
    85  	HeartbeatConfig    *HeartBeatConfig      `yaml:"heartbeat"`
    86  }
    87  
    88  // HeartBeatConfig represents heartbeat config
    89  type HeartBeatConfig struct {
    90  	Enabled       bool `yaml:"enabled"`
    91  	Timeout       int  `yaml:"timeout"`
    92  	Interval      int  `yaml:"interval"`
    93  	CheckInterval int  `yaml:"checkInterval"`
    94  }
    95  
    96  // SinkMode defines the subscriber sink mode
    97  type SinkMode int
    98  
    99  const (
   100  	Sink_Undefined SinkMode = iota
   101  	Sink_AresDB
   102  	Sink_Kafka
   103  )
   104  
   105  var sinkModeStr = map[string]SinkMode{
   106  	"undefined": Sink_Undefined,
   107  	"aresDB":    Sink_AresDB,
   108  	"kafka":     Sink_Kafka,
   109  }
   110  
   111  // SinkConfig wraps sink configurations
   112  type SinkConfig struct {
   113  	// SinkMode defines the subscriber sink mode
   114  	SinkModeStr string `yaml:"sinkMode"`
   115  	// AresDBConnectorConfig defines aresDB client config
   116  	AresDBConnectorConfig client.ConnectorConfig `yaml:"aresDB"`
   117  	// KafkaProducerConfig defines Kafka producer config
   118  	KafkaProducerConfig KafkaProducerConfig `yaml:"kafkaProducer"`
   119  }
   120  
   121  // KafkaProducerConfig represents Kafka producer configuration
   122  type KafkaProducerConfig struct {
   123  	// Brokers defines a list of broker addresses separated by comma
   124  	Brokers string `yaml:"brokers"`
   125  	// RetryMax is the max number of times to retry sending a message (default 3).
   126  	RetryMax int `yaml:"retryMax"`
   127  	// TimeoutInMSec is the max duration the broker will wait
   128  	// the receipt of the number of RequiredAcks (defaults to 10 seconds)
   129  	TimeoutInSec int `yaml:"timeoutInSec"`
   130  }
   131  
   132  // AresNSConfig defines the mapping b/w ares namespace and its clusters
   133  type AresNSConfig struct {
   134  	AresNameSpaces map[string][]string   `yaml:"namespaces"`
   135  	AresClusters   map[string]SinkConfig `yaml:"clusters"`
   136  }
   137  
   138  // JobNSConfig defines the mapping b/w job namespace and its clusters
   139  type JobNSConfig struct {
   140  	Jobs map[string][]string `yaml:"namespaces"`
   141  }
   142  
   143  // ControllerConfig defines aresDB controller configuration
   144  type ControllerConfig struct {
   145  	// Enable defines whether to enable aresDB controll or not
   146  	Enable bool `yaml:"enable" default:"false"`
   147  	// Address is aresDB controller address
   148  	Address string `yaml:"address" default:"localhost:5436"`
   149  	// Timeout is request sent to aresDB controller timeout in seconds
   150  	Timeout int `yaml:"timeout" default:"30"`
   151  	// RefreshInterval is the interval to sync up with aresDB controller in minutes
   152  	RefreshInterval int `yaml:"refreshInterval" default:"10"`
   153  	// ServiceName is aresDB controller name
   154  	ServiceName string `yaml:"serviceName" default:"ares-controller"`
   155  }
   156  
   157  // ZooKeeperConfig defines the ZooKeeper client configuration
   158  type ZooKeeperConfig struct {
   159  	// Server defines zookeeper server addresses
   160  	Server                   string        `yaml:"server"`
   161  	SessionTimeoutSeconds    time.Duration `yaml:"sessionTimeoutSeconds" default:"60"`
   162  	ConnectionTimeoutSeconds time.Duration `yaml:"connectionTimeoutSeconds" default:"15"`
   163  	BaseSleepTimeSeconds     time.Duration `yaml:"exponentialBackoffRetryPolicy.baseSleepTimeSeconds" default:"1"`
   164  	MaxRetries               int           `yaml:"exponentialBackoffRetryPolicy.maxRetries" default:"3"`
   165  	MaxSleepSeconds          time.Duration `yaml:"exponentialBackoffRetryPolicy.maxSleepSeconds" default:"15"`
   166  }
   167  
   168  // NewServiceConfig constructs ServiceConfig.
   169  func NewServiceConfig(p Params) (Result, error) {
   170  	raw := p.Config.Get(cfgfx.Root)
   171  	serviceConfig := ServiceConfig{}
   172  
   173  	if err := raw.Populate(&serviceConfig); err != nil {
   174  		return Result{
   175  			ServiceConfig: serviceConfig,
   176  		}, err
   177  	}
   178  	serviceConfig.Environment = p.Environment
   179  	serviceConfig.Logger = p.Logger
   180  	serviceConfig.Scope = p.Scope.Tagged(map[string]string{
   181  		"deployment":  p.Environment.Deployment,
   182  		"dc":          p.Environment.Zone,
   183  		"application": p.Environment.ApplicationID,
   184  	})
   185  	serviceConfig.Config = p.Config
   186  	serviceConfig.ActiveAresClusters = make(map[string]SinkConfig)
   187  
   188  	// Skip local job and aresCluster config if controller is enabled
   189  	if serviceConfig.ControllerConfig.Enable {
   190  		return Result{
   191  			ServiceConfig: serviceConfig,
   192  		}, nil
   193  	}
   194  
   195  	// set serviceConfig.ActiveAresClusters
   196  	if serviceConfig.AresNSConfig.AresClusters == nil || serviceConfig.AresNSConfig.AresNameSpaces == nil {
   197  		return Result{
   198  			ServiceConfig: serviceConfig,
   199  		}, errors.New("Ares namespaces and clusters must be configured")
   200  	}
   201  
   202  	activeAresClusters := serviceConfig.AresNSConfig.AresNameSpaces[ActiveAresNameSpace]
   203  	if activeAresClusters != nil {
   204  		for _, cluster := range activeAresClusters {
   205  			serviceConfig.ActiveAresClusters[cluster] = serviceConfig.AresNSConfig.AresClusters[cluster]
   206  		}
   207  		if len(serviceConfig.ActiveAresClusters) == 0 {
   208  			return Result{
   209  				ServiceConfig: serviceConfig,
   210  			}, fmt.Errorf("No ares cluster configure is found for namespace %s", ActiveAresNameSpace)
   211  		}
   212  	} else {
   213  		return Result{
   214  			ServiceConfig: serviceConfig,
   215  		}, fmt.Errorf("No ares clusters are defined for namespace %s", ActiveAresNameSpace)
   216  	}
   217  
   218  	// set serviceConfig.ActiveJobs
   219  	if serviceConfig.JobNSConfig.Jobs == nil {
   220  		return Result{
   221  			ServiceConfig: serviceConfig,
   222  		}, errors.New("Job namespace config not found")
   223  	}
   224  	serviceConfig.ActiveJobs = serviceConfig.JobNSConfig.Jobs[ActiveJobNameSpace]
   225  
   226  	return Result{
   227  		ServiceConfig: serviceConfig,
   228  	}, nil
   229  }
   230  
   231  func (s SinkConfig) GetSinkMode() SinkMode {
   232  	if val, ok := sinkModeStr[s.SinkModeStr]; ok {
   233  		return val
   234  	}
   235  	return Sink_Undefined
   236  }