support named instances and other props via jdbc uri syntax #48 [#158388528] (#49)
This commit is contained in:
Родитель
921677f66a
Коммит
9885d34e58
|
@ -13,6 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
using Steeltoe.CloudFoundry.Connector.Services;
|
||||
using System;
|
||||
using System.Net;
|
||||
|
||||
namespace Steeltoe.CloudFoundry.Connector.SqlServer
|
||||
|
@ -36,7 +37,35 @@ namespace Steeltoe.CloudFoundry.Connector.SqlServer
|
|||
{
|
||||
configuration.Port = si.Port;
|
||||
configuration.Server = si.Host;
|
||||
configuration.Database = si.Path.Replace("databaseName=", string.Empty);
|
||||
if (!string.IsNullOrEmpty(si.Path))
|
||||
{
|
||||
configuration.Database = si.Path;
|
||||
}
|
||||
|
||||
if (si.Query != null)
|
||||
{
|
||||
foreach (var piece in si.Query.Split('&'))
|
||||
{
|
||||
var kvp = piece.Split('=');
|
||||
if (kvp[0].EndsWith("database", StringComparison.InvariantCultureIgnoreCase) || kvp[0].EndsWith("databaseName", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
configuration.Database = kvp[1];
|
||||
}
|
||||
else if (kvp[0].EndsWith("instancename", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
configuration.InstanceName = kvp[1];
|
||||
}
|
||||
else if (kvp[0].StartsWith("hostnameincertificate", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
// adding this key could result in "System.ArgumentException : Keyword not supported: 'hostnameincertificate'" later
|
||||
}
|
||||
else
|
||||
{
|
||||
configuration.Options.Add(kvp[0], kvp[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (configuration.UrlEncodedCredentials)
|
||||
{
|
||||
configuration.Username = WebUtility.UrlDecode(si.UserName);
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Steeltoe.CloudFoundry.Connector.SqlServer
|
||||
|
@ -59,6 +61,11 @@ namespace Steeltoe.CloudFoundry.Connector.SqlServer
|
|||
|
||||
public string Server { get; set; } = Default_Server;
|
||||
|
||||
public string InstanceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the port SQL Server is listening on. To exclude from connection string, use a value less than 0
|
||||
/// </summary>
|
||||
public int Port { get; set; } = Default_Port;
|
||||
|
||||
public string Username { get; set; }
|
||||
|
@ -83,6 +90,8 @@ namespace Steeltoe.CloudFoundry.Connector.SqlServer
|
|||
/// <remarks>Default value is 15</remarks>
|
||||
public int? Timeout { get; set; }
|
||||
|
||||
internal Dictionary<string, string> Options { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ConnectionString) && !cloudFoundryConfigFound)
|
||||
|
@ -91,14 +100,41 @@ namespace Steeltoe.CloudFoundry.Connector.SqlServer
|
|||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
AddKeyValue(sb, "Data Source", $"{Server},{Port}");
|
||||
AddDataSource(sb);
|
||||
AddKeyValue(sb, "Initial Catalog", Database);
|
||||
AddKeyValue(sb, "User Id", Username);
|
||||
AddKeyValue(sb, "Password", Password);
|
||||
AddKeyValue(sb, "Integrated Security", IntegratedSecurity);
|
||||
AddKeyValue(sb, nameof(Timeout), Timeout);
|
||||
|
||||
if (Options != null && Options.Any())
|
||||
{
|
||||
foreach (var o in Options)
|
||||
{
|
||||
AddKeyValue(sb, o.Key, o.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private void AddDataSource(StringBuilder sb)
|
||||
{
|
||||
sb.Append("Data Source");
|
||||
sb.Append(Default_Separator);
|
||||
sb.Append(Server);
|
||||
|
||||
if (InstanceName != null)
|
||||
{
|
||||
sb.Append($"\\{InstanceName}");
|
||||
}
|
||||
|
||||
if (Port > 0)
|
||||
{
|
||||
sb.Append($",{Port}");
|
||||
}
|
||||
|
||||
sb.Append(Default_Terminator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,16 +19,12 @@ namespace Steeltoe.CloudFoundry.Connector.Services
|
|||
public static readonly string[] SQLSERVER_SCHEME = { "sqlserver", "jdbc:sqlserver", "mssql" };
|
||||
|
||||
public SqlServerServiceInfo(string id, string url)
|
||||
: base(id, url.Replace("jdbc:", string.Empty).Replace(';', '/'))
|
||||
: base(id, url)
|
||||
{
|
||||
}
|
||||
|
||||
public SqlServerServiceInfo(string id, string url, string username, string password)
|
||||
: base(
|
||||
id,
|
||||
url != null ? url.Replace("jdbc:", string.Empty) : string.Empty,
|
||||
username,
|
||||
password)
|
||||
: base(id, url, username, password)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,11 +63,6 @@ namespace Steeltoe.CloudFoundry.Connector.Services
|
|||
}
|
||||
else
|
||||
{
|
||||
if (url.Contains(";databaseName="))
|
||||
{
|
||||
url = url.Replace(";databaseName", "/databaseName");
|
||||
}
|
||||
|
||||
return new SqlServerServiceInfo(id, url, username, password);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,8 +40,6 @@ namespace Steeltoe.CloudFoundry.Connector.Services
|
|||
|
||||
public UriInfo(string uristring, bool urlEncodedCredentials = false)
|
||||
{
|
||||
this.UriString = uristring;
|
||||
|
||||
Uri uri = MakeUri(uristring);
|
||||
if (uri != null)
|
||||
{
|
||||
|
@ -68,12 +66,12 @@ namespace Steeltoe.CloudFoundry.Connector.Services
|
|||
Password = userinfo[1];
|
||||
}
|
||||
}
|
||||
|
||||
this.UriString = uristring;
|
||||
}
|
||||
|
||||
public UriInfo(string uristring, string username, string password)
|
||||
{
|
||||
this.UriString = uristring;
|
||||
|
||||
Uri uri = MakeUri(uristring);
|
||||
if (uri != null)
|
||||
{
|
||||
|
@ -90,6 +88,7 @@ namespace Steeltoe.CloudFoundry.Connector.Services
|
|||
|
||||
this.UserName = username;
|
||||
this.Password = password;
|
||||
this.UriString = uristring;
|
||||
}
|
||||
|
||||
public string Scheme { get; internal protected set; }
|
||||
|
@ -158,6 +157,11 @@ namespace Steeltoe.CloudFoundry.Connector.Services
|
|||
{
|
||||
try
|
||||
{
|
||||
if (uriString.StartsWith("jdbc") || uriString.Contains(";"))
|
||||
{
|
||||
ConvertJdbcToUri(ref uriString);
|
||||
}
|
||||
|
||||
return new Uri(uriString);
|
||||
}
|
||||
catch (Exception)
|
||||
|
@ -166,7 +170,7 @@ namespace Steeltoe.CloudFoundry.Connector.Services
|
|||
if (uriString.Contains(","))
|
||||
{
|
||||
// Slide past the protocol
|
||||
var splitUri = UriString.Split('/');
|
||||
var splitUri = uriString.Split('/');
|
||||
|
||||
// get the host list (and maybe credentials)
|
||||
// -- pre-emptively set it as the Host property rather than a local variable
|
||||
|
@ -187,6 +191,35 @@ namespace Steeltoe.CloudFoundry.Connector.Services
|
|||
}
|
||||
}
|
||||
|
||||
protected internal void ConvertJdbcToUri(ref string uriString)
|
||||
{
|
||||
uriString = uriString.Replace("jdbc:", string.Empty).Replace(";", "&");
|
||||
if (!uriString.Contains("?"))
|
||||
{
|
||||
var firstAmp = uriString.IndexOf("&");
|
||||
|
||||
// If there is an equals sign before any ampersands, it is likely a key was included for the db name.
|
||||
// Make the database name part of the path rather than query string if possible
|
||||
var firstEquals = uriString.IndexOf("=");
|
||||
if (firstEquals > 0 && (firstEquals < firstAmp || firstAmp == -1))
|
||||
{
|
||||
var dbnameindex = uriString.IndexOf("databasename=", StringComparison.InvariantCultureIgnoreCase);
|
||||
if (dbnameindex > 0)
|
||||
{
|
||||
uriString = uriString.Remove(dbnameindex, 13);
|
||||
|
||||
// recalculate the location of the first '&'
|
||||
firstAmp = uriString.IndexOf("&");
|
||||
}
|
||||
}
|
||||
|
||||
if (firstAmp > 0)
|
||||
{
|
||||
uriString = uriString.Substring(0, firstAmp) + questionMark[0] + uriString.Substring(firstAmp + 1, uriString.Length - firstAmp - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected internal string GetPath(string pathAndQuery)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pathAndQuery))
|
||||
|
|
|
@ -116,5 +116,22 @@ namespace Steeltoe.CloudFoundry.Connector.SqlServer.Test
|
|||
Assert.Contains("User Id=Dd6O1BPXUHdrmzbP;", opts);
|
||||
Assert.Contains("Password=7E1LxXnlH2hhlPVt;", opts);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Configure_With_ServiceInfo_NamedInstance_Overrides_Config()
|
||||
{
|
||||
SqlServerProviderConfigurer configurer = new SqlServerProviderConfigurer();
|
||||
|
||||
// override provided by environment
|
||||
SqlServerServiceInfo si = new SqlServerServiceInfo("MyId", "jdbc:sqlserver://servername/databaseName=de5aa3a747c134b3d8780f8cc80be519e;instanceName=someInstance;integratedSecurity=true");
|
||||
|
||||
// apply override
|
||||
var opts = configurer.Configure(si, config);
|
||||
|
||||
// resulting options should contain values parsed from environment
|
||||
Assert.Contains("Data Source=servername\\someInstance", opts);
|
||||
Assert.Contains("Initial Catalog=de5aa3a747c134b3d8780f8cc80be519e;", opts);
|
||||
Assert.Contains("integratedSecurity=true;", opts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace Steeltoe.CloudFoundry.Connector.Services.Test
|
|||
Assert.Equal(1433, r1.Port);
|
||||
Assert.Equal("7E1LxXnlH2hhlPVt", r1.Password);
|
||||
Assert.Equal("Dd6O1BPXUHdrmzbP", r1.UserName);
|
||||
Assert.Equal("databaseName=de5aa3a747c134b3d8780f8cc80be519e", r1.Path);
|
||||
Assert.Equal("de5aa3a747c134b3d8780f8cc80be519e", r1.Path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче