/// <summary> /// <para>Creates a new instance of <see cref="Consumer"/> for the specified <paramref name="topic"/> and /// <paramref name="channel"/>, using the specified <paramref name="logger"/> and <paramref name="config"/>.</para> /// </summary> /// <exception cref="ArgumentNullException">Thrown when one or more required arguments are null.</exception> /// <exception cref="ArgumentException">Thrown when the <paramref name="topic"/> or /// <paramref name="channel"/> exceed the maximum length or contain invalid characters. Topic and channel names /// must be greater than 0 and less than or equal to 64 characters longer and must match the pattern "^[\.a-zA-Z0- /// 9_-]+(#ephemeral)?$". /// </exception> /// <param name="topic">The topic name.</param> /// <param name="channel">The channel name.</param> /// <param name="logger">The <see cref="ILogger"/> instance.</param> /// <param name="config">The <see cref="Config"/> settings. After config is passed in the values are no longer mutable /// (they are copied). /// </param> public Consumer(string topic, string channel, ILogger logger, Config config) { if (string.IsNullOrEmpty(topic)) throw new ArgumentNullException("topic"); if (string.IsNullOrEmpty(channel)) throw new ArgumentNullException("channel"); if (config == null) throw new ArgumentNullException("config"); if (logger == null) throw new ArgumentNullException("logger"); config.Validate(); if (!Protocol.IsValidTopicName(topic)) { throw new ArgumentException("invalid topic name", "topic"); } if (!Protocol.IsValidChannelName(channel)) { throw new ArgumentException("invalid channel name", "channel"); } _id = Interlocked.Increment(ref _instCount); _topic = topic; _channel = channel; _config = config.Clone(); _logger = logger; _maxInFlight = config.MaxInFlight; _incomingMessages = new Chan<Message>(); _rdyRetryTimers = new Dictionary<string, Timer>(); _pendingConnections = new Dictionary<string, Conn>(); _connections = new Dictionary<string, Conn>(); _lookupdRecheckChan = new Chan<int>(bufferSize: 1); _rng = new RNGCryptoServiceProvider(); _stopChan = new Chan<int>(); _exitChan = new Chan<int>(); _wg.Add(1); GoFunc.Run(rdyLoop, string.Format("rdyLoop: {0}/{1}", _topic, _channel)); }
public void Validate(Config c) { // no op }
/// <summary> /// <para>Creates a new instance of <see cref="Consumer"/> for the specified <paramref name="topic"/> and /// <paramref name="channel"/>, using the specified <paramref name="config"/>.</para> /// <para>Uses <see cref="ConsoleLogger"/> with log level <see cref="F:LogLevel.Info"/>.</para> /// </summary> /// <exception cref="ArgumentNullException">Thrown when one or more required arguments are null.</exception> /// <exception cref="ArgumentException">Thrown when the <paramref name="topic"/> or <paramref name="channel"/> /// exceed the maximum length or contain invalid characters. Topic and channel names must be greater than 0 and /// less than or equal to 64 characters longer and must match the pattern "^[\.a-zA-Z0-9_-]+(#ephemeral)?$". /// </exception> /// <remarks>Uses <see cref="ConsoleLogger"/> with <see cref="F:LogLevel.Info"/> to log messages.</remarks> /// <param name="topic">The topic name.</param> /// <param name="channel">The channel name.</param> /// <param name="config">The <see cref="Config"/> settings. After config is passed in the values are no longer mutable /// (they are copied). /// </param> public Consumer(string topic, string channel, Config config) : this(topic, channel, new ConsoleLogger(LogLevel.Info), config) { }
public bool HandlesOption(Config c, string option) { switch (option) { case "tls_min_version": case "tls_check_certificate_revocation": case "tls_insecure_skip_verify": return true; } return false; }
public void Set(Config c, string option, object value) { var tlsConfig = c.TlsConfig != null ? c.TlsConfig.Clone() : new TlsConfig(); switch (option) { case "tls_min_version": var version = (string)value; switch (version) { case "ssl3.0": tlsConfig.MinVersion = SslProtocols.Ssl3; break; case "tls1.0": tlsConfig.MinVersion = SslProtocols.Tls; break; #if !NETFX_3_5 && !NETFX_4_0 case "tls1.1": tlsConfig.MinVersion = SslProtocols.Tls11; break; case "tls1.2": tlsConfig.MinVersion = SslProtocols.Tls12; break; #endif default: throw new Exception(string.Format("ERROR: {0} is not a tls version", value)); } break; case "tls_check_certificate_revocation": bool checkCertificationRevocation = value.Coerce<bool>(); tlsConfig.CheckCertificateRevocation = checkCertificationRevocation; break; case "tls_insecure_skip_verify": bool insecureSkipVerify = value.Coerce<bool>(); tlsConfig.InsecureSkipVerify = insecureSkipVerify; break; default: throw new Exception(string.Format("unknown option {0}", option)); } c.TlsConfig = tlsConfig; }
public void SetDefaults(Config c) { Type typ = c.GetType(); foreach (var field in typ.GetProperties()) { var opt = field.Get<OptAttribute>(); var defaultValue = field.Get<DefaultAttribute>(); if (opt == null || defaultValue == null) continue; c.Set(opt.Name, defaultValue.Value); } string hostname = OS.Hostname(); c.ClientID = hostname.Split(new[] { '.' })[0]; c.Hostname = hostname; c.UserAgent = string.Format("{0}/{1}", ClientInfo.ClientName, ClientInfo.Version); }
public void Validate(Config c) { var typ = c.GetType(); foreach (var field in typ.GetProperties()) { MinAttribute min = field.Get<MinAttribute>(); MaxAttribute max = field.Get<MaxAttribute>(); if (min == null && max == null) continue; object value = field.GetValue(c, index: null); var opt = field.Get<OptAttribute>(); if (min != null) { var coercedMinVal = (IComparable)opt.Coerce(min.Value, field.PropertyType); if (coercedMinVal.CompareTo(value) == 1) throw new Exception(string.Format("invalid {0} ! {1} < {2}", opt.Name, value, coercedMinVal)); } if (max != null) { var coercedMaxVal = (IComparable)opt.Coerce(max.Value, field.PropertyType); if (coercedMaxVal.CompareTo(value) == -1) throw new Exception(string.Format("invalid {0} ! {1} > {2}", opt.Name, value, coercedMaxVal)); } } if (c.HeartbeatInterval > c.ReadTimeout) { throw new Exception(string.Format("HeartbeatInterval {0} must be less than ReadTimeout {1}", c.HeartbeatInterval, c.ReadTimeout)); } // TODO: PR go-nsq: this check was removed, seems still valid since the value can be set through code // https://github.com/bitly/go-nsq/commit/dd8e5fc4ad80922d884ece51f5574af3fa4f14d3#diff-b4bda758a2aef091432646c354b4dc59L376 if (c.BackoffStrategy == null) throw new Exception(string.Format("BackoffStrategy cannot be null")); }
public void Set(Config c, string option, object value) { var typ = c.GetType(); foreach (var field in typ.GetProperties()) { var opt = field.Get<OptAttribute>(); if (opt == null || opt.Name != option) continue; var min = field.Get<MinAttribute>(); var max = field.Get<MaxAttribute>(); var coercedVal = opt.Coerce(value, field.PropertyType); if (min != null) { var coercedMinVal = (IComparable)opt.Coerce(min.Value, field.PropertyType); if (coercedMinVal.CompareTo(coercedVal) == 1) throw new Exception(string.Format("invalid {0} ! {1} < {2}", opt.Name, coercedVal, coercedMinVal)); } if (max != null) { var coercedMaxVal = (IComparable)opt.Coerce(max.Value, field.PropertyType); if (coercedMaxVal.CompareTo(coercedVal) == -1) throw new Exception(string.Format("invalid {0} ! {1} > {2}", opt.Name, coercedVal, coercedMaxVal)); } field.SetValue(c, coercedVal, index: null); return; } throw new Exception(string.Format("unknown option {0}", option)); }
public bool HandlesOption(Config c, string option) { var typ = c.GetType(); foreach (var field in typ.GetProperties()) { var opt = field.Get<OptAttribute>(); if (opt != null && opt.Name == option) { return true; } } return false; }
/// <summary>Clones (makes a copy) of this instance.</summary> /// <returns>A copy of this object.</returns> public Config Clone() { var newConfig = new Config(); newConfig.BackoffStrategy = BackoffStrategy; var typ = GetType(); foreach (var field in typ.GetProperties()) { var opt = field.Get<OptAttribute>(); if (opt != null) { newConfig.Set(opt.Name, field.GetValue(this, index: null)); } } return newConfig; }
public void Set(Config c, string option, object value) { if (c.TlsConfig == null) { c.TlsConfig = new TlsConfig { MinVersion = SslProtocols.Tls, #if NETFX_3_5 || NETFX_4_0 MaxVersion = SslProtocols.Tls #else MaxVersion = SslProtocols.Tls12 #endif }; } switch (option) { case "tls_cert": case "tls_key": // TODO: Test if (option == "tls_cert") certFile = (string)value; else keyFile = (string)value; if (!string.IsNullOrEmpty(certFile) && !string.IsNullOrEmpty(keyFile) && c.TlsConfig.Certificates.Count == 0) { c.TlsConfig.Certificates.Import(certFile); c.TlsConfig.Certificates.Import(keyFile); } return; case "tls_root_ca_file": // TODO: Test string path = (string)value; var certificates = PEM(File.ReadAllText(path)); c.TlsConfig.RootCAs = certificates; return; case "tls_insecure_skip_verify": bool coercedVal = value.Coerce<bool>(); c.TlsConfig.InsecureSkipVerify = coercedVal; return; case "tls_min_version": var version = (string)value; switch (version) { case "ssl3.0": c.TlsConfig.MinVersion = SslProtocols.Ssl3; break; case "tls1.0": c.TlsConfig.MinVersion = SslProtocols.Tls; break; #if !NETFX_3_5 && !NETFX_4_0 case "tls1.1": c.TlsConfig.MinVersion = SslProtocols.Tls11; return; case "tls1.2": c.TlsConfig.MinVersion = SslProtocols.Tls12; return; #endif default: throw new Exception(string.Format("ERROR: {0} is not a tls version", value)); } return; } throw new Exception(string.Format("unknown option {0}", option)); } public void Validate(Config c) { // no op }
public bool HandlesOption(Config c, string option) { switch (option) { case "tls_root_ca_file": case "tls_insecure_skip_verify": case "tls_cert": case "tls_key": case "tls_min_version": return true; } return false; }