/// <summary> /// The LogStreamer sample application allows simple transaction log /// streaming between Starcounter databases. It accepts three kinds /// of command line parameters. /// /// An URI or file path ending with ".logstreamer.xml" is taken to be /// the source of a LogStreamer configuration to use. If it is a local /// file path, the file will be created if necessary. /// /// Any other string not starting with '@' will be taken as the /// upstream URI to use. Either or both of these parameters may be /// omitted. /// /// Parameters starting with '@' are documented in code, but should /// not be needed for general use. /// /// Usually when starting LogStreamer, you'll want to launch it into /// a specific database. If you prefer, you can do that from the /// command line using something like this: /// /// star.exe -d=DBNAME LogStreamer.exe /// /// </summary> /// <param name="args">Command line parameters.</param> static void Main(string[] args) { string upstreamUri = null; bool streamingEnabled = true; bool generateConfigFile = false; bool useFileLog = false; var options = new HandlerOptions() { SkipRequestFilters = true }; // Provide a host local handler for the default config. // Don't move this one - it must be present for the configuration loader // if default configuration is in effect. Handle.GET(DefaultRelativeUri, HandleGETDefaultConfigFile, options); // Provide a handler for some more throughout sample configuration Handle.GET(SampleRelativeUri, HandleGETSampleConfigFile, options); foreach (var arg in args) { if (arg == null || arg.Length < 1) continue; // If you pass .config.json, we take it. Otherwise, // we consider it the upstream URI if (arg[0] != '@') { if (arg.EndsWith(".config.json")) { _configUri = arg; } else { upstreamUri = arg; } } else if (arg.Equals("@disabled", StringComparison.CurrentCultureIgnoreCase) || arg.Equals("@paused", StringComparison.CurrentCultureIgnoreCase)) { streamingEnabled = false; } else if (arg.Equals("@enabled", StringComparison.CurrentCultureIgnoreCase)) { streamingEnabled = true; } else if (arg.Equals("@generate", StringComparison.CurrentCultureIgnoreCase)) { generateConfigFile = true; } else if (arg.Equals("@logfile", StringComparison.CurrentCultureIgnoreCase)) { useFileLog = true; } else { Console.WriteLine("Warning: Ignoring unrecognized argument '{0}'", arg); } } if (string.IsNullOrWhiteSpace(_configUri)) { // Apply the default URI, and then make sure the log streamer // is disabled until explicitly told otherwise string filePath = GetDefaultFilePath(); if (generateConfigFile || File.Exists(filePath)) { _configUri = "file://" + filePath; } else { _configUri = "http://localhost:" + StarcounterEnvironment.Default.UserHttpPort + DefaultRelativeUri; streamingEnabled = false; } } if (generateConfigFile) { if (!_configUri.Contains("://")) { _configUri = "file://" + _configUri; } if (_configUri.StartsWith("file://")) { var cfg = new Configuration(); cfg.ApplyDefaults(); if (!string.IsNullOrWhiteSpace(upstreamUri)) { cfg.UpstreamUri = LogStreamerConfiguration.CleanUri(upstreamUri); } File.WriteAllText(_configUri.Substring(7), ConfigToJson(cfg.ToConfiguration())); } else { Console.WriteLine("Can't generate config file for URI '{0}'", _configUri); } } _config = LogStreamerConfiguration.Load(_configUri, upstreamUri); Console.WriteLine( "Starting LogStreamer in {0}, OID range {1} - {2}. UpstreamUri: '{3}'.", Db.Environment.DatabaseName, Db.Environment.FirstUserOid, Db.Environment.LastUserOid, _config.UpstreamUri ?? "" ); // Ensure that the FirstUserOid and LastUserOid match what we actually have. if (_config.FirstUserOid != Db.Environment.FirstUserOid) { throw new ArgumentException("FirstUserOid mismatch: config " + _config.FirstUserOid + " != " + Db.Environment.FirstUserOid + " actual"); } if (_config.LastUserOid != Db.Environment.LastUserOid) { throw new ArgumentException("LastUserOid mismatch: config " + _config.LastUserOid + " != " + Db.Environment.LastUserOid + " actual"); } Handle.GET(BaseUri, HandleGETRoot); Handle.GET(BaseUri + "/log", HandleGETLog); Handle.GET(BaseUri + "/config", HandleGETConfig); Handle.GET<string>(BaseUri + "?{?}", HandleGETRootParam); Handle.GET(BaseUri + "/config/upstreamwhitelist", HandleGETUpstreamWhitelist); Handle.GET(BaseUri + "/config/downstreamwhitelist", HandleGETDownstreamWhitelist); string logFilePath = null; if (useFileLog) { logFilePath = Path.Combine(GetConfigDirectory(), "logs", "logstreamer", Db.Environment.DatabaseNameLower + ".logstreamer.log"); (new FileInfo(logFilePath)).Directory.Create(); } _logger = new Logger(logFilePath); Status = "Not connected."; if (!string.IsNullOrWhiteSpace(_config.ListenUri)) { _server = new LogStreamerParent(_logger, _servermanager, _serverCts.Token, _config); } StreamingEnabled = streamingEnabled; }
public static ILogStreamerConfiguration Load(string sourceUri, string explicitUpstreamUri) { string content = string.Empty; if (sourceUri.StartsWith("http://")) { var contentResult = Http.GET(sourceUri); if (contentResult == null || !contentResult.IsSuccessStatusCode) { throw new ArgumentException(string.Format( "Http.GET(\"{0}\") returned {1}", sourceUri, contentResult == null ? "null" : "status " + contentResult.StatusCode )); } content = contentResult.Body; } else { if (sourceUri.StartsWith("file://")) { sourceUri = sourceUri.Substring(7); } content = File.ReadAllText(sourceUri); } var cfg = new Configuration(); cfg.PopulateFromJson(content); cfg.ListenUri = CleanUri(cfg.ListenUri); if (string.IsNullOrWhiteSpace(explicitUpstreamUri)) { cfg.UpstreamUri = CleanUri(cfg.UpstreamUri); } else { cfg.UpstreamUri = CleanUri(explicitUpstreamUri); } return cfg.ToConfiguration(); }