diff --git a/.gitignore b/.gitignore
index 986a32a..af8a7b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -195,5 +195,7 @@ FakesAssemblies/
# Visual Studio 6 workspace options file
*.opt
+*.lock.json
+
# VIM files
.*.swp
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws.Netcore.sln b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws.Netcore.sln
new file mode 100644
index 0000000..cc077f0
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws.Netcore.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Elasticsearch.Net.Aws", "Elasticsearch.Net.Aws\Elasticsearch.Net.Aws.xproj", "{EDC0CA5E-1970-4C97-936D-B9D3A1675F09}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Tests", "Tests\Tests.xproj", "{DE3D30F3-64CD-4145-A38D-6F24A2028BA5}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {EDC0CA5E-1970-4C97-936D-B9D3A1675F09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EDC0CA5E-1970-4C97-936D-B9D3A1675F09}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EDC0CA5E-1970-4C97-936D-B9D3A1675F09}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EDC0CA5E-1970-4C97-936D-B9D3A1675F09}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DE3D30F3-64CD-4145-A38D-6F24A2028BA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DE3D30F3-64CD-4145-A38D-6F24A2028BA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DE3D30F3-64CD-4145-A38D-6F24A2028BA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DE3D30F3-64CD-4145-A38D-6F24A2028BA5}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/AwsHttpConnection-Netcore.cs b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/AwsHttpConnection-Netcore.cs
new file mode 100644
index 0000000..200a044
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/AwsHttpConnection-Netcore.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Threading.Tasks;
+
+namespace Elasticsearch.Net.Aws
+{
+ public class AwsHttpConnection : HttpConnection
+ {
+ readonly Credentials _credentials;
+ readonly string _region;
+
+ public AwsHttpConnection(AwsSettings settings)
+ {
+ // todo - proper credential chain
+ _credentials = new Credentials
+ {
+ AccessKey = settings.AccessKey,
+ SecretKey = settings.SecretKey,
+ };
+ _region = settings.Region;
+ }
+
+ protected override HttpRequestMessage CreateHttpRequestMessage(RequestData requestData)
+ {
+
+ var result = base.CreateHttpRequestMessage(requestData);
+ var signable = new SignableHttpRequestMessage(result, requestData);
+ SignV4Util.SignRequest(signable, _credentials, _region, "es");
+ return result;
+ }
+ }
+}
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/AwsHttpConnection.cs b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/AwsHttpConnection.cs
index 43032a5..27aeda2 100644
--- a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/AwsHttpConnection.cs
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/AwsHttpConnection.cs
@@ -1,4 +1,5 @@
-using System;
+#if !DOTNETCORE
+using System;
using System.Configuration;
using System.IO;
using System.Net;
@@ -14,8 +15,10 @@ private static string GetAccessKey(AwsSettings awsSettings)
{
var key = awsSettings.AccessKey;
if (!string.IsNullOrWhiteSpace(key)) return key;
+#if NET45
key = ConfigurationManager.AppSettings["AWSAccessKey"];
if (!string.IsNullOrWhiteSpace(key)) return key;
+#endif
return Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID");
}
@@ -87,7 +90,8 @@ protected override HttpWebRequest CreateHttpWebRequest(RequestData requestData)
}
}
}
- SignV4Util.SignRequest(request, data, _credentials, _region, "es");
+ var signableRequest = new SignableHttpWebRequest(request, data);
+ SignV4Util.SignRequest(signableRequest, _credentials, _region, "es");
return request;
}
@@ -106,3 +110,4 @@ private void RefreshCredentials()
}
}
}
+#endif
\ No newline at end of file
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws.csproj b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws.csproj
index aca8b54..c5937ad 100644
--- a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws.csproj
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws.csproj
@@ -56,10 +56,14 @@
+
+
+
+
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws.project.json b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws.project.json
new file mode 100644
index 0000000..16c3e4a
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws.project.json
@@ -0,0 +1,11 @@
+{
+ "runtimes": {
+ "win": {}
+ },
+ "frameworks": {
+ "net45": {}
+ },
+ "dependencies": {
+ "Newtonsoft.Json": "9.0.1"
+ }
+}
\ No newline at end of file
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws.xproj b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws.xproj
new file mode 100644
index 0000000..a2891bd
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws.xproj
@@ -0,0 +1,19 @@
+
+
+
+ 14.0.25420
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ edc0ca5e-1970-4c97-936d-b9d3a1675f09
+ Elasticsearch.Net.Aws
+ .\obj
+ .\bin\
+
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/HttpRequestExtensions.cs b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/HttpRequestExtensions.cs
new file mode 100644
index 0000000..dec6c58
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/HttpRequestExtensions.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Elasticsearch.Net.Aws
+{
+ internal static class HttpRequestExtensions
+ {
+ public static string GetHeaderValue(this IHttpRequest request, string name)
+ => string.Join(",", request.GetHeaderValues(name));
+ }
+}
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/IHttpRequest.cs b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/IHttpRequest.cs
new file mode 100644
index 0000000..b72a86d
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/IHttpRequest.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Elasticsearch.Net.Aws
+{
+ internal interface IHttpRequest
+ {
+ Uri Uri { get; }
+ string Method { get; }
+ byte[] Body { get; }
+ IEnumerable GetHeaderKeys();
+ IEnumerable GetHeaderValues(string name);
+ void SetHeader(string name, string value);
+ }
+}
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/InstanceProfileService.cs b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/InstanceProfileService.cs
index cc0abba..a487186 100644
--- a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/InstanceProfileService.cs
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/InstanceProfileService.cs
@@ -2,7 +2,11 @@
using System.Collections.Generic;
using System.IO;
using System.Net;
-using System.Web.Script.Serialization;
+using Newtonsoft.Json;
+
+#if DOTNETCORE
+using System.Net.Http;
+#endif
namespace Elasticsearch.Net.Aws
{
@@ -12,7 +16,6 @@ internal static class InstanceProfileService
private const string Server = "http://169.254.169.254";
private const string RolesPath = "/latest/meta-data/iam/security-credentials/";
private const string SuccessCode = "Success";
- private static readonly JavaScriptSerializer CredentialSerializer = new JavaScriptSerializer();
private static InstanceProfileCredentials _cachedCredentials;
private static readonly object CacheLock = new object();
@@ -28,7 +31,7 @@ internal static InstanceProfileCredentials GetCredentials()
{
var role = GetFirstRole();
var json = GetContents(new Uri(Server + RolesPath + role));
- var credentials = CredentialSerializer.Deserialize(json);
+ var credentials = JsonConvert.DeserializeObject(json);
if (credentials.Code != SuccessCode)
return null;
@@ -84,16 +87,24 @@ private static string GetContents(Uri uri)
{
try
{
- var request = WebRequest.Create(uri) as HttpWebRequest;
- using (var response = request.GetResponse() as HttpWebResponse)
- using (var reader = new StreamReader(response.GetResponseStream()))
+#if DOTNETCORE
+ using (var client = new HttpClient())
+ using (var response = client.GetAsync(uri).Result)
+ {
+ return response.Content.ReadAsStringAsync().Result;
+ }
+#else
+ using (var response = WebRequest.CreateHttp(uri).GetResponse())
+ using (var body = response.GetResponseStream())
+ using (var reader = new StreamReader(body))
{
return reader.ReadToEnd();
}
+#endif
}
- catch (WebException ex)
+ catch (Exception ex)
{
- throw new Exception("Unable to reach credentials server", ex);
+ throw new Exception("Unable to get instance profile credentials", ex);
}
}
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/SignV4Util.cs b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/SignV4Util.cs
index 0204b5c..e947050 100644
--- a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/SignV4Util.cs
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/SignV4Util.cs
@@ -6,7 +6,11 @@
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
+#if DOTNETCORE
+using Microsoft.AspNetCore.WebUtilities;
+#else
using System.Web;
+#endif
namespace Elasticsearch.Net.Aws
{
@@ -14,15 +18,15 @@ internal static class SignV4Util
{
static readonly char[] _datePartSplitChars = { 'T' };
- public static void SignRequest(HttpWebRequest request, byte[] body, Credentials credentials, string region, string service)
+ public static void SignRequest(IHttpRequest request, Credentials credentials, string region, string service)
{
var date = DateTime.UtcNow;
var dateStamp = date.ToString("yyyyMMdd");
var amzDate = date.ToString("yyyyMMddTHHmmssZ");
- request.Headers["X-Amz-Date"] = amzDate;
+ request.SetHeader("X-Amz-Date", amzDate);
var signingKey = GetSigningKey(credentials.SecretKey, dateStamp, region, service);
- var stringToSign = GetStringToSign(request, body, region, service);
+ var stringToSign = GetStringToSign(request, region, service);
Debug.Write("========== String to Sign ==========\r\n{0}\r\n========== String to Sign ==========\r\n", stringToSign);
var signature = signingKey.GetHmacSha256Hash(stringToSign).ToLowercaseHex();
var auth = string.Format(
@@ -32,9 +36,11 @@ public static void SignRequest(HttpWebRequest request, byte[] body, Credentials
GetSignedHeaders(request),
signature);
- request.Headers[HttpRequestHeader.Authorization] = auth;
- if (!String.IsNullOrWhiteSpace(credentials.Token))
- request.Headers["x-amz-security-token"] = credentials.Token;
+ request.SetHeader("Authorization", auth);
+ if (!string.IsNullOrWhiteSpace(credentials.Token))
+ {
+ request.SetHeader("x-amz-security-token", credentials.Token);
+ }
}
public static byte[] GetSigningKey(string secretKey, string dateStamp, string region, string service)
@@ -48,18 +54,17 @@ public static byte[] GetSigningKey(string secretKey, string dateStamp, string re
private static byte[] GetHmacSha256Hash(this byte[] key, string data)
{
- using (var kha = KeyedHashAlgorithm.Create("HmacSHA256"))
+ using (var kha = new HMACSHA256(key))
{
- kha.Key = key;
return kha.ComputeHash(_encoding.GetBytes(data));
}
}
- public static string GetStringToSign(HttpWebRequest request, byte[] data, string region, string service)
+ public static string GetStringToSign(IHttpRequest request, string region, string service)
{
- var canonicalRequest = GetCanonicalRequest(request, data);
+ var canonicalRequest = GetCanonicalRequest(request);
Debug.Write("========== Canonical Request ==========\r\n{0}\r\n========== Canonical Request ==========\r\n", canonicalRequest);
- var awsDate = request.Headers["x-amz-date"];
+ var awsDate = request.GetHeaderValue("x-amz-date");
Debug.Assert(Regex.IsMatch(awsDate, @"\d{8}T\d{6}Z"));
var datePart = awsDate.Split(_datePartSplitChars, 2)[0];
return string.Join("\n",
@@ -75,21 +80,21 @@ private static string GetCredentialScope(string date, string region, string serv
return string.Format("{0}/{1}/{2}/aws4_request", date, region, service);
}
- public static string GetCanonicalRequest(HttpWebRequest request, byte[] data)
+ public static string GetCanonicalRequest(IHttpRequest request)
{
var canonicalHeaders = request.GetCanonicalHeaders();
var result = new StringBuilder();
result.Append(request.Method);
result.Append('\n');
- result.Append(GetPath(request.RequestUri));
+ result.Append(GetPath(request.Uri));
result.Append('\n');
- result.Append(request.RequestUri.GetCanonicalQueryString());
+ result.Append(request.Uri.GetCanonicalQueryString());
result.Append('\n');
WriteCanonicalHeaders(canonicalHeaders, result);
result.Append('\n');
WriteSignedHeaders(canonicalHeaders, result);
result.Append('\n');
- WriteRequestPayloadHash(data, result);
+ WriteRequestPayloadHash(request.Body, result);
return result.ToString();
}
@@ -102,7 +107,7 @@ private static string GetPath(Uri uri)
.Split('/')
.Select(segment =>
{
- string escaped = HttpUtility.UrlEncode(segment);
+ string escaped = WebUtility.UrlEncode(segment);
escaped = escaped.Replace("*", "%2A");
return escaped;
}
@@ -110,18 +115,17 @@ private static string GetPath(Uri uri)
return string.Join("/", segments);
}
- private static Dictionary GetCanonicalHeaders(this HttpWebRequest request)
+ private static Dictionary GetCanonicalHeaders(this IHttpRequest request)
{
- var q = from string key in request.Headers
+ var q = from string key in request.GetHeaderKeys()
let headerName = key.ToLowerInvariant()
let headerValues = string.Join(",",
- request.Headers
- .GetValues(key) ?? Enumerable.Empty()
+ request.GetHeaderValues(key) ?? Enumerable.Empty()
.Select(v => v.Trimall())
)
select new { headerName, headerValues };
var result = q.ToDictionary(v => v.headerName, v => v.headerValues);
- result["host"] = request.RequestUri.Host.ToLowerInvariant();
+ result["host"] = request.Uri.Host.ToLowerInvariant();
return result;
}
@@ -129,14 +133,14 @@ private static void WriteCanonicalHeaders(Dictionary canonicalHe
{
var q = from pair in canonicalHeaders
orderby pair.Key ascending
- select string.Format("{0}:{1}\n", pair.Key, pair.Value);
+ select $"{pair.Key}:{pair.Value}\n";
foreach (var line in q)
{
output.Append(line);
}
}
- private static string GetSignedHeaders(HttpWebRequest request)
+ private static string GetSignedHeaders(IHttpRequest request)
{
var canonicalHeaders = request.GetCanonicalHeaders();
var result = new StringBuilder();
@@ -158,11 +162,18 @@ private static void WriteSignedHeaders(Dictionary canonicalHeade
public static string GetCanonicalQueryString(this Uri uri)
{
if (string.IsNullOrWhiteSpace(uri.Query)) return string.Empty;
+
+#if DOTNETCORE
+ var q = from kvp in QueryHelpers.ParseQuery(uri.Query)
+ from value in kvp.Value
+ select new { key = kvp.Key, value };
+#else
var queryParams = HttpUtility.ParseQueryString(uri.Query);
var q = from string key in queryParams
orderby key
from value in queryParams.GetValues(key)
select new { key, value };
+#endif
var output = new StringBuilder();
foreach (var param in q)
@@ -181,7 +192,7 @@ private static void WriteEncoded(this StringBuilder output, string value)
{
if (value[i].RequiresEncoding())
{
- output.Append(Uri.HexEscape(value[i]));
+ output.AppendHexEscaped(value[i]);
}
else
{
@@ -237,7 +248,7 @@ private static byte[] GetHash(string data)
private static byte[] GetHash(this byte[] data)
{
- using (var algo = HashAlgorithm.Create("SHA256"))
+ using (var algo = SHA256.Create())
{
return algo.ComputeHash(data);
}
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/SignableHttpRequestMessage.cs b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/SignableHttpRequestMessage.cs
new file mode 100644
index 0000000..a2f16ac
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/SignableHttpRequestMessage.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+
+namespace Elasticsearch.Net.Aws
+{
+ internal class SignableHttpRequestMessage : IHttpRequest
+ {
+ readonly HttpRequestMessage _request;
+ readonly RequestData _requestData;
+
+ public SignableHttpRequestMessage(HttpRequestMessage request, RequestData requestData)
+ {
+ _request = request;
+ _requestData = requestData;
+ }
+
+ public Uri Uri => _request.RequestUri;
+ public string Method => _request.Method.Method;
+ public byte[] Body
+ {
+ get
+ {
+ // note - this probably won't work if compression is enabled
+ if (_requestData?.PostData == null) return null;
+ if (_requestData.PostData.WrittenBytes != null) return _requestData.PostData.WrittenBytes;
+ using (var ms = new MemoryStream())
+ {
+ _requestData.PostData.Write(ms, _requestData.ConnectionSettings);
+ return ms.ToArray();
+ }
+ }
+ }
+
+ public IEnumerable GetHeaderKeys() => _request.Headers.Select(h => h.Key);
+
+ public IEnumerable GetHeaderValues(string name) => _request.Headers.GetValues(name);
+
+ public void SetHeader(string name, string value)
+ {
+ _request.Headers.Remove(name);
+ _request.Headers.Add(name, value);
+ }
+ }
+}
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/SignableHttpWebRequest.cs b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/SignableHttpWebRequest.cs
new file mode 100644
index 0000000..8fa1ede
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/SignableHttpWebRequest.cs
@@ -0,0 +1,43 @@
+#if !DOTNETCORE
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Elasticsearch.Net.Aws
+{
+ internal class SignableHttpWebRequest : IHttpRequest
+ {
+ public HttpWebRequest Request { get; }
+
+ public SignableHttpWebRequest(HttpWebRequest request, byte[] body)
+ {
+ Request = request;
+ Body = body;
+ }
+
+ public Uri Uri => Request.RequestUri;
+
+ public string Method => Request.Method;
+
+ public byte[] Body { get; }
+
+ public IEnumerable GetHeaderKeys()
+ {
+ return Request.Headers.Cast();
+ }
+
+ public IEnumerable GetHeaderValues(string name)
+ {
+ return Request.Headers.GetValues(name);
+ }
+
+ public void SetHeader(string name, string value)
+ {
+ Request.Headers[name] = value;
+ }
+ }
+}
+#endif
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/StringBuilderExtensions.cs b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/StringBuilderExtensions.cs
new file mode 100644
index 0000000..0c01f0b
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/StringBuilderExtensions.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Elasticsearch.Net.Aws
+{
+ internal static class StringBuilderExtensions
+ {
+ private static readonly char[] _hexUpperChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ public static void AppendHexEscaped(this StringBuilder builder, char value)
+ {
+ builder.Append('%');
+ builder.Append(_hexUpperChars[(value & 0xf0) >> 4]);
+ builder.Append(_hexUpperChars[value & 0xf]);
+ }
+ }
+}
diff --git a/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/project.json b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/project.json
new file mode 100644
index 0000000..b40416d
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Elasticsearch.Net.Aws/project.json
@@ -0,0 +1,17 @@
+{
+ "version": "2.1.4.0",
+ "dependencies": {
+ "Elasticsearch.Net": "2.4.6",
+ "Microsoft.AspNetCore.WebUtilities": "1.0.0",
+ "NETStandard.Library": "1.6.0",
+ "Newtonsoft.Json": "9.0.1"
+ },
+ "frameworks": {
+ "netstandard1.6": {
+ "imports": "dnxcore50"
+ }
+ },
+ "buildOptions": {
+ "define": [ "DOTNETCORE" ]
+ }
+}
diff --git a/src/Elasticsearch.Net.Aws/IntegrationTests/IntegrationTests.csproj b/src/Elasticsearch.Net.Aws/IntegrationTests/IntegrationTests.csproj
index b4d4758..084022d 100644
--- a/src/Elasticsearch.Net.Aws/IntegrationTests/IntegrationTests.csproj
+++ b/src/Elasticsearch.Net.Aws/IntegrationTests/IntegrationTests.csproj
@@ -38,15 +38,15 @@
- ..\packages\Elasticsearch.Net.2.0.2\lib\net45\Elasticsearch.Net.dll
+ ..\packages\Elasticsearch.Net.2.4.1\lib\net45\Elasticsearch.Net.dll
True
- ..\packages\NEST.2.0.2\lib\net45\Nest.dll
+ ..\packages\NEST.2.4.1\lib\net45\Nest.dll
True
-
- ..\packages\Newtonsoft.Json.8.0.1\lib\net45\Newtonsoft.Json.dll
+
+ ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
True
diff --git a/src/Elasticsearch.Net.Aws/IntegrationTests/packages.config b/src/Elasticsearch.Net.Aws/IntegrationTests/packages.config
index 498093a..597ab2f 100644
--- a/src/Elasticsearch.Net.Aws/IntegrationTests/packages.config
+++ b/src/Elasticsearch.Net.Aws/IntegrationTests/packages.config
@@ -1,7 +1,7 @@
-
-
-
+
+
+
\ No newline at end of file
diff --git a/src/Elasticsearch.Net.Aws/Tests/InstanceProfileTests.cs b/src/Elasticsearch.Net.Aws/Tests/InstanceProfileTests.cs
index b0b35fb..c080733 100644
--- a/src/Elasticsearch.Net.Aws/Tests/InstanceProfileTests.cs
+++ b/src/Elasticsearch.Net.Aws/Tests/InstanceProfileTests.cs
@@ -14,13 +14,16 @@ public void GetCredentials_should_return_valid_credentials()
var credentials = InstanceProfileService.GetCredentials();
Trace.Write(String.Format("AccessKeyId: {0}", credentials.AccessKeyId));
- Assert.IsNotNullOrEmpty(credentials.AccessKeyId);
+ Assert.IsNotNull(credentials.AccessKeyId);
+ Assert.IsNotEmpty(credentials.AccessKeyId);
Trace.Write(String.Format("SecretAccessKey: {0}", credentials.SecretAccessKey));
- Assert.IsNotNullOrEmpty(credentials.SecretAccessKey);
+ Assert.IsNotNull(credentials.SecretAccessKey);
+ Assert.IsNotEmpty(credentials.SecretAccessKey);
Trace.Write(String.Format("Token: {0}", credentials.Token));
- Assert.IsNotNullOrEmpty(credentials.Token);
+ Assert.IsNotNull(credentials.Token);
+ Assert.IsNotEmpty(credentials.Token);
}
}
}
diff --git a/src/Elasticsearch.Net.Aws/Tests/MockHttpRequest.cs b/src/Elasticsearch.Net.Aws/Tests/MockHttpRequest.cs
new file mode 100644
index 0000000..5b459a6
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Tests/MockHttpRequest.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Threading.Tasks;
+using Elasticsearch.Net.Aws;
+
+namespace Tests
+{
+ public class MockHttpRequest : IHttpRequest
+ {
+ public Uri Uri { get; set; }
+ public string Method { get; set; }
+ public byte[] Body { get; set; }
+ public NameValueCollection Headers { get; set; } = new NameValueCollection();
+ public IEnumerable GetHeaderKeys() => Headers.Keys.Cast();
+
+ public IEnumerable GetHeaderValues(string name)
+ => Headers?.GetValues(name) ?? Enumerable.Empty();
+
+ public void SetHeader(string name, string value)
+ {
+ if (Headers == null) Headers = new NameValueCollection();
+ Headers[name] = value;
+ }
+ }
+}
diff --git a/src/Elasticsearch.Net.Aws/Tests/SignUtilTests.cs b/src/Elasticsearch.Net.Aws/Tests/SignUtilTests.cs
index 7f1c018..b6ad061 100644
--- a/src/Elasticsearch.Net.Aws/Tests/SignUtilTests.cs
+++ b/src/Elasticsearch.Net.Aws/Tests/SignUtilTests.cs
@@ -1,7 +1,6 @@
using System;
-using System.Diagnostics;
-using System.Linq;
-using System.Net;
+using System.Collections.Generic;
+using System.Collections.Specialized;
using System.Text;
using Elasticsearch.Net.Aws;
using NUnit.Framework;
@@ -11,24 +10,29 @@ namespace Tests
[TestFixture]
public class SignUtilTests
{
- HttpWebRequest _sampleRequest;
- byte[] _sampleBody;
+ MockHttpRequest _sampleRequest;
[SetUp]
public void SetUp()
{
- _sampleRequest = WebRequest.CreateHttp("https://iam.amazonaws.com/");
- _sampleRequest.Method = "POST";
- _sampleRequest.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
- _sampleRequest.Headers["X-Amz-Date"] = "20110909T233600Z";
- var encoding = new UTF8Encoding(false);
- _sampleBody = encoding.GetBytes("Action=ListUsers&Version=2010-05-08");
+ _sampleRequest = new MockHttpRequest
+ {
+ Uri = new Uri("https://iam.amazonaws.com/"),
+ Method = "POST",
+ Headers = new NameValueCollection
+ {
+ ["Content-Type"] = "application/x-www-form-urlencoded; charset=utf-8",
+ ["X-Amz-Date"] = "20110909T233600Z",
+
+ },
+ Body = new UTF8Encoding(false).GetBytes("Action=ListUsers&Version=2010-05-08"),
+ };
}
[Test]
public void GetCanonicalRequest_should_match_sample()
{
- var canonicalRequest = SignV4Util.GetCanonicalRequest(_sampleRequest, _sampleBody);
+ var canonicalRequest = SignV4Util.GetCanonicalRequest(_sampleRequest);
Trace.WriteLine("=== Actual ===");
Trace.Write(canonicalRequest);
@@ -42,7 +46,7 @@ public void GetCanonicalRequest_should_match_sample()
[Test]
public void GetStringToSign_should_match_sample()
{
- var stringToSign = SignV4Util.GetStringToSign(_sampleRequest, _sampleBody, "us-east-1", "iam");
+ var stringToSign = SignV4Util.GetStringToSign(_sampleRequest, "us-east-1", "iam");
Trace.WriteLine("=== Actual ===");
Trace.Write(stringToSign);
@@ -78,18 +82,21 @@ public void SignRequest_should_apply_signature_to_request()
SecretKey = "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
Token = "token1",
};
- SignV4Util.SignRequest(_sampleRequest, _sampleBody, creds, "us-east-1", "iam");
+ SignV4Util.SignRequest(_sampleRequest, creds, "us-east-1", "iam");
var amzDate = _sampleRequest.Headers["X-Amz-Date"];
- Assert.IsNotNullOrEmpty(amzDate);
+ Assert.IsNotNull(amzDate);
+ Assert.IsNotEmpty(amzDate);
Trace.WriteLine("X-Amz-Date: " + amzDate);
- var auth = _sampleRequest.Headers[HttpRequestHeader.Authorization];
- Assert.IsNotNullOrEmpty(auth);
+ var auth = _sampleRequest.Headers["Authorization"];
+ Assert.IsNotNull(auth);
+ Assert.IsNotEmpty(auth);
Trace.WriteLine("Authorize: " + auth);
var token = _sampleRequest.Headers["x-amz-security-token"];
- Assert.IsNotNullOrEmpty(token);
+ Assert.IsNotNull(token);
+ Assert.IsNotEmpty(token);
Trace.WriteLine("Token: " + token);
}
diff --git a/src/Elasticsearch.Net.Aws/Tests/Tests.csproj b/src/Elasticsearch.Net.Aws/Tests/Tests.csproj
index a82ca7e..b28db2b 100644
--- a/src/Elasticsearch.Net.Aws/Tests/Tests.csproj
+++ b/src/Elasticsearch.Net.Aws/Tests/Tests.csproj
@@ -38,15 +38,15 @@
- ..\packages\Elasticsearch.Net.2.0.2\lib\net45\Elasticsearch.Net.dll
+ ..\packages\Elasticsearch.Net.2.4.1\lib\net45\Elasticsearch.Net.dll
True
- ..\packages\NEST.2.0.2\lib\net45\Nest.dll
+ ..\packages\NEST.2.4.1\lib\net45\Nest.dll
True
-
- ..\packages\Newtonsoft.Json.8.0.1\lib\net45\Newtonsoft.Json.dll
+
+ ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
True
@@ -63,9 +63,11 @@
+
+
diff --git a/src/Elasticsearch.Net.Aws/Tests/Tests.project.json b/src/Elasticsearch.Net.Aws/Tests/Tests.project.json
new file mode 100644
index 0000000..16c3e4a
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Tests/Tests.project.json
@@ -0,0 +1,11 @@
+{
+ "runtimes": {
+ "win": {}
+ },
+ "frameworks": {
+ "net45": {}
+ },
+ "dependencies": {
+ "Newtonsoft.Json": "9.0.1"
+ }
+}
\ No newline at end of file
diff --git a/src/Elasticsearch.Net.Aws/Tests/Tests.xproj b/src/Elasticsearch.Net.Aws/Tests/Tests.xproj
new file mode 100644
index 0000000..488ab32
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Tests/Tests.xproj
@@ -0,0 +1,19 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ de3d30f3-64cd-4145-a38d-6f24a2028ba5
+ Tests
+ .\obj
+ .\bin\
+ v4.5
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/src/Elasticsearch.Net.Aws/Tests/Trace.cs b/src/Elasticsearch.Net.Aws/Tests/Trace.cs
new file mode 100644
index 0000000..8891a78
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Tests/Trace.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Tests
+{
+ public static class Trace
+ {
+#if DOTNETCORE
+ public static void WriteLine(string line) => Console.WriteLine(line);
+ public static void Write(string line) => Console.Write(line);
+#else
+ public static void WriteLine(string line) => System.Diagnostics.Trace.WriteLine(line);
+ public static void Write(string line) => System.Diagnostics.Trace.Write(line);
+#endif
+ }
+}
diff --git a/src/Elasticsearch.Net.Aws/Tests/packages.config b/src/Elasticsearch.Net.Aws/Tests/packages.config
index 498093a..597ab2f 100644
--- a/src/Elasticsearch.Net.Aws/Tests/packages.config
+++ b/src/Elasticsearch.Net.Aws/Tests/packages.config
@@ -1,7 +1,7 @@
-
-
-
+
+
+
\ No newline at end of file
diff --git a/src/Elasticsearch.Net.Aws/Tests/project.json b/src/Elasticsearch.Net.Aws/Tests/project.json
new file mode 100644
index 0000000..7b0a1e3
--- /dev/null
+++ b/src/Elasticsearch.Net.Aws/Tests/project.json
@@ -0,0 +1,17 @@
+{
+ "version": "1.0.0-*",
+ "dependencies": {
+ "Elasticsearch.Net": "2.4.6",
+ "Elasticsearch.Net.Aws": "2.1.4.0",
+ "NETStandard.Library": "1.6.0",
+ "NUnit": "3.5.0"
+ },
+ "frameworks": {
+ "netstandard1.6": {
+ "imports": "dnxcore50"
+ }
+ },
+ "buildOptions": {
+ "define": [ "DOTNETCORE" ]
+ }
+}