diff --git a/src/Cassandra.IntegrationTests/Cassandra.IntegrationTests.csproj b/src/Cassandra.IntegrationTests/Cassandra.IntegrationTests.csproj index 51f33addc..f0cb5f28e 100644 --- a/src/Cassandra.IntegrationTests/Cassandra.IntegrationTests.csproj +++ b/src/Cassandra.IntegrationTests/Cassandra.IntegrationTests.csproj @@ -81,7 +81,6 @@ - diff --git a/src/Cassandra.IntegrationTests/DataStax/Cloud/CloudIntegrationTests.cs b/src/Cassandra.IntegrationTests/DataStax/Cloud/CloudIntegrationTests.cs index fab2d946f..b70203ac3 100644 --- a/src/Cassandra.IntegrationTests/DataStax/Cloud/CloudIntegrationTests.cs +++ b/src/Cassandra.IntegrationTests/DataStax/Cloud/CloudIntegrationTests.cs @@ -19,7 +19,9 @@ using System.IO; using System.Linq; using System.Net; +#if NETCOREAPP using System.Net.Http; +#endif using System.Threading; using System.Threading.Tasks; using Cassandra.Data.Linq; diff --git a/src/Cassandra.IntegrationTests/DataStax/Graph/GraphMultiNodeTests.cs b/src/Cassandra.IntegrationTests/DataStax/Graph/GraphMultiNodeTests.cs index 192503599..ffc6488aa 100644 --- a/src/Cassandra.IntegrationTests/DataStax/Graph/GraphMultiNodeTests.cs +++ b/src/Cassandra.IntegrationTests/DataStax/Graph/GraphMultiNodeTests.cs @@ -19,7 +19,6 @@ using System.Diagnostics; using System.Linq; using System.Net; -using System.Net.Http; using System.Text; using System.Text.RegularExpressions; using System.Threading; @@ -102,34 +101,28 @@ public void WaitForWorkers(int expectedWorkers) { Trace.TraceInformation("GraphMultiNodeTests: WaitForWorkers"); var master = FindSparkMaster(); - var client = new HttpClient(); + var client = new TestHttpClient(new Uri(string.Format("http://{0}:7080", master))); var count = 100; while (count > 0) { - var task = client.GetAsync(string.Format("http://{0}:7080", master)); + var task = client.SendAsync(TestHttpClient.Get, string.Empty); task.Wait(5000); - var response = task.Result; - if (response.StatusCode == HttpStatusCode.OK) + var body = task.Result; + var match = Regex.Match(body, "Alive\\s+Workers:.*(\\d+)", RegexOptions.Multiline); + if (match.Success && match.Groups.Count > 1) { - var content = response.Content.ReadAsStringAsync(); - content.Wait(); - var body = content.Result; - var match = Regex.Match(body, "Alive\\s+Workers:.*(\\d+)", RegexOptions.Multiline); - if (match.Success && match.Groups.Count > 1) + try { - try + var workers = int.Parse(match.Groups[1].Value); + if (workers == expectedWorkers) { - var workers = int.Parse(match.Groups[1].Value); - if (workers == expectedWorkers) - { - return; - } - } - catch - { - // ignored + return; } } + catch + { + // ignored + } } count--; Thread.Sleep(500); diff --git a/src/Cassandra.IntegrationTests/TestBase/TestHttpClient.cs b/src/Cassandra.IntegrationTests/TestBase/TestHttpClient.cs new file mode 100644 index 000000000..2945ce327 --- /dev/null +++ b/src/Cassandra.IntegrationTests/TestBase/TestHttpClient.cs @@ -0,0 +1,192 @@ +// +// Copyright (C) DataStax Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if NETCOREAPP +using System.Net.Http; +#endif + +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +using Cassandra.IntegrationTests.SimulacronAPI.Models.Converters; + +using Newtonsoft.Json; + +namespace Cassandra.IntegrationTests.TestBase +{ + internal class TestHttpClient + { + private readonly Uri _baseAddress; + + public const string Post = "POST"; + public const string Put = "PUT"; + public const string Get = "GET"; + public const string Delete = "DELETE"; + + public TestHttpClient(Uri baseAddress) + { + _baseAddress = baseAddress; + } + + public Task SendAsync(string method, string url) + { +#if NETCOREAPP + return SendAsync(method, url, null); +#endif + +#if NETFRAMEWORK + return SendAsync(method, url, null, null); +#endif + } + +#if NETCOREAPP + public async Task SendWithJsonAsync(string method, string url, object body) + { + HttpContent content = null; + if (body != null) + { + var bodyStr = GetJsonFromObject(body); + content = new StringContent(bodyStr, Encoding.UTF8, "application/json"); + } + + var dataStr = await SendAsync(method, url, content).ConfigureAwait(false); + return string.IsNullOrEmpty(dataStr) ? default(T) : JsonConvert.DeserializeObject(dataStr); + } + + public async Task SendAsync(string method, string url, HttpContent content) + { + HttpMethod httpMethod; + switch (method) + { + case TestHttpClient.Put: + httpMethod = HttpMethod.Put; + break; + + case TestHttpClient.Get: + httpMethod = HttpMethod.Get; + break; + + case TestHttpClient.Delete: + httpMethod = HttpMethod.Delete; + break; + + case TestHttpClient.Post: + httpMethod = HttpMethod.Post; + break; + + default: + throw new ArgumentException($"{method} not recognized.", nameof(method)); + } + + using (var client = new HttpClient()) + { + client.BaseAddress = _baseAddress; + var message = new HttpRequestMessage(httpMethod, url); + if (content != null) + { + message.Content = content; + } + var response = await client.SendAsync(message).ConfigureAwait(false); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Invalid status code received {response.StatusCode}.{Environment.NewLine}" + + $"{await response.Content.ReadAsStringAsync().ConfigureAwait(false)}"); + } + + var dataStr = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + return dataStr; + } + } +#endif + +#if NETFRAMEWORK + + public async Task SendWithJsonAsync(string method, string url, object body) + { + byte[] content = null; + if (body != null) + { + var bodyStr = GetJsonFromObject(body); + content = Encoding.UTF8.GetBytes(bodyStr); + } + + var data = await SendAsync(method, url, "application/json", content).ConfigureAwait(false); + return string.IsNullOrEmpty(data) + ? default(T) + : JsonConvert.DeserializeObject(data); + } + + public async Task SendAsync(string method, string url, string contentType, byte[] content) + { + var request = (HttpWebRequest)WebRequest.Create(_baseAddress + "/" + url); + + request.KeepAlive = false; + request.Method = method; + + if (content != null) + { + request.ContentType = contentType; + request.ContentLength = content.Length; + using (var dataStream = request.GetRequestStream()) + { + dataStream.Write(content, 0, content.Length); + dataStream.Close(); + } + } + + using (var response = (HttpWebResponse)request.GetResponse()) + { + using (var dataStream = response.GetResponseStream()) + { + var reader = new StreamReader(dataStream); + var responseFromServer = await reader.ReadToEndAsync().ConfigureAwait(false); + var statusCode = (int)response.StatusCode; + if (statusCode < 200 || statusCode >= 300) + { + throw new Exception($"Invalid status code received {statusCode}.{Environment.NewLine}" + + $"{responseFromServer}"); + } + + return responseFromServer; + } + } + } + +#endif + + private static string GetJsonFromObject(object body) + { + var bodyStr = string.Empty; + if (body != null) + { + var jsonSerializerSettings = new JsonSerializerSettings + { + Converters = new List + { + new ConsistencyLevelEnumConverter(), + new TupleConverter() + } + }; + bodyStr = JsonConvert.SerializeObject(body, jsonSerializerSettings); + } + return bodyStr; + } + } +} \ No newline at end of file diff --git a/src/Cassandra.IntegrationTests/TestClusterManagement/SimulacronManager.cs b/src/Cassandra.IntegrationTests/TestClusterManagement/SimulacronManager.cs index a5b081060..85f90293a 100644 --- a/src/Cassandra.IntegrationTests/TestClusterManagement/SimulacronManager.cs +++ b/src/Cassandra.IntegrationTests/TestClusterManagement/SimulacronManager.cs @@ -18,14 +18,13 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Net.Http; -using System.Text; using System.Threading; using System.Threading.Tasks; -using Cassandra.IntegrationTests.SimulacronAPI.Models.Converters; + +using Cassandra.IntegrationTests.TestBase; using Cassandra.IntegrationTests.TestClusterManagement.Simulacron; using Cassandra.Tasks; -using Newtonsoft.Json; + using Newtonsoft.Json.Linq; namespace Cassandra.IntegrationTests.TestClusterManagement @@ -34,6 +33,7 @@ public class SimulacronManager { private const string CreateClusterPathFormat = "/cluster?data_centers={0}&cassandra_version={1}&dse_version={2}&name={3}" + "&activity_log={4}&num_tokens={5}"; + private const string CreateClusterPath = "/cluster"; private volatile Process _simulacronProcess; @@ -44,10 +44,12 @@ public class SimulacronManager private static readonly object GlobalLock = new object(); + private readonly TestHttpClient _testHttpClient; + public static SimulacronManager DefaultInstance { get; } = new SimulacronManager(); - + public static SimulacronManager InstancePeersV2Tests { get; } = new SimulacronManager(9011); - + public Uri BaseAddress => new Uri($"http://127.0.0.1:{HttpPort}"); public int? StartPort { get; } = null; @@ -58,9 +60,10 @@ public class SimulacronManager private SimulacronManager() { + _testHttpClient = new TestHttpClient(BaseAddress); } - private SimulacronManager(int? startPort) + private SimulacronManager(int? startPort) : this() { StartPort = startPort; } @@ -185,7 +188,7 @@ public void Stop() Trace.TraceInformation("Simulacron process stopped"); } } - + public Task CreateNewAsync(int nodeLength) { return CreateNewAsync(new SimulacronOptions { Nodes = nodeLength.ToString() }); @@ -198,7 +201,7 @@ public SimulacronCluster CreateNew(int nodeLength) { return CreateNew(new SimulacronOptions { Nodes = nodeLength.ToString() }); } - + public async Task CreateNewAsync(SimulacronOptions options) { Start(); @@ -212,7 +215,7 @@ public SimulacronCluster CreateNew(SimulacronOptions options) { return TaskHelper.WaitToComplete(CreateNewAsync(options)); } - + /// /// Creates a new cluster with POST body parameters. /// @@ -230,13 +233,13 @@ private SimulacronCluster CreateFromData(dynamic data) Data = data, DataCenters = new List() }; - var dcs = (JArray) cluster.Data["data_centers"]; + var dcs = (JArray)cluster.Data["data_centers"]; foreach (var dc in dcs) { var dataCenter = new SimulacronDataCenter(cluster.Id + "/" + dc["id"], this); cluster.DataCenters.Add(dataCenter); dataCenter.Nodes = new List(); - var nodes = (JArray) dc["nodes"]; + var nodes = (JArray)dc["nodes"]; foreach (var nodeJObject in nodes) { var node = new SimulacronNode(dataCenter.Id + "/" + nodeJObject["id"], this); @@ -246,108 +249,45 @@ private SimulacronCluster CreateFromData(dynamic data) } return cluster; } - - public async Task Post(string url, object body) + + public Task Post(string url, object body) { if (!_initialized) { throw new ObjectDisposedException("Simulacron Process not started."); } - var bodyStr = GetJsonFromObject(body); - var content = new StringContent(bodyStr, Encoding.UTF8, "application/json"); - - using (var client = new HttpClient()) - { - client.BaseAddress = BaseAddress; - var response = await client.PostAsync(url, content).ConfigureAwait(false); - await EnsureSuccessStatusCode(response).ConfigureAwait(false); - var dataStr = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JObject.Parse(dataStr); - } + return _testHttpClient.SendWithJsonAsync(TestHttpClient.Post, url, body); } - public async Task PutAsync(string url, object body) + public Task PutAsync(string url, object body) { if (!_initialized) { throw new ObjectDisposedException("Simulacron Process not started."); } - var bodyStr = GetJsonFromObject(body); - var content = new StringContent(bodyStr, Encoding.UTF8, "application/json"); - - using (var client = new HttpClient()) - { - client.BaseAddress = BaseAddress; - var response = await client.PutAsync(url, content).ConfigureAwait(false); - await EnsureSuccessStatusCode(response).ConfigureAwait(false); - var dataStr = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - if (string.IsNullOrEmpty(dataStr)) - { - return null; - } - return JObject.Parse(dataStr); - } + return _testHttpClient.SendWithJsonAsync(TestHttpClient.Put, url, body); } - public async Task GetAsync(string url) + public Task GetAsync(string url) { if (!_initialized) { throw new ObjectDisposedException("Simulacron Process not started."); } - using (var client = new HttpClient()) - { - client.BaseAddress = BaseAddress; - var response = await client.GetAsync(url).ConfigureAwait(false); - await EnsureSuccessStatusCode(response).ConfigureAwait(false); - var dataStr = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject(dataStr); - } + return _testHttpClient.SendWithJsonAsync(TestHttpClient.Get, url, null); } - public async Task DeleteAsync(string url) + public Task DeleteAsync(string url) { if (!_initialized) { throw new ObjectDisposedException("Simulacron Process not started."); } - using (var client = new HttpClient()) - { - client.BaseAddress = BaseAddress; - var response = await client.DeleteAsync(url).ConfigureAwait(false); - await EnsureSuccessStatusCode(response).ConfigureAwait(false); - } - } - - private static async Task EnsureSuccessStatusCode(HttpResponseMessage response) - { - if (!response.IsSuccessStatusCode) - { - throw new Exception($"Invalid status code received {response.StatusCode}.{Environment.NewLine}" + - $"{await response.Content.ReadAsStringAsync().ConfigureAwait(false)}"); - } - } - - private static string GetJsonFromObject(object body) - { - var bodyStr = string.Empty; - if (body != null) - { - var jsonSerializerSettings = new JsonSerializerSettings - { - Converters = new List - { - new ConsistencyLevelEnumConverter(), - new TupleConverter() - } - }; - bodyStr = JsonConvert.SerializeObject(body, jsonSerializerSettings); - } - return bodyStr; + return _testHttpClient.SendWithJsonAsync(TestHttpClient.Delete, url, null); } } -} +} \ No newline at end of file diff --git a/src/Cassandra/Cassandra.csproj b/src/Cassandra/Cassandra.csproj index cd4f7ca2e..2fef690c1 100644 --- a/src/Cassandra/Cassandra.csproj +++ b/src/Cassandra/Cassandra.csproj @@ -34,7 +34,6 @@ - @@ -54,4 +53,4 @@ - \ No newline at end of file +