static void ConfigureListCommand(CommandLineApplication hcCommand) { hcCommand.RelayCommand("list", (listCmd) => { listCmd.Description = "List HybridConnection(s)"; var connectionStringArgument = listCmd.Argument("connectionString", "Relay ConnectionString"); listCmd.OnExecute(async() => { string connectionString = ConnectionStringUtility.ResolveConnectionString(connectionStringArgument); if (string.IsNullOrEmpty(connectionString)) { TraceMissingArgument(connectionStringArgument.Name); listCmd.ShowHelp(); return(1); } var connectionStringBuilder = new RelayConnectionStringBuilder(connectionString); RelayTraceSource.TraceInfo($"Listing HybridConnections for {connectionStringBuilder.Endpoint.Host}"); RelayTraceSource.TraceInfo($"{"Path",-38} {"ListenerCount",-15} {"RequiresClientAuth",-20}"); var namespaceManager = new RelayNamespaceManager(connectionString); IEnumerable <HybridConnectionDescription> hybridConnections = await namespaceManager.GetHybridConnectionsAsync(); foreach (var hybridConnection in hybridConnections) { RelayTraceSource.TraceInfo($"{hybridConnection.Path,-38} {hybridConnection.ListenerCount,-15} {hybridConnection.RequiresClientAuthorization}"); } return(0); }); }); }
static void ConfigureSendCommand(CommandLineApplication hcCommand) { hcCommand.RelayCommand("send", (sendCmd) => { sendCmd.Description = "HybridConnection send command"; var pathArgument = sendCmd.Argument("path", "HybridConnection path"); var connectionStringArgument = sendCmd.Argument("connectionString", "Relay ConnectionString"); var numberOption = sendCmd.Option(CommandStrings.NumberTemplate, CommandStrings.NumberDescription, CommandOptionType.SingleValue); var methodOption = sendCmd.Option("-m|--method <method>", "The HTTP Method (GET|POST|PUT|DELETE|WEBSOCKET)", CommandOptionType.SingleValue); var requestOption = sendCmd.Option(CommandStrings.RequestTemplate, CommandStrings.RequestDescription, CommandOptionType.SingleValue); var requestLengthOption = sendCmd.Option(CommandStrings.RequestLengthTemplate, CommandStrings.RequestLengthDescription, CommandOptionType.SingleValue); sendCmd.OnExecute(async() => { string connectionString = ConnectionStringUtility.ResolveConnectionString(connectionStringArgument); if (string.IsNullOrEmpty(connectionString)) { TraceMissingArgument(connectionStringArgument.Name); sendCmd.ShowHelp(); return(1); } var connectionStringBuilder = new RelayConnectionStringBuilder(connectionString); connectionStringBuilder.EntityPath = pathArgument.Value ?? connectionStringBuilder.EntityPath ?? DefaultPath; int number = GetIntOption(numberOption, 1); string method = GetStringOption(methodOption, "GET"); string requestContent = GetMessageBody(requestOption, requestLengthOption, null); await HybridConnectionTests.VerifySendAsync(connectionStringBuilder, number, method, requestContent, RelayTraceSource.Instance); return(0); }); }); }
static void ConfigureCreateCommand(CommandLineApplication hcCommand) { hcCommand.RelayCommand("create", (createCmd) => { createCmd.Description = "Create a HybridConnection"; var pathArgument = createCmd.Argument("path", "HybridConnection path"); var connectionStringArgument = createCmd.Argument("connectionString", "Relay ConnectionString"); var requireClientAuthOption = createCmd.Option( CommandStrings.RequiresClientAuthTemplate, CommandStrings.RequiresClientAuthDescription, CommandOptionType.SingleValue); createCmd.OnExecute(async() => { string connectionString = ConnectionStringUtility.ResolveConnectionString(connectionStringArgument); if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(pathArgument.Value)) { TraceMissingArgument(string.IsNullOrEmpty(connectionString) ? connectionStringArgument.Name : pathArgument.Name); createCmd.ShowHelp(); return(1); } var connectionStringBuilder = new RelayConnectionStringBuilder(connectionString); RelayTraceSource.TraceInfo($"Creating HybridConnection '{pathArgument.Value}' in {connectionStringBuilder.Endpoint.Host}..."); var hcDescription = new HybridConnectionDescription(pathArgument.Value); hcDescription.RequiresClientAuthorization = GetBoolOption(requireClientAuthOption, true); var namespaceManager = new RelayNamespaceManager(connectionString); await namespaceManager.CreateHybridConnectionAsync(hcDescription); RelayTraceSource.TraceInfo($"Creating HybridConnection '{pathArgument.Value}' in {connectionStringBuilder.Endpoint.Host} succeeded"); return(0); }); }); }
static void ConfigureListenCommand(CommandLineApplication hcCommand) { hcCommand.RelayCommand("listen", (listenCmd) => { listenCmd.Description = "HybridConnection listen command"; var pathArgument = listenCmd.Argument("path", "HybridConnection path"); var connectionStringArgument = listenCmd.Argument("connectionString", "Relay ConnectionString"); var responseOption = listenCmd.Option("--response <response>", "Response to return", CommandOptionType.SingleValue); var responseLengthOption = listenCmd.Option("--response-length <responseLength>", "Length of response to return", CommandOptionType.SingleValue); var responseChunkLengthOption = listenCmd.Option("--response-chunk-length <responseLength>", "Length of response to return", CommandOptionType.SingleValue); var statusCodeOption = listenCmd.Option("--status-code <statusCode>", "The HTTP Status Code to return (200|201|401|404|etc.)", CommandOptionType.SingleValue); var statusDescriptionOption = listenCmd.Option("--status-description <statusDescription>", "The HTTP Status Description to return", CommandOptionType.SingleValue); listenCmd.OnExecute(async() => { string connectionString = ConnectionStringUtility.ResolveConnectionString(connectionStringArgument); if (string.IsNullOrEmpty(connectionString)) { TraceMissingArgument(connectionStringArgument.Name); listenCmd.ShowHelp(); return(1); } string response = GetMessageBody(responseOption, responseLengthOption, "<html><head><title>Azure Relay HybridConnection</title></head><body>Response Body from Listener</body></html>"); var connectionStringBuilder = new RelayConnectionStringBuilder(connectionString); connectionStringBuilder.EntityPath = pathArgument.Value ?? connectionStringBuilder.EntityPath ?? DefaultPath; var statusCode = (HttpStatusCode)GetIntOption(statusCodeOption, 200); int responseChunkLength = GetIntOption(responseChunkLengthOption, response.Length); return(await HybridConnectionTests.VerifyListenAsync(RelayTraceSource.Instance, connectionStringBuilder, response, responseChunkLength, statusCode, statusDescriptionOption.Value())); }); }); }
static void ConfigureCountCommand(CommandLineApplication hcCommand) { hcCommand.RelayCommand("count", (countCommand) => { countCommand.Description = "Get HybridConnection Count"; var connectionStringArgument = countCommand.Argument("connectionString", "Relay ConnectionString"); countCommand.OnExecute(async() => { string connectionString = ConnectionStringUtility.ResolveConnectionString(connectionStringArgument); if (string.IsNullOrEmpty(connectionString)) { TraceMissingArgument(connectionStringArgument.Name); countCommand.ShowHelp(); return(1); } var namespaceManager = Microsoft.ServiceBus.NamespaceManager.CreateFromConnectionString(connectionString); Uri namespaceUri = namespaceManager.Address; string namespaceHost = namespaceUri.Host; var tokenProvider = namespaceManager.Settings.TokenProvider; RelayTraceSource.TraceVerbose($"Getting HybridConnection count for '{namespaceUri}"); int count = await NamespaceUtility.GetEntityCountAsync(namespaceUri, tokenProvider, "HybridConnections"); RelayTraceSource.TraceInfo(string.Format($"{{0,-{namespaceHost.Length}}} {{1}}", "Namespace", "HybridConnectionCount")); RelayTraceSource.TraceInfo(string.Format($"{{0,-{namespaceHost.Length}}} {{1}}", namespaceHost, count)); return(0); }); }); }
static void ConfigureDeleteCommand(CommandLineApplication hcCommand) { hcCommand.RelayCommand("delete", (deleteCmd) => { deleteCmd.Description = "Delete a HybridConnection"; var pathArgument = deleteCmd.Argument("path", "HybridConnection path"); var connectionStringArgument = deleteCmd.Argument("connectionString", "Relay ConnectionString"); deleteCmd.OnExecute(async() => { string connectionString = ConnectionStringUtility.ResolveConnectionString(connectionStringArgument); if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(pathArgument.Value)) { TraceMissingArgument(string.IsNullOrEmpty(connectionString) ? connectionStringArgument.Name : pathArgument.Name); deleteCmd.ShowHelp(); return(1); } var connectionStringBuilder = new RelayConnectionStringBuilder(connectionString); RelayTraceSource.TraceInfo($"Deleting HybridConnection '{pathArgument.Value}' in {connectionStringBuilder.Endpoint.Host}..."); var namespaceManager = new RelayNamespaceManager(connectionString); await namespaceManager.DeleteHybridConnectionAsync(pathArgument.Value); RelayTraceSource.TraceInfo($"Deleting HybridConnection '{pathArgument.Value}' in {connectionStringBuilder.Endpoint.Host} succeeded"); return(0); }); }); }
static void ConfigureCreateCommand(CommandLineApplication sasCommand) { sasCommand.RelayCommand("create", (createCmd) => { createCmd.Description = "Create a Sas Token"; var pathArgument = createCmd.Argument("path", "Entity path"); var connectionStringArgument = createCmd.Argument("connectionString", "The ConnectionString to use"); createCmd.OnExecute(async() => { string connectionString = ConnectionStringUtility.ResolveConnectionString(connectionStringArgument); if (string.IsNullOrEmpty(connectionString)) { TraceMissingArgument(connectionStringArgument.Name); createCmd.ShowHelp(); return(1); } var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString); var audience = new UriBuilder(namespaceManager.Address); if (!string.IsNullOrEmpty(pathArgument.Value)) { audience.Path = pathArgument.Value; } string token = await namespaceManager.Settings.TokenProvider.GetWebTokenAsync(audience.Uri.AbsoluteUri, string.Empty, true, TimeSpan.FromMinutes(20)); RelayTraceSource.TraceInfo($"Token:\r\n{token}"); return(0); }); }); }
static void ConfigureTestCommand(CommandLineApplication hcCommand) { hcCommand.RelayCommand("test", (testCmd) => { testCmd.Description = "HybridConnection tests"; var connectionStringArgument = testCmd.Argument("connectionString", "Relay ConnectionString"); testCmd.OnExecute(async() => { string connectionString = ConnectionStringUtility.ResolveConnectionString(connectionStringArgument); if (string.IsNullOrEmpty(connectionString)) { TraceMissingArgument(connectionStringArgument.Name); testCmd.ShowHelp(); return(1); } return(await HybridConnectionTests.RunTestsAsync(new RelayConnectionStringBuilder(connectionString), RelayTraceSource.Instance)); }); }); }
internal static void ConfigureCommands(CommandLineApplication app) { app.RelayCommand("diag", (diagCommand) => { diagCommand.Description = "Operations for diagnosing relay/hc issues (Analyze)"; var namespaceOrConnectionStringArgument = diagCommand.Argument(NamespaceOrConnectionStringArgumentName, NamespaceOrConnectionStringArgumentDescription); CommandOption allOption = diagCommand.Option( "-a|--all", "Show all details", CommandOptionType.NoValue); CommandOption namespaceOption = diagCommand.Option( "-n|-ns|--namespace", "Show namespace details", CommandOptionType.NoValue); CommandOption netStatOption = diagCommand.Option( "--netstat", "Show netstat output", CommandOptionType.NoValue); CommandOption portsOption = diagCommand.Option( "-p|--ports", "Probe Relay Ports", CommandOptionType.NoValue); CommandOption instancePortsOption = diagCommand.Option( "-ip|--instance-ports <instanceCount>", "Probe Relay Instance Level Ports", CommandOptionType.SingleValue); CommandOption osOption = diagCommand.Option( "-o|--os", "Display Platform/OS/.NET information", CommandOptionType.NoValue); CommandOption protocolOption = diagCommand.AddSecurityProtocolOption(); diagCommand.OnExecute(async() => { ConfigureSecurityProtocol(protocolOption); bool defaultOptions = !allOption.HasValue() && !namespaceOption.HasValue() && !netStatOption.HasValue() && !portsOption.HasValue() && !osOption.HasValue(); // Run netstat before we try to lookup the namespace to keep ourself out of the results // NetStat output isn't part of the default run, must specify --netstat or --all if (netStatOption.HasValue() || allOption.HasValue()) { ExecuteNetStatCommand(); } NamespaceDetails namespaceDetails = default; string connectionString = ConnectionStringUtility.ResolveConnectionString(namespaceOrConnectionStringArgument); // Might not be present if (!string.IsNullOrEmpty(connectionString)) { var connectionStringBuilder = new ServiceBusConnectionStringBuilder(connectionString); try { namespaceDetails = await NamespaceUtility.GetNamespaceDetailsAsync(connectionStringBuilder.Endpoints.First().Host); } catch (Exception e) { RelayTraceSource.TraceException(e, "Getting namespace details"); } } if (defaultOptions || osOption.HasValue() || allOption.HasValue()) { await ExecutePlatformCommandAsync(namespaceDetails); } if (defaultOptions || namespaceOption.HasValue() || allOption.HasValue()) { ExecuteNamespaceCommand(namespaceDetails); } if (defaultOptions || portsOption.HasValue() || allOption.HasValue() || instancePortsOption.HasValue()) { int gatewayCount = GetIntOption(instancePortsOption, 1); await ExecutePortsCommandAsync(namespaceDetails, gatewayCount); } return(0); }); }); }