/// <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;
}