public HttpClient Create(string apiKey, ChaosConfiguration apiConfiguration) { string cacheKey = "client:" + apiKey; if (_memoryCache.Contains(cacheKey)) { return((HttpClient)_memoryCache.Get(cacheKey)); } var client = HttpClientFactory.Create( new ChaoticDelegatingHandler( new Chance(), new HandlerSettings(new ConfigurationRotationTimer(apiConfiguration), apiConfiguration), new ChaoticResponseFactory(new ResponseMediaType()), new RandomDelay(), new ChaosIntervalTimer(apiConfiguration), new ResponseFiddler(new ResponseMediaType()))); client.Timeout = TimeSpan.FromSeconds(apiConfiguration.HttpClientTimeoutInSeconds > 0 ? apiConfiguration.HttpClientTimeoutInSeconds : 15); _memoryCache.Add(cacheKey, client, DateTimeOffset.UtcNow.AddSeconds(30)); return(client); }
private static void Main() { Logger = LogManager.GetLogger(nameof(Program)); //This is for one log file per run (based on start time...) NLog.GlobalDiagnosticsContext.Set("StartTime", DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss")); var configPath = Path.Combine(Environment.CurrentDirectory, "Chaos.json"); if (File.Exists(configPath)) { _chaosConfiguration = GetChaosConfiguration(configPath); } if (_chaosConfiguration == null) { // if GetChaosConfiguration fails (which it logs...), then exit... Logger?.Info("No configruration supplied... Exiting..."); Environment.Exit(-1); } //Repeat setting if (_chaosConfiguration.Repeat > 0) { _repeat = _chaosConfiguration.Repeat; } //Start delay setting if (_chaosConfiguration.RunDelay > 0) { _runDelay = _chaosConfiguration.RunDelay; } try { //Must initialize Bedlam with a ChaosConfiguration... _bedlam = new Bedlam(_chaosConfiguration); } catch (Exception e) { Logger?.Info("Error initializing Bedlam: " + e.Message + "\n Exiting..."); Logger?.Error(e); Environment.Exit(-1); } for (int i = 0; i < _repeat + 1; i++) { if (_runDelay > 0) { Thread.Sleep(_runDelay * 1000); } _bedlam.Run(); } }
internal Bedlam(ChaosConfiguration configuration) { _logger = Program.Logger; if (configuration == null) { _logger?.Error("Can't initialize Bedlam with chaos configuration settings. Check your Chaos.config file."); Environment.Exit(-1); } _config = configuration; //Check for null to support the use of one or more chaos operations in the config file... -CT if (_config.CpuPressure != null) { _operations.Add(new CpuPressure(_config.CpuPressure, _config.Duration)); } if (_config.MemoryPressure != null) { _operations.Add(new MemoryPressure(_config.MemoryPressure, _config.Duration)); } if (_config.NetworkEmulation != null) { _operations.Add(new Operations.NetworkEmulation(_config.NetworkEmulation, _config.Duration)); } if (_operations.Count == 0) { _logger?.Error("No operations settings provided. Aborting...."); throw new Exception( "Cannot execute Bedlam without an operations setting. Check your Chaos.config file..."); } if (_operations.Count == 1) { _config.Orchestration = Orchestration.Sequential; } if (_config.Orchestration == Orchestration.Unknown) { _logger?.Error("No orchestration setting provided. Aborting."); throw new Exception("Cannot execute Bedlam without an Orchestration setting. Check your Chaos.config file."); } _runModes = new Dictionary <Orchestration, Action> { { Orchestration.Concurrent, RunConcurrent }, { Orchestration.Random, RunRandom }, { Orchestration.Sequential, RunSequential } }; }
private static void Main() { Logger = LogManager.GetLogger(nameof(Program)); var configPath = Path.Combine(Environment.CurrentDirectory, "Chaos.config"); if (File.Exists(configPath)) { _chaosConfiguration = GetChaosConfiguration(configPath); } if (_chaosConfiguration == null) { // if GetChaosConfiguration fails (which it logs...), then exit... Logger?.Info("No configruration supplied... Exiting..."); Environment.Exit(-1); } //Repeat setting if (_chaosConfiguration.Repeat > 0) { _repeat = _chaosConfiguration.Repeat; } //Start delay setting if (_chaosConfiguration.RunDelay > 0) { _runDelay = _chaosConfiguration.RunDelay; } try { //Must initialize Bedlam instance with ChaosConfiguration instance... _bedlam = new Bedlam(_chaosConfiguration); } catch (Exception e) { Logger?.Info("Error initializing Bedlam: " + e.Message + "\n Exiting..."); Environment.Exit(-1); } for (int i = 0; i < _repeat + 1; i++) { if (_runDelay > 0) { Thread.Sleep(_runDelay * 1000); } _bedlam.Run(); } }
protected void Run(int port = 0) { var endpoint = GetServerEndpoint(); IListener listener = Listener; if (ParseUtils.ParseSize(options.Bandwidth) is int bandwidth) { listener = new ThrottlingListener(listener, bandwidth); } IConnector connector = new SimpleConnector(endpoint, listener); if (options.Chaos) { var chaosConfiguration = new ChaosConfiguration { Reject = { Percentage = 0.5 }, Abort = { Percentage = 1, UpstreamBytes = new Range <long>(0, 1024 * 1024 * 10), DownstreamBytes = new Range <long>(0, 1024 * 1024 * 10) } }; var chaosConnector = new ChaosConnector(chaosConfiguration, connector); //chaosConnector.Rejected += (s, e) => Console.WriteLine("REJECTED"); //chaosConnector.Aborted += (s, e) => Console.WriteLine($"ABORTED reason {e.Reason}, upstream {e.UpstreamTransferred}, downstream {e.DownstreamTransferred}"); connector = chaosConnector; } proxy = new ProxyServer(new IPEndPoint(IPAddress.Loopback, port), connector); proxy.ExceptionOccured += (s, e) => Console.WriteLine($"EXCEPTION: {e.Exception.Message} ({e.Exception.GetType().FullName})"); proxy.Start(); Running(proxy.EndPoint); }
/// <summary> /// Returns a ChaosConfiguaration object with properties set from supplied config file /// throws an Exception if anything goes wrong, so try-catch the call to this and handle it... /// </summary> /// <param name="configPath">full path to Chaos.config file</param> /// <returns>ChaosConfguration</returns> private static ChaosConfiguration GetChaosConfiguration(string configPath) { if (!File.Exists(configPath)) { return(null); } try { var config = File.ReadAllText(configPath); _chaosConfiguration = JsonConvert.DeserializeObject <ChaosConfiguration>(config); return(_chaosConfiguration); } catch (Exception e) { Logger?.Error(e); //Main will exit, OK not to die here... return(null); } }
private static void SimulateNetworkFailureEchoServer() { using (var echoServer = new EchoServer(new IPEndPoint(IPAddress.Loopback, 0))) { echoServer.Start(); var configuration = new ChaosConfiguration { Reject = { Percentage = 0.5 } }; var connector = new ChaosConnector( configuration, new SimpleConnector(echoServer.EndPoint) ); using (var proxyServer = new ProxyServer(new IPEndPoint(IPAddress.Loopback, 0), connector)) { proxyServer.Start(); var block = Encoding.UTF8.GetBytes("Hello world!"); int errors = 0; for (int i = 0; i < 100; i++) { using (var echoClient = new EchoPingClient(proxyServer.EndPoint, block)) { echoClient.ExceptionOccured += (s, e) => Interlocked.Increment(ref errors); echoClient.Start(); echoClient.Ping(); } } Console.WriteLine(errors); } } }
/// <summary> /// Returns a ChaosConfiguaration object with properties set from supplied config file /// throws an Exception if anything goes wrong, so try-catch the call to this and handle it... /// </summary> /// <param name="configPath">full path to Chaos.config file</param> /// <returns>ChaosConfguration</returns> private static ChaosConfiguration GetChaosConfiguration(string configPath) { if (!File.Exists(configPath)) { return(null); } try { var serializer = new XmlSerializer(typeof(ChaosConfiguration)); using (var reader = new StringReader(File.ReadAllText(configPath))) { _chaosConfiguration = (ChaosConfiguration)serializer.Deserialize(reader); } return(_chaosConfiguration); } catch (Exception e) { Logger?.Error(e); return(null); } }
private HttpClient CreateHttpClientForProxiedRequest(ChaosConfiguration chaosConfiguration, string apiKey) { var client = _chaosHttpClientFactory.Create(apiKey, chaosConfiguration); return(client); }
public void Init() { _apiConfiguration = new ChaosConfiguration(); }
public static ChaosConfiguration ToChaosConfiguration(UpdateConfigurationRequest updateRequest) { var config = new ChaosConfiguration { ChaosInterval = new TimeSpan(0, 0, updateRequest.ChaosInterval), ConfigurationRotationInterval = new TimeSpan(0, 0, updateRequest.ConfigurationRotationInterval), Enabled = updateRequest.Enabled, HttpClientTimeoutInSeconds = updateRequest.HttpClientTimeoutInSeconds }; foreach (var updateChaosSettings in updateRequest.ChaosSettings) { var chaosConfiguration = new ChaosSettings { Name = updateChaosSettings.Name, MaxResponseDelayTime = updateChaosSettings.MaxResponseDelayTime, MinResponseDelayTime = updateChaosSettings.MinResponseDelayTime, PercentageOfChaos = updateChaosSettings.PercentageOfChaos, PercentageOfSlowResponses = updateChaosSettings.PercentageOfSlowResponses, ResponseTypeMediaType = updateChaosSettings.ResponseTypeMediaType }; if (updateChaosSettings.IgnoreUrls != null) { foreach (var url in updateChaosSettings.IgnoreUrls) { chaosConfiguration.IgnoreUrlPattern.Add(url.Pattern); } } foreach (var updateResponse in updateChaosSettings.HttpResponses) { var httpResponse = new ResponseDetails { StatusCode = updateResponse.StatusCode }; foreach (var payload in updateResponse.Payloads.Select(chaosResponsePayload => new ChaosResponsePayload { Code = chaosResponsePayload.Code, Content = chaosResponsePayload.Content })) { httpResponse.Payloads.Add(payload); } chaosConfiguration.HttpResponses.Add(httpResponse); } foreach (var responseFiddle in updateChaosSettings.ResponseFiddles) { var fiddle = new ResponseFiddle { Match = responseFiddle.Match, ReplaceMatchingWith = responseFiddle.ReplaceMatchingWith }; chaosConfiguration.ResponseFiddles.Add(fiddle); } config.ChaosSettings.Add(chaosConfiguration); } return(config); }